OmniAICreator/Qiita-1.07M huggingface dataset:
駅情報をcsvでシードデータに登録する

# 初めに
以前とあるアプリを開発時に駅情報や路線情報が必要になり、色々と調べましたが情報を集めるのに苦戦したため記事を書こうと思い至りました。
間違っている等あればコメントよろしくお願いいたします。
また、本記事に関しては駅情報のみについて記載しますが、路線情報についても手順は一緒のため割愛致します。

# 手順
## 1,モデル作成
まずは対象のモデルを作成致します。
```
rails g model Station                   
```
## 2,マイグレーションファイルに記述
①先ほどのコードでマイグレーションファイルが作成されるので中身を記述して行きます。
```
def change
    create_table :stations do |t|
      t.integer :station_cd
      t.integer :station_g_cd
      t.string :station_name
      t.string :station_name_k
      t.string :station_name_r
      t.integer :line_cd
      t.integer :pref_cd
      t.string :post
      t.string :address
      t.float :lon
      t.float :lat
      t.date :open_ymd
      t.date :close_ymd
      t.integer :e_status
      t.integer :e_sort

      t.timestamps
    end
  end
```
②上記を記述したらマイグレーションを実行します。
```
rails db:migrate      
```
## 3,マスタデータ取得
色々とデータを取得できるサイトはありますが今回は駅データjpというサイトからダウンロード致します。
※ダウンロードするには無料の会員登録が必要なので注意です。
## 4,取得したものを配置
取得してきたものを/assets/csvフォルダを作成した配下に貼り付けます
![スクリーンショット 2024-08-31 18.33.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3037491/b2ff5bae-e28a-e80d-8560-f12c3e333f2c.png)


## 5,seed.rbに記述
以下に内容をseed.rbに記述します
```
require 'csv'

station_csv_file_path = 'app/assets/csv/station.csv'
CSV.foreach(station_csv_file_path, headers: true) do |row|
　　　　Station.create!(row.to_hash)
end
```

## 6 ,seedデータ作成
最後にseedデータを実行して終了です

```
rails db:seed
```

# 最後に
以上で終了になります。これによりプルダウンの項目に表示させたりと色々おこなえるようになります。
拙い文章でしたが最後まで読んでいただきありがとうございました。
複数の文字を連続で出力させたい

# １ 複数の文字を出力させたい
備忘録として書きました。
powershellで複数の文字を出力させたい場面があった時の出力方法になります。


# 2 配列と繰り返し表現を使用する

出力させたい文字列を配列にし、foreachを使用して繰り返しするようにしました。
以下のようになります。

```todohuken.ps1

$kens = "神奈川県","静岡県","山梨県"

foreach ($ken in $kens) {
Write-Host $ken
}
```

出力結果は以下のようになります。
```
神奈川県
静岡県
山梨県
```

配列「kens」に格納していた３つの文字が出力されています。
【JavaScript】スプレッド構文について

# 背景
JavaScript復習中に学んだことをアウトプット。
今回はスプレッド構文について。
## スプレッド構文とは...
[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax "スプレッド構文 - JavaScript | MDN")を見ると、以下のように説明されています。
> 配列式や文字列などの反復可能オブジェクトを、0個以上の引数 (関数呼び出しの場合) や要素 (配列リテラルの場合) を期待された場所で展開したり、オブジェクト式を、0個以上のキーと値の組 (オブジェクトリテラルの場合) を期待された場所で展開したりすることができます。

内容を完全に理解しようとすると少し難しいですが、ポイントとしては「<b>展開する</b>」というところになります。

実際に動作確認してみた方が分かりやすいと思うので、今回は以下の3パターンでスプレッド構文を活用してみます。
## 関数呼び出し
例えば、`Math.min()`で5つの値の最小値を求めようと思った場合、以下のような記述になります。
```js
Math.min(1, 5, 10, 6, 9);
// => 1
```
ここで、引数に配列を渡してあげた場合、出力結果はどうなってしまうのか...。
```js
const nums = [1, 5, 10, 6, 9];

Math.min(nums);
// => NaN
```
上記のように、NaNが返ってきてしまいます。
`Math.min()`は、数値そのものをカンマ区切りで渡してあげないと上手く機能してくれません。

では、どうすれば配列に格納されている数値を引数として渡してあげられるのか。

ここで登場するのがスプレッド構文です。
書き方としてはとてもシンプルで、先ほど引数として渡した配列`nums`の前に、`...`を付けてあげます。
```js
const nums = [1, 5, 10, 6, 9];

Math.min(...nums);
// => 1
```
すると、関数が実行され、配列の中にある数値から最小値を求めてくれるようになります。
このように、配列にスプレッド構文を使うと、中身が<b>展開</b>されて関数の引数として用いることができるようになります。
## 配列リテラル
次に、既存の配列を使って新しい配列を作成する場合で考えてみます。
```js
const nums1 = [1, 2, 3];
const nums2 = [4, 5, 6];
```
この2つの配列を合体させて、新しい配列を作成したいです。
ここでまた登場するのがスプレッド構文。
```js
const allNums = [...nums1, ...nums2];

console.log(allNums);
// => [1, 2, 3, 4, 5, 6]
```
上記のように記述することで、一度`nums1`、`nums2`の中身をそれぞれ展開し、展開された値を新しい配列に格納することができます。

余談ですが、配列同士の合体は`concat()`を使って実現することもできます。
ただ個人的にはスプレッド構文を使った書き方の方がシンプルで使いやすいですし、かなり応用も効くと思うので、この方法を活用していきたいと思ってます。
## オブジェクトリテラル
最後に、オブジェクトをコピーして新しいオブジェクトを作成する場合で考えてみます。
例として、以下のようなオブジェクトがあったとします。
```js
const yamada = {lastName: "yamada", country: "Japan", isHuman: true};
```
こちらのオブジェクトを用いて、新しいオブジェクトを生成してみましょう。
```js
const yamadaTaro = {firstName: "taro", ...yamada};

console.log(yamadaTaro);
// => {firstName: 'taro', lastName: 'yamada', country: 'Japan', isHuman: true}
```
このように、オブジェクトの中身も展開することができます。
## まとめ
- スプレッド構文（`...`）を用いることで、配列やオブジェクトの中身を展開することができる
- 展開した要素を、新しい配列やオブジェクトに格納することができる
## 感想
非常に便利な構文なので、いろんな場面でうまく活用していきたいです。
UE5のUMG、「Canvas Panel」と「Overlay」の違いって？

## 疑問！
UnrealEngineのWidget blueprintで使う、「Canvas Panel」と「Overlay」。
両方とも、子Widgetを複数格納することができるWidgetです。
二つの違いがわからなかったので、調べました。

<br>

## 結論
|  |    内容     | その他|
|---:|----------|--------------------|
| Overlay  |      子ウィジェットの位置をレイアウトすることができるようになる       |子ウィジェットの位置は数値で調整する |
|  Canvas Panel |  子ウィジェットの位置**とサイズ**をレイアウトすることができるようになる | 子ウィジェットは自由に手動でレイアウトすることができる|


<br>

## 詳細
### 🌟Overlay
Overlayの子ウィジェットを選択すると、Detailsから、PaddingとAlignmentを使って、位置を変更できるようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115955/068dc15e-97c4-f691-0b8d-2e553bd04847.png)


imageを子ウィジェットにしている場合、画像のサイズはimage sizeによって決まります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115955/a8994499-ea0d-7d4d-f365-1b3d746320eb.png)


また、ビューポート(？)でマウスドラッグによってレイアウトを変えることはできません。
Detailsの数値を変更することでのみ位置の変更が可能です。


<br><br>


### 🌟Canvas Panel
Canvas Panelの子ウィジェットを選択すると、Detailsから、位置とサイズを変更できるようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115955/d0c46a93-7771-7e10-68df-3598210b1d06.png)


imageを子ウィジェットにしている場合、image sizeは画像のサイズに影響を及ぼさなくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115955/983552e4-6a86-836c-9645-28c6efa827cd.png)

また、ビューポート(？)でマウスドラッグによって自由にレイアウトを変えることも可能です。

![2024-08-31_17h59_38.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115955/f4ba3fab-1886-5809-f83b-5f0f9367b7d6.gif)

<br>

## おまけ
Canvas Panelの直下にSizeBoxを配置するのは全く意味がない行為ってことになってしまうのかな？
Sizeを設定する役割のSizeBoxを配置しても、CanvasPanelの子として設定したサイズのほうが優先されてしまいますもんね？

![2024-08-31_18h15_59.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115955/5f25a698-ca11-179f-bf1d-27100d36417e.gif)


<br>

<br>

## 参考文献
https://shuntaendo.hatenablog.com/entry/2020/11/11/230000

https://historia.co.jp/archives/5322/
最小努力と最短時間で62-193合格

昨日の(AI-900)に引き続き超絶激マイナー資格62-193（Technology Literacy for Educator）も無事一回で合格しました。
勉強時間は3時間程度でした。
当日の詰め込みショートカット勉強法なので、きちんと正攻法で勉強することをお勧めします。


過去の体験記はこちら：

https://qiita.com/ponponmikankan/items/fd363bb0323569d3676f

https://qiita.com/ponponmikankan/items/77202be0de32cda5893d

https://qiita.com/ponponmikankan/items/4b64124be47a34467019

https://qiita.com/ponponmikankan/items/c27d6db74bac7cb44fef

https://qiita.com/ponponmikankan/items/f25fa53b13f10df574d6

https://qiita.com/ponponmikankan/items/95790b6892a3c6d3e285

https://qiita.com/ponponmikankan/items/d19606c99f902f57a4ca


## 前提

とにかく今年度はたくさん資格を受けよう！というモチベーションでMicrosoftの資格一覧を見ていたところ、鬼マイナーな試験を発見。
本来は教師向けの資格ですが、もともと教育に興味があるのと、ラーニングパスもあるのでとりあえず申し込みました。

内容としては21世紀型の学習のデザインの概念を理解します。学習者中心の教育、学習の拡張性、ICT 統合がテーマなのですが、意外にマイクロソフトみは低いです。
どんなツールを使う？というところでちょっとだけソフト名が出てくるくらいです。

## 参考にした勉強法

あまりにもマイナーすぎてまず合格体験記がほとんどインターネットにないです笑笑

https://blog.edunote.jp/entry/2021/10/31/154959

こちらを確認し、「うむ。やはりLearnやね」と
ひたすらLearnを3時間くらい眺めてました。

## 実際の勉強でやったこと

### Learnを飛ばし読み（3時間程度）

所要時間20時間超となってますが、基本的に概要→6つのルーブリックの説明→締めなので最初にルーブリックを眺めておけば全体を把握できるのでさくさくといけます。
あまり受ける人がいないからか、Learnの直訳がかなり酷いのと、挿絵も英語のままなのでめちゃくちゃとっつきにくいです。
日本語で上手くまとめてる方もいないので気合いで頑張るしかありません。。

ソフト名の部分はおなじみのOffice系のほかSway、Minecraft、MakeCodeが登場します。あとソフトじゃないけど、アクセシビリティの観点でイマーシブリーダーが謎に登場したのでおぼえておいたほうがよきです。

### プラクティス評価があるとおもいきや…

なんとこちらの試験、いつも直前に解きまくってるプラクティス評価がありません笑笑
日本語ではネットにもほぼ問題例がないので割とドキドキしました。

一応英語ですが、こちらのサイトを参考にしました。
なんとなくケーススタディの出題形式の様子もわかるかと思います。

https://www.examtopics.com/exams/microsoft/62-193/

### 試験の感想

試験時間は1時間ですが、見直し一周がギリギリで時間いっぱい使ってしまいました。もうこれ国語の問題やん…というくらい文章量が質問文も選択肢の文章も多いのでとにかく飛ばし読みすることが大切かも。
Fundamentalsでは見かけないケーススタディ（でかめの前提案件があってそれについて答える問題）の大問が3つ(10問分くらい)、択一やドラッグドロップ系が30問くらい出ます。
ケーススタディは終了後、元に戻ることができないので魂を込めてクリックしていきます。

ルーブリック、全部レベルまで暗記しないとやばいかなあと思ってましたが、意外に暗記しなくとも解けるのでご安心ください。

マイクロソフト的知識もほぼ問われず、あんまり自信なかったんですが、なんやかんや9割くらいとれてたので最後まで諦めないことが大事です！笑

…というわけで、今回も超最低限勉強法で無事合格！
来週はいよいよ未知のDynamics系の受験が控えているのでがんばります✊
PaHUB（M5Stack用Port A I2C拡張ハブユニット）をM5Stack＋UIFlowで使う

# はじめに
M5Stackで複数のセンサを一緒に使いたい！
PaHUB（M5Stack用Port A I2C拡張ハブユニット）を使いたい！センサとの通信はI2C！
それを、UIFlowで実現したい！

そう思った時に、少し困ったので、使い方をまとめておきます。
UIFlowでも、やったことがある人は当たり前かもしれないですが、ちょっとネット上にも情報が少ないような気がしたので、メモがてら。
<br>

👇今回使用するPaHUB（M5Stack用Port A I2C拡張ハブユニット）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/8b9a895e-25a5-01b1-d9c8-c72ba0ba1b85.png)

https://ssci.to/7588

ひとつのI2C HY2.0-4Pインターフェースを最大6チャンネルのI2Cに拡張/接続できる拡張ハブです。




# まずは確認する公式ドキュメントなのですが
👇まずは、公式ドキュメントを確認します

https://docs.m5stack.com/en/unit/pahub

<br>

UnitによってUIFlowのサンプルがあるものとないものがあるような気もしますが、PaHUBに関しては以下のようなサンプルが準備されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/0d0c727b-9141-3be4-8fb8-b7994273aa10.png)

<br>

サンプルを参考にUIFlowで複数のUnitを使っていきたいのですが、分からない(笑)
ぱっと見で複雑に感じたのですが、詳しく見ても自分には更に分かりませんでした。
これでは、とても簡単にセンサを扱えていたのに、これは良くないなと思い、


# 簡単に使えるようにちゃんと準備されていた
公式ドキュメントでは分からなかったのですが、実は簡単に使用することができました！

### PaHUBの追加
その他のUnitと同様に追加することができます。現時点では、『port』とI2Cの『Address』を設定できます。PaHUBは、デフォルトでは、「0x70」なので、このまま使用できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/7a51614a-9edc-57f4-a3fa-97d93cc14aed.png)


### その他のUnitを追加

今回は、よく使われそうな環境センサ(ENV Unit)を例に話を進めます。
『port』の選択に、『PAHUB』が準備されているので、こちらを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/0d43d8eb-87a7-9597-e65c-b7f8ab91c848.png)

『port』で、『PAHUB』を選択すると、次に、『PAHUB』のどのチャンネルを使用するかを選択できるようになります。PaHUBは、全部で６チャンネル用意されていますが、こちらでどのチャンネルにこのUnitを接続するのかを設定することが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/a5373635-3994-66ba-8b75-de4c08af54d9.png)

<br>

上記のような手順でUnitを追加していくことで、あとは普通にUnitを追加した場合を同じようなブロックで制御できます。とても簡単に使えて助かりました。ただ、ネットを調べるとあまりこの辺りの情報が少なくて、ハマりポイントの１つかと思います。


# その他の注意事項

### M5Stack用温湿度気圧センサユニット Ver.3（ENV Ⅲ）はI2Cアドレスが被っているので注意！

内部で使用している気圧センサQMP6988のI2Cアドレスが、[0x70]なので、PaHUBを被ってしまい、そのままでは使用することができません。その場合は、PaHUBの基板でPaHUBのI2Cアドレスを変更できるので、こちらを変更することが可能です。

https://ssci.to/7254

# まとめ
複数のセンサを一緒に使いたい場合は多くあると思うのですが、これもUIFlowで簡単に使用できるようになるので、更に試せることが多くなると思います！是非、参考に！
macのターミナルでカーソルを移動させる方法

# 行頭･行末へ移動する
## 行頭へ
- `ctrl + a`

## 行末へ
- `ctrl + e`

# １単語ごとに移動する
## 前(左)に
- `ctrl + [` 押してから `b`
- `esc` 押してから `b`
- `opt + ←`

## 後ろ(右)に
- `ctrl + [` 押してから `f`
- `esc` 押してから `f`
- `opt + →`

# １文字ずつ移動する
## 前(左)に
- `ctrl + b`
- `←`

## 後ろ(右)に
- `ctrl + f`
- `→`

# おまけ
## 文字を削除する
### 行ごと(カット)
- `ctrl + u`

### カーソルから行末まで(カット)
- `ctrl + k`

### カーソルより前(左)にある１単語を削除する
- `ctrl + w`

### １文字ずつ削除する
#### カーソルの前(左)にある文字を
- `ctrl + h`
- `BackSpace`

#### カーソル上の文字を
- `ctrl + d`
- `fn + BackSpace`
- `delete`

## 最後にカットした文字を貼り付ける
- `ctrl + y`
Amazon Titan Text ExpressをCloudShellで実行する

# 概要
Amazon Titan Text ExpressをCloudShellで実行する手順を残します
CloudShellとAmazonが提供しているテキスト生成モデル Amazon Titan Text の紹介のみとなります
コードはAmazon公式サイトの物をほぼ流用させて頂きました

# Amazon Titan Text G1 - Expressとは
- Amazon Titanテキストモデルの一つです
- テキスト生成用の大規模言語モデルであり、検索拡張生成 (RAG) をサポートするだけでなく、自由形式のテキスト生成や会話型チャットなどに対応可能です
- 現時点(2024.8.31)では英語のみ対応の模様です
- サポートするユースケース
    - 検索拡張生成
    - 自由形式のテキスト生成
    - ブレインストーミング
    - 要約
    - コード生成
    - 表作成
    - データフォーマット
    - 書き換え
    - 抽出
    - Q&A
    - チャット

# CloudShell
- ブラウザベースで利用可能
- AWSマネジメントコンソールから直接起動可能
- 事前にシェル構築済み
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235774/9cf9d3c0-693c-b6c2-6322-7030eccf6869.png)

# CloudShellでAmazon Titan Text ExpressのAPI実行

## CloudShellにてpythonコマンド実行
```bash
$ python
Python 3.9.16 (main, Jul  5 2024, 00:00:00) 
[GCC 11.4.1 20230605 (Red Hat 11.4.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
```

## API実行
Pythonで Amazon Titan Text ExpressのAPI 実行します。
``` prompt = "Write the code for the Hello World program in Vue.js" ```
で、プロンプトを定義しています。
英語で「Vue.jsでHello Worldプログラムのコードを書いて」と定義

```py
import boto3
import json

from botocore.exceptions import ClientError

# Create an Amazon Bedrock Runtime client.
brt = boto3.client("bedrock-runtime")

# Set the model ID, e.g., Amazon Titan Text G1 - Express.
model_id = "amazon.titan-text-express-v1"

# Define the prompt for the model.
prompt = "Write the code for the Hello World program in Vue.js"

# Format the request payload using the model's native structure.
native_request = {
    "inputText": prompt,
    "textGenerationConfig": {
        "maxTokenCount": 512,
        "temperature": 0.5,
        "topP": 0.9
    },
}

# Convert the native request to JSON.
request = json.dumps(native_request)

response = brt.invoke_model(modelId=model_id, body=request)

# Decode the response body.
model_response = json.loads(response["body"].read())

# Extract and print the response text.
response_text = model_response["results"][0]["outputText"]
print(response_text)
```

## 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235774/b20d25bb-6712-f3e2-4cc4-300f1f4e7201.png)

- コードは以下です
- ちょっと物足りないですが、ちゃんと書いてくれました。

``` JavaScript
// Define a Vue component named 'HelloWorld'
Vue.component('hello-world', {
  // Define the template for the component
  template: '<div>Hello, Vue!</div>'
});
// Create a new instance of the 'HelloWorld' component
new Vue({
  el: '#app'
});
```

#参考サイト
[Amazon Bedrock での Amazon Titan](https://aws.amazon.com/jp/bedrock/titan/)
[Amazon Titan Text G1 - Express](https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/titan-text-models.html)
[Amazon Bedrock ユーザーガイド](https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/getting-started-api-ex-python.html)
[AWS CloudShell とは](https://docs.aws.amazon.com/ja_jp/cloudshell/latest/userguide/welcome.html)
AI ChatGPTへの質問　そのままコードを使うと怒られる編

エンジニアと話しているとき、よくAIの使い方について話に上がってきます。
なぜか話すとベテランエンジニアが喜んでくれた使い方が2つあったので、書き残そうと思います。

# 目次

- [1行ずつ説明させる](#1行ずつ説明させる)
- [複数パターンを提示させる](#複数パターンを提示させる)

# 1行ずつ説明させる
新人エンジニアでは、使用したことのない言語の案件を担当して、こんなことがよくあると思います。
「やることが漠然としていて何からしたらいいかわからないどうしよう？」
「AIに聞いちゃおう！」
「でも、上司や先輩にはそのまま使うな、理解していないコードは書いちゃダメって言われるしな...」

結論、AIを使っても理解していればそのコードを使っても問題はないと思います。
ではどうやって理解するかです。

それもAIに任せちゃいましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873715/c2808ecb-00da-140e-9be7-e511479fa70a.png)

「何が書いてあるかさっぱりだ...」
そこで1歩踏み込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873715/91166bc7-beee-138d-e063-1226b956daf6.png)

これによって
「そうか、プッシュ通知にはNotificationというものと、serviceWorkerというものが必要なんだな。まずはそのチェック処理をしてから後の処理をするんだ。」
と気付くことが出来ます。
※AIが間違ったことを言っている可能性もあるので、このやり方が正しいかも調べたら良いと思います。

また、「このコードなんで入れたの？」と聞かれてもこれで答えられますね。
勉強するときにも使えるので、ぜひやってみてください。

# 複数パターンを提示させる
AIに質問をしていてこんなことはないでしょうか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873715/7018101d-1bf8-d9f0-24d1-a3e6cd6da093.png)

「よしよし、この通りにやれば...あれ？直らないんだけど...」
そんなときに複数パターンを提示してもらいましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873715/84536e27-bf91-6aef-7f32-45bc47badac4.png)

このようにすれば自分に合った解決方法が見つかりやすくなり、
もしその中に答えがなかったとしても、どういう視点で解決していけば良いかがなんとなくわかってきます。
EclipseでのKotlin開発ガイド：バージョン互換性、非公式プラグインの活用と代替IDEの選択

# はじめに

Kotlinは、シンプルでモダンなプログラミング言語として人気を集めていますが、Eclipseでの開発環境の整備には注意が必要です。Eclipseは多くの開発者に親しまれているIDEですが、Kotlinの開発においてはバージョン管理やプラグインの選択が非常に重要です。本記事では、EclipseでのKotlin開発におけるバージョン互換性、非公式プラグインの利用方法、そしてEclipseの代替としてIntelliJ IDEAの利点について解説します。

# EclipseとKotlinのバージョン互換性

## 1. 安定したKotlinバージョン：1.5, 1.6
- **推奨Eclipseバージョン**: Eclipse 2020-03 (4.15) 以降
- **対応JDKバージョン**: Java 11からJava 17
- **特徴**: 
  - Kotlin 1.5および1.6はEclipseの公式Kotlinプラグインで安定してサポートされており、幅広いJDKのバージョンと互換性があります。業務システム開発に適したバージョンです。

## 2. 実験的サポート：Kotlin 1.7以降
- **推奨Eclipseバージョン**: Eclipse 2023-03 (4.27) 以降
- **対応JDKバージョン**: Java 17およびJava 20
- **特徴**:
  - Kotlin 1.7以降は公式プラグインでのサポートが実験的であり、安定性は保証されていません。新機能を試したい開発者には興味深い選択肢となりますが、本番環境での利用には注意が必要です。

# 最新の非公式プラグインの活用

Eclipseの公式プラグインは最新のKotlinバージョンのサポートが遅れているため、非公式のプラグインを利用するのも一つの手です。

- **非公式プラグインリポジトリ**: [https://github.com/bvfalcon/kotlin-eclipse-2024](https://github.com/bvfalcon/kotlin-eclipse-2024)
  - 最新のKotlinバージョンに対応した非公式プラグインが提供されています。特にKotlin 1.7から2.0.0の利用を検討している場合には有効な選択肢となります。
  - **導入方法**: ダウンロード後、Eclipseの「Install New Software...」機能を使用してプラグインをインストールします。十分にテストを行い、環境の安定性を確認することが重要です。

# Eclipseのプラグインメンテナンス状況と代替IDEの選択

EclipseのKotlinプラグインは、更新が滞りがちであり、最新のKotlinバージョンへの対応が遅れる傾向があります。そのため、EclipseでのKotlin開発は特定のバージョンに依存しやすく、最新の機能を使用する際に制約が生じる可能性があります。

## **より適した代替IDE: IntelliJ IDEA**

- **IntelliJ IDEA**: JetBrains社が提供する公式のKotlin開発環境であり、Kotlinの最新バージョンのサポートやプラグインの更新が迅速に行われます。IntelliJはKotlinのフルサポートを提供し、最適な開発体験を実現します。
- **利点**:
  - **最新バージョン対応**: Kotlinの最新機能や改善点を迅速に取り入れ、常に最適な開発環境を提供します。
  - **高い統合性**: Kotlinだけでなく、Javaや他のJVM言語との統合も優れており、一貫した開発環境を提供します。
  - **豊富なプラグインエコシステム**: 豊富なプラグインが提供されており、開発の効率化やプロジェクトの拡張が容易です。

# まとめ

EclipseでのKotlin開発には、安定したKotlin 1.5および1.6のバージョンを使用することが推奨されますが、最新の機能を求める場合には非公式プラグインの利用やIntelliJ IDEAの導入を検討してみてください。特にIntelliJ IDEAは、Kotlinの開発において最も適したIDEであり、最新のKotlinバージョンをすぐに利用できるという大きな利点があります。Eclipseに固執せず、必要に応じて最適な開発環境を選び、Kotlinの魅力を最大限に活用しましょう。

# 参考

https://qiita.com/blue_islands/items/487e8727372f30825120
競馬予想AIを作りたい（AI学習編２）【作れた】

# はじめに
回収率100%超えウオオオーーーーー！！！！

失礼、取り乱しました。

## 前回までの話
1. 中央競馬の過去のデータを収集し、DNNやCNNで1着を当てるよう学習させたが、精度が20%程度しか出なかった
2. 低精度の原因を考え直したが、変わらずダメ
3. データの項目を見直し、相関関係などを見たが、人気や単勝オッズがそれなりに相関していること以外あまり有益な情報が得られなかった

## 今回の話
アプローチを変えた。
レース単位で入力するのではなく、馬単位で入力した。
例えば以下の表の場合、1行1件のデータとして入力し、着順を予想させた。

| 着順 | 馬番  | 単勝オッズ | ...  |
|:----:|:----:|:---------:|:----:|
| 15   |  1   | 103.9     | ...  |
| 7    |  2   | 21.2      | ...  |
| 3    |  3   | 23.9      | ...  |
| ...  | ...  | ...       | ...  |


また、今までは1着を当てる方向で学習させていたが、掲示板入着を当てるようにした。
要は掲示板に入るか入らないかの2値分類にした。
掲示板入着を当てられれば、三連単や三連複の的中も狙えるのでお得。

学習にあたっては、XGBoostを採用した。
こういったデータに対する実績が高いから。
パラメータは以下の通り
- max_depth: 2
- objective: multi:softmax
- nthread: 4
- eta: 1e-2
- 学習回数: 1000

学習データは2008年～2022年の中央競馬・芝レースに限り、1勝以上のレースのみとした。
テスト用のデータは2023年以降とし、その他条件は学習データと同じ。

これで学習させた結果、各変数の影響力は以下のグラフとなった。
![importance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382806/25f1900d-985f-9025-7377-a48a8cd8ead1.png)

単勝オッズと人気が重要なのは分かるが、なんと2走順位が重要という結果に。
前走よりも2走前の方が重要とは、どう解釈すれば良いんだ？（誰か教えて）

各種指標は以下の通り。（テストデータ）
| 目的変数 | precision | recall | f1-score | 件数   |
|:-------:|:---------:|:------:|:--------:|:------:|
| 0       | 0.66      | 0.54   | 0.60     |  7,913 |
| 1       | 0.74      | 0.82   | 0.78     | 12,454 |

目的変数が0、つまり掲示板入着のrecallが低いのが気になるが、冒頭のとおり回収率が十分なので気にしない。
逆に板外の予測精度は高めだが、そもそもデータが偏ってるので、「とりあえず1と言っときゃいいだろ」となってる可能性は否定できない。

なお、予測精度は72%。

# 回収率
作ったAIが0（掲示板入着）だと判断した馬を買うシミュレーションで計算した。
仮に5頭を0だと判断した場合、単勝は5頭分の500円、三連単は5P3通りなので6,000円、三連複は5C3通りなので1,000円を賭けることになる。
それぞれ賭けて、実際のオッズで払戻金を計算した。

学習データにおいては以下の通り。

|         | 回収率            | 馬券代      | 払戻金              |
|:-------:|:----------------:|:-----------:|:------------------:|
| 単勝    | 16,822.38%       | 6,012,800   | 1,011,496,000      |
| 三連単  | 240,440,354.26%  | 32,970,600  | 14,457,197,621,000 |
| 三連複  | 9,011,194.07%    | 2,433,100   | 219,251,363,000    |

テストデータの場合は以下の通り。

|         | 回収率            | 馬券代      | 払戻金              |
|:-------:|:----------------:|:-----------:|:------------------:|
| 単勝    | 83,734.11%       | 648,400   | 542,932,000      |
| 三連単  | 20,887,560.76%  | 3,557,400  | 135,434,944,000 |
| 三連複  | 778,158.11%    | 266,900   | 2,076,904,000    |

どちらのデータでも、回収率が100%どころじゃないことが分かる。
これで爆勝ち間違いなしや！ｗ

# まとめ
良い勉強になりました。
焚き付けてくれた友人に感謝します。

今後は、今回扱っていない新馬戦やダート、地方競馬、あるいは未来のレースで試してみて、調子良さそうならweb公開とか考えてみます。
DBeaverの設定データ移行手順

# 概要

DBeaverは様々なDBMSに対応したマルチプラットフォームのデータベースクライアントです。業務使用していて複数の環境や接続先を設定し愛用していたのですが、PC新調のため移行する必要が生じました。データベースへの接続設定など、DBeaverの設定すべてを移行します。DB最終的には簡単に移行できたのですが、日本語での情報が少ないのでここに記載します。

- インポート・エクスポート機能が用意されているので、これを使用。
- 旧PCにて、メニューバー > ファイル > エクスポート >
- 「DBeaver」の「プロジェクト」 >
- 「General」にチェック、出力先ファイル・ディレクトリを設定し「終了」、`*.dbp`ファイルを出力
- 新PCにて、メニューバー > ファイル > インポート >
- 「DBeaver」 > 「プロジェクト」 >
- 先ほどの`*.dbp`ファイルを指定
- プロジェクト設定を出力、名前がGeneralで被ってしまう。上書きインポートはできない。
- 「データベースナビゲータ」に表示されるよう、インポートしたプロジェクトをアクティブプロジェクトに設定。
- sshキーファイルのパスなど、必要に応じて修正

## 手順

旧PCから新PCへ設定を移行します。

### 旧PCにて、DBeaverの設定を「エクスポート」

- メニューバー > ファイル > エクスポート >
- 「DBeaver」 > 「プロジェクト」を選択し「次へ」押下（下記画像）

![エクスポートモーダル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139537/875acc43-e9b5-368d-9378-95a8f3bda4ae.png)

- 「General」（普段使用しているプロジェクト）にチェックし、出力先ファイル・ディレクトリを設定し「終了」（下記画像）

![プロジェクトのエクスポートウィザード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139537/400e6122-518f-0e4a-73d9-5283c87c5f35.png)

- 指定したディレクトリに`*.dbp`という拡張子のファイルが出力されているので、新PCへコピー

### 新PCにて、DBeaverの設定を「インポート」

- メニューバー > ファイル > インポート >
- 「DBeaver」 > 「プロジェクト」を選択し「次へ」押下（下記画像）

![インポートモーダル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139537/49743e17-3b2e-9a91-00b5-212678b834ba.png)

- 「入力」の「ファイル」に旧PCからコピーした`*.dbp`ファイルを指定（下記画像）

![インポートウィザード1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139537/5a389f17-1f6c-2a59-fe8d-fd6f447e1dd3.png)

- 「プロジェクト」にて、「General」にチェックを入れ、ターゲット名は任意の名前（`General2`など）に変更
- モーダル上部に「プロジェクトをインポートする準備ができました」と表示されることを確認（下記画像）

![インポートウィザード2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139537/d124be4e-d8ba-5a22-ee36-07fa55c99559.png)

- プロジェクトインポートに成功した旨のダイアログが出現することを確認
- 左ペインから「プロジェクト」タブを表示
- 先ほどターゲット名に指定したプロジェクト名（例では`General2`）を右クリックし「アクティブなプロジェクトを設定」（下記画像）

![アクティブなプロジェクトを設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139537/9f847544-e267-2d79-e244-e073696c2746.png)

- 左ペインの「データベースナビゲータ」に設定していたデータベース接続が一覧されることを確認

以上で完了です。不要であれば初期からあるプロジェクト`General`は削除してしまって構いません。

## その他

### SSHトンネル機能で使用するSSHキーのパス

WindowsPCからWindowsPCへ移行した際の話になります。SSHトンネルを使用したデータベース接続設定の場合は、SSHキーのパスは絶対パスで指定されているようでした。私はSSHキーを`%USERPROFILE%\.ssh`配下に指定していました。また、新PCではユーザ名を変更してしまいました。そのため、新PC上ではパスが合わなくなってしまい、キーのパスを設定し直す必要が生じました。

### 「データベースナビゲータ」と「アクティブなプロジェクトを設定」

左ペインにある「データベースナビゲータ」は、現在アクティブなプロジェクトの「Connections」を参照してくれるようです。今まで1つのプロジェクト「General」のみを使用していたためこれに気付きませんでした。初めてプロジェクトのインポートを行い、複数プロジェクトが存在することになり、どうやっても「データベースナビゲータ」にデータベースが一覧されないのでしばらくはまりました。

### 「一般」 > 「設定」の機能は…

最初わからず下記のエクスポートウィザードで行っていました。想定したエクスポートが行われないようで、移行のやり直しになりました。

- メニューバー > ファイル > エクスポート >
- 「一般」 > 「設定」

これはどのような使い方をするのか…調べ切れていません。

## 動作確認環境

私が動作確認できた環境一覧です。

|移行元|移行先|結果|
|---|---|---|
|Windows 10 pro|Windows 10 Pro|OK|
|Windows 10 pro|macOS Monterey|OK|

DBeaverバージョン24.1.5.202408181605


## 参考

- [How can I export DBeaver connection configurations? - Stack Overflow](https://stackoverflow.com/questions/56561439/how-can-i-export-dbeaver-connection-configurations)
【GitHub Actions】APIで呼び出した別リポジトリのWorkflow Run URLを呼び出し元に表示する

## はじめに

GitHub Actionsでは、APIを使ってリポジトリAのワークフローから別のリポジトリBのワークフローをトリガーすることができます。
しかし、[Create a workflow dispatch event API](https://docs.github.com/ja/rest/actions/workflows?apiVersion=2022-11-28#create-a-workflow-dispatch-event)のレスポンスには、トリガーされたリポジトリBのワークフローに関する情報は含まれず、リポジトリAからすぐに該当のワークフローを見つけることができません。

この記事では、トリガーされたワークフローのURLをリポジトリA側で取得する方法を紹介します。

## サンプルコード
### 呼び出し側（リポジトリAに格納）
```yml: test.yml
name: GitHub Actions Demo
on: workflow_dispatch
env:
  repo_owner: xxxxxx
  repo_name: target

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Trigger workflow in another repository
        run: |
          curl -L \
            -X POST \
            -H "Accept: application/vnd.github+json" \
            -H "Authorization: Bearer ${{ secrets.PAT }}" \
            -H "X-GitHub-Api-Version: 2022-11-28" \
            https://api.github.com/repos/$repo_owner/$repo_name/actions/workflows/target.yml/dispatches \
            -d '{
              "ref":"main",
              "inputs":{
                  "name":"hoge"
              }
            }'

      - name: Sleep for 5 seconds
        run: sleep 5s

      - name: Get the triggered workflow
        run: |
          workflows_list=`curl -L \
            -X GET \
            -H "Accept: application/vnd.github+json" \
            -H "Authorization: Bearer ${{ secrets.PAT }}" \
            -H "X-GitHub-Api-Version: 2022-11-28" \
            https://api.github.com/repos/$repo_owner/$repo_name/actions/runs`
          latest_workflow=$(echo $workflows_list | jq -r '.workflow_runs[0].html_url')
          echo $latest_workflow >> $GITHUB_STEP_SUMMARY
```
### 呼び出される側（リポジトリBに格納）
今回は``inputs``を定義してみましたが、呼び出される側のコードはどんなものでも構いません。
```yml: target.yml
name: Target Workflow

on:
  workflow_dispatch:
    inputs:
      name:
        description: 'name'
        required: true
    
jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        
      - name: ${{ inputs.name }}
        run: echo "My name is ${{ inputs.name }}"
```

## 説明
- `Trigger workflow in another repository`ステップでは、[Create a workflow dispatch event API](https://docs.github.com/ja/rest/actions/workflows?apiVersion=2022-11-28#create-a-workflow-dispatch-event)を用いてリポジトリBのワークフローをトリガーしています。リポジトリBの入力に合わせて、``inputs``を渡しています。
- `Get the triggered workflow`ステップでは、[List workflow runs for a repository API](https://docs.github.com/ja/rest/actions/workflow-runs?apiVersion=2022-11-28#list-workflow-runs-for-a-repository)を用いてリポジトリBの全てのworkflow runを取得しています。続いて、そのレスポンスのリストの中で、最新のworkflow runである0番目の`html_url`を抽出しています。最後に抽出した`html_url`をgithub step summaryに表示しています。
- 上記2つのステップの間にある`Sleep for 5 seconds`ステップは、`Trigger workflow in another repository`ステップの直後に`Get the triggered workflow`ステップを実行すると、最新のworkflow runが反映されなかったため、付け足しています。

## おわりに
今回はシンプルな実装を試しましたが、この実装では、ほとんど同時に複数回トリガーされた場合に、呼び出したworkflow runのURLを正しく取得できないことが考えられます。
これを解消するには、List workflow runs for a repository APIのレスポンスに含まれるnameやactorなどの情報をうまく活用する必要があります。

最後までお読みいただきありがとうございました。
変数にnilとかつけちゃダメだよ

## 特徴

Go言語でnilはユニバースブロックで定義されています。[ユニバースブロックとは公式によると](https://tip.golang.org/ref/spec#Blocks)Go言語でのユニバースブロックとはソースコード全体を包んでいるブロックを示します。これはプログラム全体のスコープを指し、すべてのプログラムで共通に使用される識別子や型が含まれています。

## 実装

```main.go
package main

func main() {
    nil := 42  // ここでnilを再定義
    var ptr *int
    if ptr == nil {  // 本来のnilの意味が失われている
        println("ptr is nil")
    }
}
```

上記の実装では、本来のnilの性質をシャドーイングしバグが発生しやすくなります。

## 参考記事

[The Go Programming Language Specification - The Go Programming Language](https://tip.golang.org/ref/spec#Blocks)
asdfでgoを管理しているときのPATHの通し方

GOをインストールして時に以下のように.zshrcに記述していたら、シェル起動時にパスが通っていなかった

```zsh
export PATH=$PATH:$(go env GOPATH)/bin
```

シェル起動時のルートでgoが有効になっていなかったため```go env GOPATH```が無効だった。
もしルートで有効だとしても複数のバージョンを使い分けている場合、ルートで使用しているバージョンしかパスが通らない。

asdfで管理しているすべてのバージョンのパスを通すには以下のようにする

```zsh
for version in $(ls ~/.asdf/installs/golang); do
    export PATH=$PATH:~/.asdf/installs/golang/$version/go/bin
done
```
Perl

perl -cw <プログラムファイル>
⇒プログラムを実行せずに文法とプログラム中の識別子の利用方法についてチェック

wオプション： use warnings
use warnings;
⇒詳細な警告を出力する

use strict;
⇒厳密な構文チェックを行う
※変数の宣言がmust
VBA

'関数宣言
Set objShell = CreateObject("WScript.Shell")
Set objFso = CreateObject("Scripting.FileSystemObject")

'親ディレクトリの取得
CurrentPath = ActiveWorkbook.Path

'実行
set oExec = objShell.Exec(Execbat & " " & <引数>)

'前処理が完了するまで待機
Do While oExec.Status = 0
    Application.Wait(Now + TimeValue("0:00:05")) '5秒待機
Loop

'最終行の取得
Cells(Rows.Count,1).End(xlUp).Row
※後ろからする時(行の削除・挿入など)
Cells(Rows.Count,1).End(xlUp).Row To 2 step -1

'文字色
Cells(i,4).Font.color = vbred
'背景色
Cells(i,4).Interior.color = vbred
※基本色
vbRed,vbBlack,vbGreen,vbBlue,vbYellow,vbMagenta,vbCyan,vbWhite
Pythonで画像から文字列を読み込み（OCR）

# 1.ライブラリをインポート
```
pip install pillow
pip install pytesseract
```
# 2.Tesseract-OCRをインストール
https://digi.bib.uni-mannheim.de/tesseract/?C=M;O=D

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/5a365c9c-7eb1-6693-cbe4-5fea4c1ab1d0.png)

# 3.日本語のOCRの訓練データを取得
下記のサイトからダウンロードして、「Tesseract-OCR\tessdata」のパスに格納する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/27c43dc1-c827-ca57-f9f7-6f03164a8a64.png)

https://github.com/tesseract-ocr/tessdata_best/blob/main/jpn.traineddata

# 4.Pythonで画像から文字列を読み込み
```Python
from PIL import Image
import pytesseract
import os

# Tesseractのパスを指定
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' 

# 画像フォルダのパス
image_folder = 'C:/Desktop/pdf'

# 結果を保存するフォルダ
output_folder = 'output_txts'
os.makedirs(output_folder, exist_ok=True)

# 画像をループ
for image_file in os.listdir(image_folder):
    if image_file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tiff')):  
        # 画像のパス
        image_path = os.path.join(image_folder, image_file)
        
        # 画像を読み込み
        image = Image.open(image_path)
        
        # Tesseractを使って画像を読み込み
        text = pytesseract.image_to_string(image, lang='jpn')  # 'jpn' は日本語、英語の場合は 'eng'
        
        #  txtファイルを作成
        txt_name = os.path.splitext(image_file)[0] + '.txt'
        txt_path = os.path.join(output_folder, txt_name)
        
        # 文字列をTXTに書き込み
        with open(txt_path, 'w', encoding='utf-8') as txt_file:
            txt_file.write(text)
        
        print(f"{image_file} は {txt_name}に書き込みました")

print("完了")

```
# 下記のエラーが出た場合

modulenotfounderror: no module named 'pytesseract'
```
pip show pytesseract
# ⬇️こんな情報が出てくる

Name: {モジュール名}
Version: 0.13
Summary: {モジュール名} cryptographic signature library (pure python)
Home-page: http://github.com/xxxxxx/xxxxxx
Author: xxxxx xxxxx
Author-email: xxxxx@xxxxx.com
License: XXXXX
Location: /opt/anaconda3/envs/xxxxxxxx/lib/pythonX.X/site-packages -> このPASSをコピーする
Requires: 
Required-by: 
```
```
import sys

# passの設定 (pip showで出てきた、LocationのPASSを以下に設定)
sys.path.append('/opt/anaconda3/envs/xxxxxxxx/lib/pythonX.X/site-packages')

# passの設定はimportするモジュールより前に設定
import xxxxxx
```

# 参考サイト
https://blog.csdn.net/maiya_yayaya/article/details/137827403

https://qiita.com/ymto/items/e00e95543aab2d4d45ee
【JavaScript】Ruby以外のフレームワークについて気になったのでVue.jsについて調べてみた

どうもこんにちは。

今回は、RailsではなくVue.jsについて調べてみました。言語は違いますが、同じフレームワークのRailsと自分の感覚を比較してみようと思います。合わせて環境構築もしてみたので、参考になればと...

以下のサイトを参考にしています。

https://www.webstaff.jp/guide/trend/webit/vuejs/

# Vue.jsってなに？

JavaScriptフレームワークの一つです。

> ユーザーから見えている部分をシンプルかつ高速に処理することができるフレームワークです。画面描画に対する新しい考え方とデータ管理の仕組みが、それを実現しています。また、チーム開発において作業の分担がしやすくなる形式のファイルを扱えるなど、開発を効率化できるのも特徴です。

HTMLやJSのコーディングが苦手な人には向いているかも？と思いました。自分の場合、バックエンドよりもフロントエンドのコーディングが苦手なので、Vue.jsを使ってフロントの勉強をするのも一つの手なのかなと思いました。

## 仮想DOM

> Vue.jsには仮想DOMという概念があり、JavaScriptオブジェクトを使って差分のみをDOMに反映する処理をおこなっています。

JSでフレームワークを使用せずに画面遷移を実装するとしたら、DOMを書き換える必要があるようなのですが、これが必要なくなるようですね。

Railsと比較して、画面遷移はRailsの方がやりやすそうです。（`config/route.rb`にパスを記述すれば良いだけなので。）

## シングルページアプリケーションの開発に向いている

と思ったら、Railsとは違って画面遷移しないアプリケーションの開発に向いているようですね！

確かにRailsは画面遷移するたびに、サーバと通信してレンダリングしますが、Vue.jsを使用することでサーバを介さずに簡単に画面切替ができるようです。DBを使用してアプリ開発する場合にはAjaxを使用する方向になるのでしょうか？

## DBの接続は？

Railsと違って、Vue.jsはDBの接続に対する機能が用意されていないので、少々難易度が高いようです。

# Vue.js + Railsで実装できる？

調べていて初めて知ったことなのですが、フロントはVue.js、バッグエンドはRailsというように分けて実装することもできるようです。

これによって、DBへの接続も簡単にできるようになりそうですね。

# Let's 環境構築

## 手順

### 1. ディレクトリ作成

```sh
mkdir vuejs_test
cd vuejs_test
```

### 2. vue createコマンドでvue-appプロジェクトを作成

```sh
docker run --rm -v ${PWD}:/app -w /app node:14-alpine sh -c "npm install -g @vue/cli && vue create -d vue-app"
```

### 3. vue-appディレクトリへ移動

```sh
cd vue-app
```

### 4. Dockerfile作成

```sh
touch Dockerfile
```

以下のコードをコピペします。

```Dockerfile
# ベースイメージ
FROM node:14-alpine

# 作業ディレクトリの設定
WORKDIR /app

# パッケージファイルをコピー
COPY package*.json ./

# 依存関係のインストール
RUN npm install

# アプリケーションのソースをコピー
COPY . .

# 開発サーバーのポートを公開
EXPOSE 8080

# アプリケーションの起動
CMD ["npm", "run", "serve"]
```

### 5. docker-compose.yml作成

vuejs_testディレクトリに戻ります。

```sh
cd ..
touch docker-compose.yml
```

以下のコードをコピペします。

```yml
version: '3.8'
services:
  vue-app:
    build: ./vue-app
    ports:
      - "8080:8080"
    volumes:
      - ./vue-app:/app
    stdin_open: true
    tty: true
```

### 6. ビルド

```sh
docker-compose build
```

### 7. 環境起動

```sh
docker-compose up
```

<http://localhost:8080>にアクセスすることで、HelloWorld画面が表示されます。

# ソースコード

https://github.com/pdc-kurashina/vue-js-sample-app/tree/master
【Rails】サーバ起動したら勝手にコードが実行されて499HTTPエラーが起きた件

どうもこんにちは。

今回は、AWS Elastic Beanstalk環境にデプロイした時に発生した499エラーの原因を解決したので、備忘録として残します。

# 何が起きていた？

当初は、以下の流れでデプロイをしていきたいと思っていました。

1. ソースコードを`git commit`
1. `eb deploy`実行
1. URLにアクセスして動作確認

しかし、3番目で499エラーが発生してしまいました。（**画面上では、502や504が表示されます。**)

# 原因はなんだったん？

499エラーの原因は、`lib`ディレクトリにありました。
開発者や組織によると思いますが、自分の触っているRailsアプリでは、**`lib`ディレクトリを`eager_load_path`に追加していました**。

```rb:config/application.rb
class Application < Rails::Application
    config.eager_load_paths << "#{config.root}/lib"
end
```

# なんでeager_load_pathにしたらいけなかったの？

`eager_load_path`に特定のディレクトリを指定すると、Railsサーバーが立ち上がった時に、自動で実行されてしまいます。自動で実行したい場合には、`eager_load_path`に追加してもいいのですが、何も知らずに`eager_load_path`に追加してしまうのは避けたいです。

ただ、気をつけていただきたいのが、**<font color="red">`lib`ディレクトリを`eager_load_path`に追加したらダメ</font>** というわけではないです。

一番言いたいことは、**`eager_load_path`に`lib`ディレクトリを追加したなら、バリデーションに引っ掛かるようなスクリプトは`lib`ディレクトリには保存しない！** ということです。

# どんなコード書いてたの？

こんなコード書いていました。

```ruby
class Tasks::DeleteFormatColumn
    content_items = ContentItem.where(format: %w[PNG JPEG BMP])
    
    content_items.each do |content_item|
        # 処理
        content_item.save!
    end
end
```

`content_item.save!`が実行される前に、バリデーションに引っ掛かるようなデータを作ってしまうような処理を行なっていました。

はぁ...

ということで、`eager_load_path`に追加されていないディレクトリにファイルを避難して解決です。
PowerShell

#関数宣言
\\$objExcel = New-Object -ComObject Excel.Application
\\$objShell = New-Object -ComObject WScript.Shell
$objFso = New-Object -ComObject Scripting.FileSystemObject

#親ディレクトリの取得
\\$CurrentPath = \\$objFso.GetParentFolderName($MyInvocation.MyCommand.Definition)

#Excel
\\$ExcelFile = \\$CurrentPath + "¥<Excelファイル名>.xlsm"
$MacroFile = "<マクロ名>"

#Excelを表示に設定
\\$objExcel.Visible = $True

#ブックを開く
\\$workbook = \\$objExcel.Workbooks.Open($ExcelFile)

#マクロを実行
& \\$objExcel.Application.Run($MacroFile,"<引数1>","<引数2>")

#ブックを閉じる
$workbook.Close()

#Excelを終了
$objExcel.Quit()

#COMオブジェクトを解放
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject(\\$objExcel) | Out-Null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

#スクリプトの設置フォルダを取得
\\$CurrentDir = Split-Path -Parent $MyInvocation MyCommand.Path

☆スクリプトファイルの1階層上の指定
Join-Path $PSScriptRoot "..¥<ファイル名>"
CodeWars オススメ問題 #1

# はじめに

個人的に好きなアルゴリズム学習サイト「CodeWars」の問題をシェア。

週1くらいのペースで、全10回を目指す予定。

:::note
CodeWarsはいいぞ！の紹介は[こちら](https://qiita.com/kohki_takatama/items/2ae2808b931e943262b8)

CodeWarsの始め方は[こちら](https://qiita.com/javacommons/items/7c473cda7825ab99e08c
)
:::
# オススメ問題

https://www.codewars.com/kata/570a6a46455d08ff8d001002/javascript

### 例
末尾の0を削除してくれ、という問題です。
```
1450 -> 145
960000 -> 96
1050 -> 105
-1050 -> -105
```
### 難易度
分類は 8kyu（最も簡単）ですが、個人的には 7kyu 相当です。

# オススメの回答
「評価が高い回答」の中から、学びの多い回答をピックアップしてご紹介。

:::note
<details><summary>条件設定と繰り返し処理</summary>

https://www.codewars.com/kata/reviews/570bb3f1c631137326000047/groups/570c6c52f616a83d6e000b0b
```js
function noBoringZeros(n) {
  while (n % 10 === 0 && n !== 0) {
    n = n / 10
  }
  return n
}
```

`%`（剰余）と`!==`（等しく**ない**）を使用し、丁寧に書かれているコードです。
再帰ではなく`while`を使用しているため、
- 何が条件か
- どんな処理をしているか

がわかりやすいのがいいですね。

再帰を使ったケースは[こちら](https://www.codewars.com/kata/reviews/570bb3f1c631137326000047/groups/5f9c6e4d3af42f0001573bb2)
</details>
:::

:::note
<details><summary>正規表現</summary>

https://www.codewars.com/kata/reviews/570bb3f1c631137326000047/groups/5711a541b25a4600a10006f2
```js
function noBoringZeros(n) {
  return +`${n}`.replace(/0*$/, "");
}
```

正規表現`/0*$/`（行末までの0の繰り返し）にマッチし、`""`（無）に`replace`していますね。無駄がない。

ここからは少しむずかしいのですが、
- 数値から文字列への変換にテンプレート記法`${}`を使用
- `+`を最初につけることで、最後に文字列から数値に再変換している

この書き方がスマートでかっこいいです。

難しい部分の話がわかりにくかった方は、[こちら](https://www.codewars.com/kata/reviews/570bb3f1c631137326000047/groups/570e493ede4dc8ac6700130c)の解答もオススメです。
</details>
:::

:::note
<details><summary>番外編：記号だけでプログラミング</summary>

長いので省略します
```js
[][(![]+[])[+!![]]+(!![]+[])[+[]]][([]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[+!![]+[+[]]]+([][[]]+[])[+!![]]+(![]+[])[!
![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+[][(![]+[])[+!![]]+(!![]+[])[+[]]])[!![]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+!![]]+(!![]+[])[+[]]]
)[+!![]+[+[]]]+(!![]+[])[+!![]]]((!![]+[
```
こんなことが延々と書いてあります。
これでもちゃんと動くんです。
こちらは[別記事](https://zenn.dev/haneru/scraps/157a3bed75963c)にまとめました。
</details>
:::

# おわりに
以上、CodeWarsオススメ問題でした。
VerticalDividerをRowに配置したらすべきこと.

# 対処できる配置
Rowで何かしらのアイテム間にVerticalDividerを配置しているパターン。

以下のような場合だと表示されない
```.dart
Row(
  children: const [
    Felxible(child: Text('Item 1')),
    VerticalDivider(),
    Flexible(child: Text('Item 1')),
  ],
)
```

正解はIntrinsicHeightで囲む。
何をしているかというと、このアイテムの高さを揃えるということをしている。
VerticalDividerの高さについての指定はないためこのような記法で他のアイテムと高さを揃えることを明示する必要がある。
```
IntrinsicHeight(
  child: Row(
    children: const [
      Felxible(child: Text('Item 1')),
      VerticalDivider(),
      Flexible(child: Text('Item 1')),
    ],
  ),
)
```

３０分ほど時間を費やしたので記事にしました。
解決済み: Pythonで[SSL: UNEXPECTED_EOF_WHILE_READING]なエラーになる

社内PCにAnacondaをインストールしてPython/JupyterNotebookでpipすると「SSL: UNEAXPECTED_EOF_WHILE_READING」なエラーになる

プロキシ経由でインターネットにアクセスするので.condarcファイルにプロキシを設定しており、urllib.request.getproxiesの出力でHTTPとHTTPSのプロキシサーバのURLが出力されるので、プロキシサーバのアドレス自体は認識してくれていると思う

いろいろ試して、pipコマンドの引数でプロキシサーバを指定する場合、httpだと成功するがhttpsだと同じエラーになる
あと、.condarcファイルで「ssl_verify:false」とした部分が無視されていそう

というわけで、SSLというか証明書らへんの問題だと思う

解決したら続きを書きます

# 解決
解決にはpip.iniの設定が必要だった
依存関係はよくわからないが.condacファイルだけでなくpip.iniも必要だった

* .condarcファイルにプロキシのアドレスを設定する
* pip.iniに証明書（cert）、プロキシ（proxy）、信頼済みホスト（trusted-host）を設定する
SAP Business Technology Platformの導入意義に対するワイの考え

# はじめに
こちらの記事を読んで私もいろいろ考えたので個人的な考えを書いていきます
前提として下記のブログを否定する意図はございません

https://qiita.com/Madao_Dayo/items/a3dc9cf0a7a14658c503

## 筆者のプロフィール
BTPの名前が変わる前のクラウドプラットフォームとかWEBIDE的なものから触ってます
SAPを中心としたクラウド関係のコンサルしたりしてます

## 引用ブログの主張
・本当に必要なんだっけ？
→SAPがS/4HANAになったことにより、クリーンコアで使う必要があり、そのために疎結合アーキテクチャーを持ち込むために使われている
その目的に対してライセンス費用も高いし、結合するためのアダプターなんてSAPみたいなメジャー製品は他の製品もある

## ブログの主張に対する考え
ほぼ同意です
「なんでBTP？」っていう話はよく言われます
ライセンス費用もほかソリューションから移ってきた人は0が1個多くね？って言われるくらい高いです
SAPどっぷりな人はこれに何も疑問を持たず「SAPが推奨しているから」「お客さんがSAPを望んでいるから」で数百万、数千万の費用が通ると思ってるコンサルタントは多いです
そんなわけ無いだろ！って思いながら聞いてますｗ

# 考えが違う点
揚げ足とりレベルですが違う点を書いていきます

## クリーンコアで使うためのBTP

下記の画像である通り、BTPでSide By Side拡張をしたからと言ってクリーコアになるわけではありません

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/e6212dbb-6c8c-7c63-cc81-10f724bd7773.png)

https://youtu.be/aKf40jtYbhk?t=503

また下記の画像の様にIn-App拡張でもクリーンコアで拡張する手段はありますのでBTPいらないけど拡張したいって人はその範囲で開発すればいいのかなって思います
ただここらへんのアーキテクチャーを理解したうえで実装まで出来るSAPコンサルっているの？問題は一定あるのかなと思います

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/04982de1-538b-52ad-e4b3-a3715833867b.png)

https://youtu.be/2TPkDWjNceA?t=869


## BTPの役割価値

SAP BTPの現在の主な役割ですが下記の様なところになっていて、ブログの筆者さんは主に3～5あたり、特に5番の話が多いのかなと思っています
「結局費用対効果合わないじゃん？」っていうのはありつつ、それだけじゃないよってところは認識してもらえればいいかなと思います

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/7ee4fe56-107a-1f9e-7e01-5be61a31de68.png)
https://youtu.be/2TPkDWjNceA?t=353

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/6f495401-de23-00b3-bacd-46112311cfc5.png)
https://youtu.be/2TPkDWjNceA?t=400

# 最後に
別のブログでも記載していますが、最近までBTP関連の開発ルールなどは少なくSAPの方がコミュニティブログで作ってくれるレベルのものしかありませんでした

ただ最近は下記のようにアーキテクチャー、開発、方法論などの観点でまとめられているので皆さんも見ていただければと思います

https://help.sap.com/docs/sap-btp-guidance-framework/guidance-framework/what-is-sap-btp-guidance-framework?q=SAP%20BTP%20Guidance%20FrameworkTP%20Guidance%20Framework
NFCを使ってみる

# はじめに
今回は、FeliCa Lite-Sの検出を行ってみたいと思います。

# 使用機器
FeliCa Lite-S RC-S966

# 手順
FeliCa Lite-Sの検出には、Pollingコマンドを使用します。
FeliCa Lite-S ユーザーズマニュアル
4.4.2 Pollingコマンド

FeliCa Lite-Sの検出手順をNXP社のアプリケーションノートのように書くと下記のようになります。
```
1:sendSPI(0x11, 0x09, 0x89);
2:sendSPI(0x16, 0x00);
3:sendSPI(0x00, 0x03, 0xFF, 0xFF, 0x0F, 0x00);
4:sendSPI(0x02, 0x00, 0xBF, 0xFF, 0xFF, 0xFF);
5:sendSPI(0x01, 0x00, 0x03, 0x00, 0x00, 0x00);
6:sendSPI(0x09, 0x00, 0x06. 0x00, 0xFF, 0xFF, 0x01, 0x00);
7:sendSPI(0x0A, 0x00);
8:sendSPI(0x14);
```
手順は下図のようになります。
※事前に、リセット解除、オペレーションモードに設定
![FeliCaLiteS.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148400/3f53c167-dc61-6a81-9f84-0a3094f2493b.png)

1\. ロードコンフィグレーション
　RFコンフィグレーションをロードする
　0x09 : FeliCa / NFC PI424
　0x89 : FeliCa / NFC PI424

　RFコンフィグレーションをロード（PN5180の仕様）
　0x11 0x09 0x89
 
2\. RFオン
　RFをオンする（PN5180の仕様）
　0x16 0x00

3\. ライトレジスタ
　IRQ_CLEARレジスタ（PN5180の仕様）
　0x00 0x03 0xFF 0xFF 0x0F 0x00

4\. AND MASK
　SYSTEM_CONFIGレジスタ（PN5180の仕様）
　0x02 0x00 0xBF 0xFF 0xFF 0xFF

5\. OR MASK
　SYSTEM_CONFIGレジスタ（PN5180の仕様）
　0x01 0x00 0x03 0x00 0x00 0x00

6\. SEND DATA
　Pollingコマンドでシステムコードを要求（FeliCa Lite-Sの仕様）
　0x09 0x00 0x06 0x00 0xFF 0xFF 0x01 0x00
　※システムコードはワイルドカード（0xFF 0xFF）とする
　※複数枚を検出することができなかったのでスロット数は１としました。

7\. READ DATAコマンド送信
　Pollingコマンドに対するレスポンスを読み出し（PN5180の仕様）
　0x0A 0x00

8\. データ取得
　Pollingコマンドに対するレスポンスデータ（FeliCa Lite-Sの仕様）
　0x14
　0x01
　0x01 0x2E 0x50 0xE7 0xDA 0xC7 0x8B 0x47
　0x00 0xF1 0x00 0x00 0x00 0x01 0x43 0x00
　0x88 0xB4

9\. SEND DATA
　Pollingコマンドで通信性能を要求（FeliCa Lite-Sの仕様）
　0x09 0x00 0x06 0x00 0x88 0xB4 0x02 0x00
　※手順6から手順8で取得したシステムコード（0x88 0xB4）を使用する

10\. READ DATAコマンド送信
　Pollingコマンドに対するレスポンスを読み出し（PN5180の仕様）
　0x0A 0x00

11\. データ取得
　Pollingコマンドに対するレスポンスデータ（FeliCa Lite-Sの仕様）
　0x14
　0x01
　0x01 0x2E 0x50 0xE7 0xDA 0xC7 0x8B 0x47
　0x00 0xF1 0x00 0x00 0x00 0x01 0x43 0x00
　0x00 0x83
　※通信速度自動検出対応

# 参考
[NXP社](https://www.nxp.jp/products/rfid-nfc/nfc-hf/nfc-readers/full-nfc-forum-compliant-frontend-ic:PN5180)
[FeliCa Lite-S](https://www.sony.co.jp/Products/felica/business/tech-support/)
[参考プログラム](https://github.com/ATrappmann/PN5180-Library/tree/master)

# 編集後記
FeliCa Lite-Sの検出ができたので、次は、データの読み書きを行ってみたいと思います。
【GAS】Spreadsheetで単語を画像として挿入する

# はじめに
[少し前の記事](https://qiita.com/Osane/items/c70b6d8d9022fc3c5279)で、Googleスライドの箇条書きを図形に変換するスクリプトを作成した。それと全く同じことを、Spreadsheetでも行いたい。
つまり、いくつか単語が並んでいる、こういうリストを...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197285/e33cadc9-20e5-08eb-95ed-72d3616787e7.png)

こういうふうに出力したい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197285/394b685f-8236-5f5b-ce55-a7a86ff660d0.png)

# どうやって行うか
まず、Google Apps Scriptでは、**Spreadsheetに図形を挿入出来ない**（記事執筆時点）。`insertImage`関数はあるものの、`insertShape`関数はSpreadsheet内に存在していない。よって、はじめにで書いたようなことを実現するには、少しひねったことが必要となってくる。

## アイデア1：データテーブルを利用する

https://qiita.com/YasumiYasumi/items/8e861565733e185d101e

上記の記事にあるように、データテーブルを用いれば、ドラッグ可能なオブジェクト（画像）として挿入できるのではないかと考えた。ところが、データテーブルを使う都合上、表題が存在せず、1つしかセルのないテーブルは作成できないことが発覚した。

https://developers.google.com/apps-script/reference/charts/data-table-builder?hl=ja

## アイデア2：スライドを利用する
Spreadsheetではだめだが、Googleスライドなら出来る。そして、Google Apps Scriptは、Googleに関係する複数のサービスを連携させることが出来る。ということで、Spreadsheetに書かれてあるリストを、テンプレートとなるGoogleスライドに転記し、画像としてダウンロードした上で、Spreadsheetに貼り付けることとした。

```js:code.gas
function list2img() {
  const slide_url="https://docs.google.com/presentation/d/AAAAAAAAAAAAAAAAAAAAAAAAA"; //テンプレート用スライドのURL
  const sheet=SpreadsheetApp.getActiveSheet();

  const rowData=sheet.getRange("A2:A"+sheet.getLastRow()).getValues();
  const pic_hight=4; let pic_row=1;
  for(const item of rowData){
    const presentation=SlidesApp.openByUrl(slide_url+"/edit");
    const shape=presentation.getSlides()[0].getShapes()[0];
    shape.getText().setText(item[0]);
    presentation.saveAndClose();

    const request_url=slide_url+"/export/png?&page=1";
    const res=UrlFetchApp.fetch(request_url);
    
    if (res.getResponseCode() === 200) {
      const img=sheet.insertImage(res.getBlob(), 4, pic_row).setHeight(80).setWidth(80);
      pic_row+=pic_hight;
    }
  }
  SpreadsheetApp.flush();
}
```

`sheet.getRange("A2:A"+sheet.getLastRow()).getValues()`では、SpreadsheetのA列にある単語（ただし1行目は除く）をすべて取得している。
`SlidesApp.openByUrl(slide_url+"/edit")`で、予め作っていたテンプレート用のGoogleスライドを開き、`shape.getText().setText(item[0])`で書き込みを、`presentation.saveAndClose()`で即時保存を行っている。
最後に、`UrlFetchApp.fetch(request_url)`で得られたpngファイルをblobに変換して、`sheet.insertImage`でSpreadsheetへ挿入している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197285/0696ba2e-ab04-b6aa-3b3f-396ca369eafb.png)

図形にスクリプトを割り当てる機能を用いて、最終的にはこのようになった。

# 既知の問題点
このスクリプトは、例えば以下のような既知の問題点がある。
- 決め打ちでテンプレート用スライドを埋め込んでいるので、複数人で同時実行しようとすると、大変なことになる
- テンプレート用スライドはGASのホストサーバーからFetchされるため、だれでも閲覧できる設定にしておかなければならない
- 挿入した画像の反映には、かなりのタイムラグがあり、例えば「シートを切り替える」「再読み込みする」等の画面の更新を掛けてあげる必要がある
- [少し前の記事](https://qiita.com/Osane/items/c70b6d8d9022fc3c5279)のように、線で繋いであげて思考ツールとして使うことはできない（矢印を編集するには、図形描画という別の画面に遷移する必要があるため）


# おわりに
わざわざSpreadsheetじゃなくて、おとなしくGoogleスライドを使うか、そういった用途に適した他のサービスを利用しよう。


以上。

　


# 参考文献

https://zenn.dev/kakieda/articles/f89fb065cc8719
Ubuntu　Nginx　Next.jsをデプロイ

アプリケーションを配置するディレクトリを/var/wwwの下に作成します。
```sudo mkdir -p /var/www/your-app```
Githubからなら
```sudo git clone https://github.com/your-username/your-repo.git /var/www/your-app```

アプリケーションのディレクトリに適切な権限を設定します。
```sudo chown -R www-data:www-data /var/www/your-app```  
```sudo chmod -R 755 /var/www/your-app```

ディレクトリに移動し、依存関係をインストール
```cd /var/www/your-app```
```npm install```
```npm run build```

Next.jsアプリを起動します。通常はpm2などのプロセスマネージャーを使用してデーモン化します。
pm2をインストールしていない場合
```npm install -g pm2```
してるなら
```pm2 start npm --name "nextjs-app(名前はなんでもOk)" -- run start```

新しいNginxの設定ファイルを作成します。
```sudo nano /etc/nginx/sites-available/your-app```

```
server {
    listen 80;
    server_name your-domain.com; # あなたのドメインに置き換えてください。

    location / {
        proxy_pass http://localhost:3000; # Next.jsアプリが動作するポート
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}
````

サイトの設定を有効化し、Nginxの設定をテストします。
```sudo ln -s /etc/nginx/sites-available/your-app /etc/nginx/sites-enabled/```
```sudo nginx -t```

設定が正しければ、Nginxを再起動します。
```sudo systemctl restart nginx```

Nginxで使用するポートをファイアウォールで許可します。
```sudo ufw allow 'Nginx Full'```

DONE!

### 何か変更したら
## 共通
```
cd /var/www/app-name
git pull origin main
git add .
git commit -m "message"
git pull origin main
```
## UbuntuマシンそのままVer
```
pm2 list
pm2 stop <id>
npm run build
pm2 start npm --name "app-name" -- run start
```
## マシン再起動
再起動コマンド
```sudo reboot```
```
//ufw有効化
sudo ufw enable

//Nginx Fullが解放されているか確認
sudo ufw status

//アプリディクトリに移動
cd /var/www/app_name

//セットアップ
npm run build
pm2 start npm --name "app-name" -- run start
```

DONE!
実務経験ゼロで1週間でSnowPro Core合格した話

こんにちは、少しだけお久しぶりです！今回はタイトル詐欺じゃないです。ただ、前回は「実務経験が大事！」と言っていたのに、思いっきり矛盾している自分でも笑っちゃいます。

## 資格を取った理由

少しだけ理由を聞いてください。私は業務でSnowflakeを触る予定もないのですし今までもなかったんのですが、会社がSnowflake案件に力を入れ、資格報奨金がなんと**3ヶ月間だけ倍増**ということをしり、しかも期限間近だったので一気に詰め込みで受験しました。いわば、つまり、そう賞金稼ぎです。

全体を通して感じたことはDatabricksの資格とは違い、Snowflakeは情報が豊富に揃っており、しっかり問題集をやり込めば合格が狙えます。日本語化対応したのも結構早かったみたいですしね。

## SnowPro Coreの概要

この記事にたどり着いた方は当然ご存知かもしれませんがSnowPro CoreはSnowflakeの公式認定資格で、Snowflakeの基本的な使い方や機能についての知識を問われます。詳細は公式サイトをご覧ください。

https://www.snowflake.com/ja/resources/learn/certifications/


## 参考にしたネット情報

1. **Snowflakeコミュニティ** - Slackの#certificationsチャンネル  

https://app.slack.com/client/T01AYMN7FMW/C03BTTBV8KC

→こちらで絶賛されていた後述問題集を採用。


2. **X(旧Twitter)** - 合格者の体験談

改めていま検索すると結構評判良いみたいです

https://x.com/synup16g/status/1827625189766791187

https://x.com/sao_08/status/1827930588042670471


## 使用した問題集

ということで、今回使用した教材は以下のみです。

https://note.com/data_ku/m/mb14f6943819e


たしかに解説がしっかりしているので、ただ暗記するだけではなくちゃんとやれば知識も身に付くかもしれません。

## 学習方法

1週間で合格するために、以下のように学習しました：

1. **問題集の反復**  
   - **1日目**: 問題集を一気に通読して全体像を把握。（考え込むの禁止！時間と自信を失うだけだから）
   - **2日目**: もう一度いっきに通読
   - **3日目**: 半分(250門)を解く（考え込まない、わからなかったらすぐ答え見る）
   - **4日目**: もう半分を同じように解く
   - **5日目**: 3,4日目で間違った部分だけを解く（この日がしんどかった。日曜まるまるつぶれた）
   - **6日目**: 5日目に間違った部分を解く
   - **7日目**: 全体通読と、間違った部分を解く。翌日試験。

2. **公式ドキュメントの活用**  
   問題集の解答で「なぜ？」とおもった部分のみリンクにとんで公式ドキュメントで確認しました。あまり深く考えずにサクサク進めました。

## 試験当日

特筆することはありません。なれた自宅からの受験部屋をぐるりをカメラ撮影したり両手になにもないアピールなどスムーズに、とくにつっこまれず試験スタート＆ゴールしました。試験担当によるかな？

## 試験結果

合格ライン(750点)にわりとぎりぎり？な800点台前半で無事合格。ほっとしました

## まとめ

今回、完全に「賞金稼ぎ」だったので参考になるかはご判断ください。同じようにプレッシャーがかかっていたり短期間で資格取得が求められている方にはオススメです。ただし、業務での活用を目指す方は、実務経験を積むことも忘れずに（まだゆってる）。