OmniAICreator/Qiita-1.07M huggingface dataset:
【RHEL】アクセスキーの登録なしでAWS CLIを利用する

## 実現したいこと
・最新版のAWS CLIを導入する
・アクセスキーID/シークレットアクセスキーを使用してAWSリソースの操作を行うのはセキュリティ観点において非推奨です。
⇒アクセスキーID/シークレットアクセスキーの発行/登録は行わずに、<font color="Red">必要な操作権限(IAMポリシー)をアタッチしたIAMロール</font>を利用してAWS CLIを利用を制御します。

## 実施環境
サーバ：Amazon EC2
OS：RHEL-8.9.0_HVM-20240213-x86_64-3-Hourly2-GP3
追加ソフト：Python3.6.8
IAMロール：以下2つのポリシーをアタッチ
* AmazonEC2FullAccess ：EC2操作のため
* AmazonSSMManagedInstanceCore ：SSM接続のため

## 導入手順
RHELの場合、AWS CLIはデフォルトでインストールされていないため、以下の手順で導入します。本手順はrootユーザで実行する想定とします。
※「pip install awscli」でもインストール可能ですが、バージョン1がインストールされます

### 1.AWS CLIのインストーラファイルをダウンロード
以下コマンドでダウンロード。
```
[root@ip-XX-XX-XX-XX ~]#curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
```
インターネットに出られない環境においては、以下URLからダウンロードしサーバ内に持ち込んでください。
https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip

### 2.インストーラの解凍
インストーラを解凍します。Linux ディストリビューションに組み込み unzip コマンドがない場合は、同等のコマンドを使用して解凍。あるいはunzipをインストールします。
```
[root@ip-XX-XX-XX-XX ~]#unzip awscliv2.zip

# unzipが導入されいない場合
[root@ip-XX-XX-XX-XX ~]#dnf install unzip
```

### 3.インストールプログラムの実行
インストールコマンドは、新しく解凍された install ディレクトリにある aws という名前のファイルを使用します。
```
[root@ip-XX-XX-XX-XX ~]# ./aws/install
You can now run: /usr/local/bin/aws --version
```
バージョンを確認します。
```
[root@ip-XX-XX-XX-XX ~]#aws --version
aws-cli/2.15.38 Python/3.11.8 Linux/4.18.0-513.18.1.el8_9.x86_64 exe/x86_64.rhel.8 prompt/off
```
### 4.awscliコマンドの動作確認
awscliコマンドの動作確認を行います。
<font color="Red">IAMロールのポリシーで設定している権限の操作ができることと、権限がない操作に関しては実施できないことを確認します。</font>
※「aws configure」を使用したアクセスキーID/シークレットアクセスキーの登録は不要です。
```
# インスタンスIDを参照して、EC2インスタンスの情報を取得するコマンド
[root@ip-10-0-10-29 ~]# $ aws ec2 describe-instances --instance-ids ${instance-id}
{
    "Reservations": [
        {
            "Groups": [],
            "Instances": [
                {
                    "AmiLaunchIndex": 0,
                    "ImageId": "ami-XXXXXXXXXXXXXXX",
                    "InstanceId": "i-XXXXXXXXXXXXXXXX",
                    "InstanceType": "t2.micro",
                    "KeyName": "sample-key",
                    "LaunchTime": "2024-04-16T13:07:36+00:00",
                    "Monitoring": {
                        "State": "disabled"
                    ---------------------------------------(省略)

# s3バケットの一覧を表示するコマンド
[root@ip-XX-XX-XX-XX ~]# aws s3 ls
An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied
```

以上

### ※参考
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html
Monobehaviorを継承したインターフェースを[SerializeField]で渡す

SerializeReference属性を利用すれば抽象型やインタフェース型のフィールドをシリアライズできます。
しかし、Monobehaviorを継承していない場合に限るので少々使い勝手が悪いです。
そこで、Monobehaviorを継承したクラスのインターフェースを[SerializeField]で渡すための仲介クラスを作っていきます
## InterfaceMediater クラス
```C#:C#
public class InterfaceMediater<TInterface>
{
    [SerializeField] GameObject _objectI;
    TInterface _interface;
    public TInterface Interface()
    {
        if (_objectI)
        {
            _objectI.TryGetComponent<TInterface>(out _interface);
        }
        return _interface;
    }
}
```
Unity2020.1からGenericな型がシリアライズ可能になっていますので、Monobehaviorを継承しないこのクラスを作成し、受け取り側でInterfaceMediater型の変数を宣言し使います。
## 使い方
Itestインターフェースには”取得完了”とだけ表示するTest()関数が定義されています
```C#:C#
public class CodeReadTestScript : MonoBehaviour
{
    [SerializeField] InterfaceMediater<ITest> _tsetInterface;
    private void Start()
    {
        var testI = _tsetInterface.Interface();
        testI.Test();
    }
}
```
[SerializeField]属性を付けてInterfaceMediater型の変数をインターフェース名を指定しながら宣言します
その変数からアクセスできるInterface()関数は指定したインターフェースのみを返します。
![スクリーンショット (1322).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3771639/98459dfb-2ea3-4838-13cd-e55ef0976667.png)
インスペクターにはこのように表示されており、このObject I に取得したいインターフェースを持ったオブジェクトをアタッチすることでInterface()関数を通してインターフェースのみを取得できます。
![スクリーンショット (1323).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3771639/ed62acf0-f6ac-d26c-b25b-cd69e51388d5.png)

## 実行結果
![スクリーンショット (1324).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3771639/c260ddc9-6d4d-643d-dbc8-05ab61d793ab.png)

このように取得したインターフェースを経由して関数を実行することが出来ます。

## 終わりに
インターフェースを利用し依存性の逆転を行うことで疎結合を実現できます。
今回は、せっかく実現したその疎結合を[SerializeField]でGameObjectをアタッチするなどして台無しにしないように、Monobehaviorを継承したクラスのインターフェースのみを[SerializeField]で受け渡す方法を記事にしました。
@IB接続でNAMEを書き直す方法

## はじめに
私は最近プログラミングスクールにて学習をスタートした初学者で、学習していく中で疑問に思ったことや苦労したことなどについて記事を書いております。

## ＠IB接続でnameを間違えて記述した

画像の通り＠IBAction接続でボタンを紐づけました。

ですが、赤線のところをよく見てみると、ボタンのつずりを間違えて記述してしまいました。

![スクリーンショット 2024-04-16 21.46.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715605/d28a23d6-5796-45f4-5067-a05860213c78.png)


この場合、赤線のところでただ単に書き直すのはNGです。

## 書き直し方

赤線のところを右クリック

![スクリーンショット 2024-04-16 21.46.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715605/3276e17f-91a2-99cd-68e8-747c18a7ab17.png)

Refactor→Renameの順でクリック

![スクリーンショット 2024-04-16 22.05.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715605/9d61ddce-c046-7504-94f6-96471cb14987.png)

緑の枠のところで修正または、書き直す。
(storyboard上のButtonのNAMEも変わっている)

![スクリーンショット 2024-04-16 22.12.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715605/dd602535-30fc-8803-1266-345804bf60bb.png)

このようにしないと、片方だけ修正されるようになるのでエラーが出てしまいます。

## おわりに

＠IB接続でViewとControllerが繋がっているので、片方だけ修正しても、もう片方は修正されないのです。
そしてエラーにつながります。
viewWillAppearについて

## 概要
viewWillAppearについて

## viewWillAppear
・viewが表示される直前に呼ばれる。
・表示されるたび毎回呼ばれる

## viewWillAppearの使い所
A画面にviewWillAppearが記載されていると仮定する。

<今回の画面遷移の例>A→B→A
viewWillAppearが呼ばれるタイミングは以下の2つである。
①A画面が最初に表示されるタイミング
②B画面からA画面に戻って、A画面が表示されるタイミング
＊A画面にviewDidLoadを記載した場合、上記の①でしか呼ばれない。(viewDidLoadはコンテンツビューが最初に作成されたときに1回だけしか呼びだされないため)

A画面でAPIなどを使ってデータを表示させる場合は、viewWillAppearに記載するとよさそう
Nuxt3 で認証機能を実装する

### 環境
- nuxt 3.11
- @sidebase/nuxt-auth 0.7.0

### はじめに
Nuxt3 で認証機能を実装するには幾つか選択肢がありますが、その中で`Sidebase Nuxt Auth`を実装しました。選択した際の経緯と実装方法の紹介です。

### Auth Module
Nuxt2にはnuxt/authという公式の認証機能があったようですがNuxt3には対応しておらず、代わりに以下の方法が紹介されています。

- [Sidebase Nuxt Auth](https://github.com/sidebase/nuxt-auth) based on next-auth
- [AuthJs Nuxt](https://github.com/Hebilicious/authjs-nuxt) based on Auth.js
- Implement your own auth using [Lucia](https://lucia-auth.com/guidebook/sign-in-with-username-and-password/nuxt/) or [Nuxt Auth Template](https://github.com/nuxt/examples/tree/main/auth/local)

独自認証は最後の手段として、`Authjs Nuxt`はあまり更新されていませんでした。
`Sidebase Nuxt Auth`は人気で更新頻度も高かったため今回利用することに決めました。

### インストール
[公式ページ](https://sidebase.io/nuxt-auth/getting-started/installation)に従ってインストールします。

```
npx nuxi@latest module add sidebase-auth
```

### 実装
[公式ページ](https://sidebase.io/nuxt-auth/getting-started/quick-start)にQuickStartがあるためこれに従って実装していきます。

`nuxt.config.ts`にProviderタイプを設定します。今回は`authjs`を設定しますが、バックエンドAPIを用意する場合は`local`や`refresh`が利用できます。

``` typescript
export default defineNuxtConfig({
    modules: ['@sidebase/nuxt-auth'],
    auth: {
        provider: {
            type: 'authjs'
        }
    }
})
```


次に認証関連のリクエストを処理するための認証ハンドラーを作成します。`server/api/auth/[...].ts`ファイルを作成します。

``` typescript
import { NuxtAuthHandler } from '#auth'
import GithubProvider from 'next-auth/providers/github'

export default NuxtAuthHandler({
    pages: {
        signIn: "/login", // ログインページ
	},
    providers: [
        // @ts-expect-error You need to use .default here for it to work during SSR. May be fixed via Vite at some point
        GithubProvider.default({
           clientId: process.env.GITHUB_CLIENT_ID,
           clientSecret: process.env.GITHUB_CLIENT_SECRET
        })
    ]
})
```

`authjs`で使用できる認証プロバイダは [NextAuth.js](https://next-auth.js.org/providers/) で確認できます。

### ログインページ

signInで指定したログインページでログインできるようにします。

``` vue
<template>
    <h1>ログイン</h1>
    <button @click="signIn('github')" type="submit">Githubでログイン</button>
    <p>Status: {{ status }}</p>
</template>

<script lang="ts" setup>
    const { status, data, signIn } = useAuth();
</script>
```

`sighnIn`を呼ぶと認証ページに飛びます。`status`で認証状態を確認できます。

### アクセス制限
`nuxt.config.ts`で`globalAppMiddleware:true`を設定することで全体に認証制限を設定できます。これで認証前にアクセスするとログインページへリダイレクトされるようになります。
ですが、これだけだとすべてのページで制限されるため、ログインページでも延々とリダイレクトします。
ログインページを`auth: false`で認証不要にするか、`unauthenticatedOnly: true`で認証前のみアクセスできるようにします。

``` typescript
export default defineNuxtConfig({
    modules: ['@sidebase/nuxt-auth'],
    auth: {
        globalAppMiddleware: true,
        provider: {
            type: 'authjs'
        }
    }
})
```


``` vue
<script setup lang="ts">
definePageMeta({
  auth: {
    unauthenticatedOnly: true,
    navigateAuthenticatedTo: "/home", // 認証済みのリダイレクト先
  },
});
</script>
```

これでログイン後home画面に遷移するのが確認できるかと思います。
Github actionsのyaml記法

# 経緯
github actionsにて、自動デプロイの設定を行おうとしたところ、yamlの記法エラーを何度か経験しました。
なので、どういう形式でgithub actionsの設定を書けばいいのかまとめていこうと思います。

# yamlファイルの理解
github actionsのサンプルファイルは[こちら](https://docs.github.com/ja/actions/learn-github-actions/understanding-github-actions)です。

```yaml
name: learn-github-actions

run-name: ${{ github.actor }} is learning GitHub Actions

on: [push]

jobs:

  check-bats-version:

    runs-on: ubuntu-latest

    steps:

      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - run: npm install -g bats

      - run: bats -v
```

githubのサイトでは左にコード、右に解説があり非常にわかりやすいのですが、Qiitaでそれができるかわかっていないため、一行ずつ解説する形にします。

```yaml
name: learn-github-actions
```
ワークフロー名。リポジトリのActionsタブで表示される名前です。
これがなかった場合、github actionsのyamlファイル名が表示されます。

```yaml
run-name: ${{ github.actor }} is learning GitHub Actions
```
ワークフロー実行の名前です。リポジトリのAcitonsタブにあるワークフロー実行の一覧に表示されます。
もしこれが省略された場合、例えばpushやプルリクイベントをトリガーするワークフローでは、コミットメッージやプルリクのタイトルが設定されます。

`${{ github.actor }}`はワークフロー内で使用される変数で、ワークフロー実行のトリガーとなったアクターのユーザー名を表示しています。

```yaml
on: [push]
```
ここが結構大切で、ワークフローのトリガーを指します。この例では、pushしたりマージしたりするたびにワークフローが実行されます。上記はすべてのブランチが対象となっています。

ちなみにトリガーにできるイベントは結構あります。

https://docs.github.com/ja/actions/using-workflows/events-that-trigger-workflows#available-events

```yaml
jobs:

  check-bats-version:
```
`check-bats-version`という名前のジョブを定義し、`jobs`はこのワークフローで実行されるすべてのジョブをグループ化します。

```yaml
runs-on: ubuntu-latest
```
ジョブを実行する仮想環境です。linuxが主流ですが、windowsやmacも選べます。

ただし、macはgithub actionsで同時実行できるジョブが他のOSより少ないです。

詳しくは以下の記事へ記載しています。

https://qiita.com/ponponnsan/items/0a03b1a9a7bd6dda4040


```yaml
 steps:
```
`check-bats-version`で実行されるすべてのステップをグループ化します。
これ以下の階層は、個別のアクションやシェルスクリプトです。

```yaml
 - uses: actions/checkout@v4
```
上記はよく見る一行ですね。これは、[actions/checkout](https://github.com/actions/checkout)のv4を実行しています。

何をしているかを公式のreadmeからとってきます。
>このアクションは$GITHUB_WORKSPACE配下のリポジトリをチェックアウトし、ワークフローがリポジトリにアクセスできるようにします。
>
>デフォルトでは、ワークフローをトリガーした ref/SHA の単一のコミットのみがフェッチされます。fetch-depth: 0に設定すると、すべてのブランチとタグのすべての履歴がフェッチされます。イベントごとに $GITHUB_SHA が指すコミットについては、こちらを参照してください。
>
>認証トークンはローカルの git config に保存されます。これにより、スクリプトで認証済みの git コマンドを実行できるようになります。トークンはジョブ終了後のクリーンアップ時に削除されます。オプトアウトするには persist-credentials: false を設定します。

つまりこういうことですかね
- `$GITHUB_WORKSPACE`配下でリポジトリのアクセス許可
- デフォルトで単一のコミットのみがダウンロード(フェッチ)される
- 認証トークンはローカルの `git config` に保存され、ジョブ後に削除される

```yaml
- uses: actions/setup-node@v4
    with:
      node-version: '20'
```
このステップでは、`actions/setup-node@v4`アクションを使用して、指定したバージョンのNode.jsをインストールします。これにより、nodeとnpmコマンドの両方がPATHに置かれます。

```yaml
    - run: npm install -g bats

    - run: bats -v
```
runは、ランナー上でコマンドを実行するようにジョブに指示します。

ちなみに複数行まとめて書くには以下のようにします。

```yaml
    - run: |
        npm install -g bats
        bats -v
```

# 最後に
結構サラッと書くつもりだったんですが、公式サイトを真剣に読み込んでしまい手が止まりました...
雰囲気で書いていたので、改めて知れてよかったです！！

# 参考文献
https://docs.github.com/ja/actions/learn-github-actions/understanding-github-actions
PL-300(Microsoft Power BI Data Analyst)合格記

先日PL-300(Microsoft Power BI Data Analyst)を受験し一発合格したため、勉強方法と注意点をまとめます。


## 試験範囲
試験範囲は以下の通りです。
なお、この情報は2024年4月23日時点のものですので、最新情報は[学習ガイド](https://learn.microsoft.com/ja-jp/credentials/certifications/resources/study-guides/pl-300)を確認してください。

**スキルの概要**
* データの準備 (25 - 30%)
* データのモデル化 (25 - 30%)
* データの視覚化と分析 (25 - 30%)
* 項目のデプロイと保守 (15 - 20%)

## 私のバックグラウンド
* AWS歴8年ほどで、AWSの資格は12冠達成済み
* データ分析基盤の設計・構築の実務経験あり
* データ可視化の経験は数ヶ月
* Power BIの経験は3ヶ月ほど

Power BI Desktopで構築作業をしたことはありますが、Power BIサービスはほぼ触ったことがないまま試験に臨みました。

## 勉強方法
### Microsoft Learn
学習ガイドの学習リソースの一覧に[ラーニングパス](https://learn.microsoft.com/ja-jp/training/courses/pl-300t00#course-syllabus)のリンクがあるので、関連するドキュメントを全て読み、一度で理解できなかった部分、実務経験のない部分は何度も読み返しました。
ラーニングパスの中にはPower BIを操作できるラボが含まれていましたが、時間の関係上ラボは実施しませんでした。

### 無料の練習問題
学習ガイドに[無料の練習問題](https://learn.microsoft.com/ja-jp/credentials/certifications/power-bi-data-analyst-associate/practice/assessment?assessment-type=practice&assessmentId=48&practice-assessment-type=certification)のリンクがあります。満点をとれるようになるまで繰り返し解きました。

### 試験問題集
[こちら](https://www.jpntest.com/shiken/PL-300J-mondaishu)の試験問題集を繰り返し解きました。
この問題集にはいろんな問題形式が含まれており、問題数も多くて実践的なものの、明らかに回答が間違っているのでは…？というようなものがあったり、解説がない問題が多いのがネックでした。
そのため、一問ごとに自分で考え方を調べたりChatGPTに質問したりして結果的に周辺知識を得ることができたので、やってよかったと思います。

## 注意点
AWSの試験とは異なる点があり戸惑うことがあったので、メモしておきます。
### AWS試験のようなラジオボタン or チェックボックス式の問題ばかりではない
回答方法が複数種類あるので、事前にどのような回答方法があるか知っておいた方が安心です。
回答の練習ができる[試験サンドボックス](https://www.starttest.com/ITDVersions/22.0.0.0/ITDStart.aspx?SVC=d307e683-bc34-4b76-918f-7e857d66087a)があるので、Microsoftの試験がはじめての方は操作性を確認しておくとよいと思います。

### 時間配分大事
セクション単位でなら見直しできるが、次のセクションに進んだら前のセクションには戻れないという制限があったため、最初のセクションに時間を使いすぎて最後のセクションはじっくり問題を読む時間がありませんでした。
時間配分は最初に考えておくべきでした。

### 試験中にMicrosoft Learnを参照できる
試験中にMicrosoft Learnで情報を検索することができました。
これってこうやるんだっけ、みたいな確認ができたので助かりました。

## 最後に
PL-300は、PowerBIを使い始めたばかりの私にとって勉強し甲斐があり実務でも役に立つ試験でした。
実務で触ったことがない機能に関しても、Learnをよく読んで画面を少し触るだけでも理解が深まりました。
PL-300は実務経験が浅くてもラーニングパスの内容をよく理解すれば合格できる試験だと思いますので、この記事がこれから受験する方のお役に立てば幸いです。
ITIL4受けてきた時の話

# はじめに
ITIL4に合格したので合格までの道のりと今後目指すマネジメント系資格について残しておきます。

## ITIL4をなぜ取ろうと思ったか？
まず、ITIL4をとるきっかけとしてマネジメント系を勉強し、自分でプロジェクトを持ちたい、任されたいという思いからでした。そのためにもマネジメント系をするならなにが必要か調べてみて、ITIL4を取ってみようと考えました。

## ITIL4合格まで
ITIL4ファンデーション試験対策(下にリンクはっています)という試験対策で勉強していました。ネット上での平均勉強時間は20~40時間程とあり僕は約48時間程度勉強しました。

## 上位のマネジメント資格

ITストラテジスト

経営者の視点で戦略立案やプロジェクトの実行を主導する。経営戦略に基づいてIT戦略を策定し、ITを高度に活用した事業革新、業務改革、及び競争優位を獲得する製品・サービスの創出を企画・推進します。

ITサービスマネージャー

システムの導入や維持・拡張のほか、システムの管理方法、情報セキュリティ対策、障害を最小限に抑えるための対処法、ITサービス改善に向けての立案する。システム運用管理に関する幅広い知識と専門性が問われます。

プロジェクトマネージャー
システム開発のプロジェクト責任者として予算や納期、品質などの管理を行います。
プロジェクトの責任者として現場を統括し、計画、実行、管理する。
計画、実行、管理など、プロジェクトマネジメント全般に関する知識と技能を問われます。

PMP資格試験
PMP(Project Management Professional)は、PMI(Project Management Institute)が認定する世界的規模のプロジェクト・マネジャー資格です。プロジェクト管理の専門家であることを認定する、国際的に評価されている資格です。

### それぞれの資格の違い

* ITサービスマネージャー資格とプロジェクトマネージャー資格との違い

ITサービスマネージャー資格はシステム運用に関するマネジメントの知識を問う試験に対してプロジェクトマネージャー資格はシステム開発におけるプロジェクトマネジメントの知識を問われます。

* ITストラテジスト資格とプロジェクトマネージャー資格の違い

ITストラテジスト資格は企業の経営戦略に基づいて、情報システム戦略を策定・提案・推進できる能力を評価するに対してプロジェクトマネージャー資格はITシステム開発プロジェクトの責任者として必要な知識と技能を評価する目的があります。




|                              | 分類     | 開催時期                                                                                     | 
| ---------------------------- | -------- | -------------------------------------------------------------------------------------------- | 
| ITストラテジスト試験         | 国家資格 | 年1回　4月                                                                                   | 
| ITサービスマネージャー試験   | 国家資格 | 年1回　4月                                                                                   | 
| プロジェクトマネージャー試験 | 国家資格 | 年1回　10月                                                                                  | 
| PMP資格試験                  | 民間資格 | テストセンター受験(PBT)　年間を通して受験可能<br>オンライン受験(CBT)　2024年1月25日～3月11日 | 

### 備考
[ITIL4 ファンデーション試験対策](https://www.amazon.co.jp/dp/429620033X/ref=nosim?tag=nkbookplus-22)
【Ubuntu ネットワークTips】デフォルトゲートウェイのMetric値がおかしくなった場合の回避方法

# はじめに
　Ubuntu 20.04で、NetworkManagerを利用している場合、インターネット接続できないと、デフォルトゲートウェイのMetricに20000加算されてしまう仕様の回避方法を紹介する。

## NetworkManagerの仕様

　下記の「connectivity section」に記載があるように、インターネット接続できないと、「各デバイスのデフォルトルートのMetricに+20000のペナルティが加算される」と記載がある。これは、複数NICを使用している際などには有効な設定となるが、インターネット接続できない可能性がある環境では不都合が生じる可能性がある。

 >  The other use is that default-route of devices without global connectivity get a penalty of +20000 to the route-metric. This has the purpose to give a better default-route to devices that have global connectivity. For example, when being connected to WWAN and to a Wi-Fi network which is behind a captive portal, WWAN still gets preferred until login.

https://developer-old.gnome.org/NetworkManager/stable/NetworkManager.conf.html

https://github.com/NetworkManager/NetworkManager/commit/6b7e9f9b225e81d365fd95901a88a7bc59c1eb39

# 動作確認環境
* Ubuntu 20.04
  * Jetson JetPack 5.1 

# 方法

　NetworkManagerの設定である「Connectivity Check(接続性の確認)」を無効化する（デフォルトでは有効となっている）。

## GUIの場合

　UbuntuのGUIメニューから、「設定」⇒「プライバシー」⇒「接続性の確認」で、OFFに設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/d1cf487e-cd10-0c4d-7557-d105a930e478.png)

## CUIの場合

　設定ファイル(NetworkManager-intern.conf)をviなどで修正する。

```bash
sudo vi /var/lib/NetworkManager/NetworkManager-intern.conf
```

下記を追記する。

```bash
[connectivity]
.set.enabled=false
```
NetworkManagerを再起動すると、設定が反映される。

```bash
sudo systemctl restart network-manager.service
```

### 自動化したい場合

　iniファイル設定ツールである[crudini](https://www.pixelbeat.org/programs/crudini/)を使って自動化する。

crudiniのインストール。
```bash
sudo apt update
sudo apt install crudini
```

Connectivity Checkの無効化設定と反映。
```bash
sudo crudini --set /var/lib/NetworkManager/NetworkManager-intern.conf "connectivity" ".set.enabled" "false"
sudo systemctl restart network-manager.service
```


# 参考

https://developer-old.gnome.org/NetworkManager/stable/NetworkManager.conf.html

https://unix.stackexchange.com/questions/444538/metric-on-connections-and-magic-20000-value-added

https://qiita.com/Ihmon/items/e5bf26f1d38eaac0628b

https://askubuntu.com/questions/1029108/how-do-i-programmatically-disable-connectivity-checking
Kaggle　～タイタニック沈没事故の生存予測～　決定木#3

こんにちは!:confused:
先日に続いて決定木のデータ解析をやっていきます!
前回の投稿では前処理で標準化したことでスコアが0.76になりました。
今回は変数を少しいじってみます!
# プログラムの内容 
```rb:
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import missingno as msno
from sklearn.tree import DecisionTreeClassifier
from sklearn.preprocessing import StandardScaler

train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')

train["Age"] = train["Age"].fillna(train["Age"].median())
train.replace({"male":0,"female":1},inplace=True)
train = pd.concat([train, pd.get_dummies(train["Embarked"], prefix="Embarked")], axis=1).drop(columns=["Embarked"])
train["FamCnt"] = train["SibSp"] + train["Parch"]
train = train.drop(columns=["Name", "Ticket", "Cabin", "SibSp", "Parch"])
columns_to_standardize = ['Age', 'FamCnt', 'Fare']
scaler = StandardScaler()
train[columns_to_standardize] = scaler.fit_transform(train[columns_to_standardize])
```
SibSPとParchを足してFamCntという列を作成しました。

# 外れ値を除去
```rb:
train = train[(train['Age'] > -3) & (train['Age'] < 3)]
train = train[(train['FamCnt'] > -3) & (train['FamCnt'] < 3)]
train = train[(train['Fare'] > -3) & (train['Fare'] < 3)]
```

# testデータの前処理
```rb:
test['Age'] = test['Age'].fillna(test['Age'].median())
test['Fare'] = test['Fare'].fillna(test['Fare'].median())
test.replace({"male":0,"female":1},inplace=True)
test = pd.concat([test, pd.get_dummies(test["Embarked"], prefix="Embarked")], axis=1).drop(columns=["Embarked"])
test["FamCnt"] = test["SibSp"] + test["Parch"]
test = test.drop(columns=["Name", "Ticket", "Cabin", "SibSp", "Parch"])
```

# 予測モデルの作成と予測の実施
```rb:
train_features = train[['Pclass', 'Sex', 'Age', 'Fare', 'FamCnt', 'Embarked_C', 'Embarked_Q', 'Embarked_S']].values
train_target = train['Survived'].values
model = DecisionTreeClassifier(max_depth = 5, class_weight = 'balanced', random_state=0)
model.fit(train_features, train_target)
test_features = test[['Pclass', 'Sex', 'Age', 'Fare', 'FamCnt', 'Embarked_C', 'Embarked_Q', 'Embarked_S']].values
predict_test_target = model.predict(test_features)
```

# csvファイルの作成
```rb:
submission = pd.DataFrame({'PassengerId': test['PassengerId'], 'Survived': predict_test_target})
submission.to_csv('submission_Titanic_DecisionTreeClassifier.csv', index = False )
```

# スコアの結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3678927/33d071b9-e3da-d341-c408-52e8eef5767e.png)

悲惨な結果となりました・・・
同乗している家族を学習にかけたことで予測結果に悪影響を及ぼした可能性が考えられます。
また改めて考え直してから投稿したいと思います。
ありがとうございました!
PowerCMS会員専用ページ

PowerCMSの会員専用ページで　mt-member.cgi を別のフォルダにアクセスさせる。
例：/cgi-bin/ 配下に置く

* PowerCMS 6.1
* Members 1.98

# mt-config.cgi の修正
```mt-config.cgi
MemberScript members.cgi
MemberCGIPath /cgi-bin/
```

# PDFもアクセス制限かける
```DynamicMTML .htaccess
<FilesMatch (^(|[^.]+)|\.[Pp][Dd][Ff]?)$>
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteRule ^ <$mt:BlogRelativeURL$><$mt:DynamicSiteBootstrapper$> [L]
</IfModule>
<IfModule !mod_rewrite.c>
  <IfVersion >= 2.3>
    Require all denied
  </IfVersion>
  <IfVersion < 2.3>
    Order Allow,Deny
    Deny from all
  </IfVersion>
  ErrorDocument 403 <$mt:BlogRelativeURL$><$mt:DynamicSiteBootstrapper$>
</IfModule>
</FilesMatch>
```

# .mtview.php のリダイレクト先の設定
mt-members.cgiを読み込むようになっている設定をコメントアウト

```/path/to/mt/plugins/Members/php/config.php
        #'config_settings' => array(
        #    'MemberScript' => array( 'default' => 'mt-members.cgi' ), # DEPRECATED
        #    'MembersScript' => array( 'default' => 'mt-members.cgi' ),
        #),
```
CGIPathを読んでいるので mt-config.cgi で設定した MemberCGIPath を読むように修正
```/path/to/mt/plugins/Members/php/config.php
                    //$login_url = $app->config( 'CGIPath' );
                    $login_url = $app->config('MemberCGIPath');
```
しおあつめプロジェクト　#00　キックオフ

知り合いが発言した。
「塩くん（推し）」をめでるだけのゲームが作れないか。

それにたいして私ともう一人友人Kが立ち上がり、
ポートフォリオもかねてアプリケーションを開発しようということになった。

参加メンバー
私（開発、BGM、SE作成）
K（開発）
S（発案及びイラスト）

目標
2025年中のリリース

言語
Unity　C#

開発目的
知り合いSの推しであるしおくんをめでるだけのゲーム

参考
ねこあつめ（https://www.nekoatsume.com/）

ただし、ねこあつめを参考にオリジナルの要素を盛り込み0から作る
※リバースエンジニアリング等を禁止しているため



要件定義
まず猫集めを遊び、どういった内容を目指していくのかという
共通認識を持つ
その上で目標とするゲームの完成形より
最低限の形を目下の目標とする。（以降ミニマムタイプなどと表現する）


必要な要素
・スタート画面
・ゲーム本編画面
・各種アイテム用画面
・各種図鑑用画面

まずはこれらの画面が最低限の画面となる。

各種キャラクターはアイテムテーブルに紐づくキー項目を持たせ、
各種キャラクターの出現率を調整することで
コンプリートに向けてのやりこみ要素とする。

次回はUnityの環境を作成し、
その上で自学用のUnity記事も別途作成する。
[Micropython]IoT機器からSlackの投稿にリアクション

## はじめに
IoT機器のボタンを押すことでSlackの投稿に対して「リアクション」させる処理をMicropythonで実装しました。そのときの実装ポイントの備忘録となります。

## TL;DR
* PythonにはSlask SDKを使って簡単にSlack APIを叩くことができるがMicropythonにはないのでurequestsを使ってHTTPリクエストを行う
* ユーザー自身の「リアクション」としたいときはユーザー自身のユーザートークンが必要
* ユーザートークンはBearer Tokenとしてヘッダーで指定
* 「リアクション」には`reactions.add`のAPIを使いパラメータには対象記事のタイムスタンプとアイコン名を指定する

## 前提
「リアクション」の対象となるSlackのチャンネルの投稿に対して以下の情報がすでにわかっているものとします。
* リアクションの対象となるSlackチャンネルのID
* ユーザー自身のユーザートークンとアクセス権限(SlackアプリのScopeでいうところの`reactions:write`)
* リアクション対象の投稿のタイムスタンプ
* リアクション時に使うアイコンの名前

以下のリンクにはユーザー自身のユーザートークンを取得するのに必要な手順が書かれていますので参照ください。

## 使用するSlack API
Slackの投稿に対して「リアクション」するために以下の`reactions.add`APIを使用します。

https://api.slack.com/methods/reactions.add

<dl>
  <dt>token</dt>
  <dd>ユーザートークンを指定。Authorizationヘッダーとして渡すかパラメターとして渡す。</dd>
  <dt>channel</dt>
  <dd>リアクション対象のSlackチャンネルIDを指定。</dd>
  <dt>name</dt>
  <dd>リアクションに使うアイコン名を指定。</dd>
  <dt>timestamp</dt>
  <dd>対象の投稿のタイムスタンプを指定。</dd>
</dl>

この`reactions.add`APIの引数はすべて必須となっています。

PythonではSlack SDKがありSlack APIにパラメータを指定するのも比較的容易に実装できますが、今回使うのはMicropythonということもありSlack SDKは使用できないので、Micropythonのurequestsモジュールを使ってSlack APIを実行することにしました。

## Slackの投稿にリアクションするコード
以下はMicropythonでurequestsを使ってSlackの投稿にリアクションするコードです。
```python
import urequests
import ujson

def reaction():
    # リアクションするためのURL
    history_url = 'https://slack.com/api/conversations.history'
    # ユーザートークン
    token = 'xoxp-xxxxxxxxxxxxx.xxxxxxxxxxxxx'
    # リアクション対象のSlackチャンネル
    channel = 'Cxxxxxxxx'
    # リアクションに使うアイコン名
    emoji = 'hei'
    # ヘッダーの作成
    header = {}
    header['Content-Type'] = 'application/json; charset=utf-8'
    header['Authorization'] = 'Bearer ' + token
    # リアクション時のパラメータを設定
    data = {}
    data['channel'] = channel
    data['timestamp'] = latesttime # 対象となる投稿のタイムスタンプ 
    data['name'] = emoji
    res = urequests.post(
        url = reaction_url,
        data = ujson.dumps(data),
        headers = header
    )
    resjson = res.json()
    if resjson['ok']:
        print('Reaction success!')
    else:
        print('Reaction failed!')
```
`data['timestamp']`には`12345678.123456`形式のタイムスタンプの文字列を指定します。
上記コードでは`latesttime`を指定していますが、`latesttime`には事前に取得した投稿のタイムスタンプの文字列が入っています。
`data['name']`にはアイコンの名前を指定します。例えば、\:thumbsup:でリアクションするときは'thumbsup'を指定します。

## 補足
Slack APIのリファレンスによると、tokenは「Authorizationヘッダーとして渡すかパラメターとして渡す」となっていますが、下記のように通常のパラメータとして渡すとレスポンスはOKになりませんでした。

```python
    # ヘッダーの作成
    header = {}
    header['Content-Type'] = 'application/json; charset=utf-8'
    # リアクション時のパラメータを設定
    body = {}
    body['token'] = token　# tokenをbodyの方で指定
    body['channel'] = channel
    body['timestamp'] = latesttime # 対象となる投稿のタイムスタンプ 
    body['name'] = emoji
    res = urequests.post(
        url = reaction_url,
        data = ujson.dumps(data),
        headers = header
    )
```

詳しくは調べていませんが、使ったユーザー独自のユーザートークンだからと勝手に予想。

## 最後に
今更ながらPythonの辞書式とJSON型の違いを言葉で説明する難しさを知りました。
そんな中、もともととある企画で作りたかったものが完成したので良しとしたいと思います。
もし、ご興味あれば以下のリンクをご覧ください。

https://qiita.com/aramss/items/7e129d29c82e1334a91e
$_POST、$_GET

## はじめに

スーパーグローバル変数について整理する。

### $_POST

POST形式のHTMLフォームから渡された情報

ユーザーから入力された値や外部サービスから取得した値を表示する場合には、HTMLエスケープが必要となる。
エスケープ処理を正しく行わないとXSSの脆弱性の原因になる。


```php:Encode.php
function e(string $str, string $charset = 'UTF-8'): string 
{
    return htmlspecialchars($str, ENT_QUOTES | ENT_HTML5, $charset, false);
}
```

```php:post.php
<?php requier_once '../Encode.php'; ?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>ポストデータ</title>
</head>
<body>
こんにちは、<?=e($_POST['name']) ?> さん！
</body>
</html> 
```

### $_GET

クエリ情報(~?キー名=値)経由で渡された情報

```php:get1.php
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>クエリ情報</title>
</head>
<body>
<form method="GET" action="get2.php">
<label for="name">名前：</label>
<input id="name" type="test" name="name" size="15" />
<input type="submit" name="送信" />
</form>
</body>
</html>
```

```php:get2.php
<?php requier_once '../Encode.php'; ?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>クエリ情報</title>
</head>
<body>
こんにちは、<?=e($_GET['name']) ?> さん！
</body>
</html>
```
nftables iptablesいろいろ

80番ポートから 192.168.122.3 に向けて出ていくTCPパケットを捨てる
iptables -I OUTPUT -p tcp --dest 192.168.122.3 --sport 80 -j DROP
iptables -D OUTPUT -p tcp --dest 192.168.122.3 --sport 80 -j DROP
iptables -L OUTPUT

https://knowledge.sakura.ad.jp/22636/
社内向けChatGPTを簡単に作れるMicrosoft社のサンプルアプリのアップデートを紹介します

以前、Microsoft社が公開している[ChatGPTライクなアプリケーションのリポジトリ](https://github.com/microsoft/sample-app-aoai-chatGPT)を紹介する記事を書きました。

https://qiita.com/keitomatsuri/items/aeacb527fbc5de34cacc

簡単な手順でAzure OpenAIと統合したチャットアプリをデプロイでき、アクセス時の認証設定もできるので社内向けChatGPT（ライクなアプリケーション）におすすめ、というものです。
記事を公開してからそれなりの期間が経ってしまいましたが、これまでに素晴らしいアップデートがされているので紹介します。

## チャット履歴が利用できる

CosmosDBを使用したチャット履歴が実装されています。

構築手順は非常にシンプルです。
CosmosDBをデプロイしてデータベースおよびコンテナを作成します。（それぞれの命名の例は.env.exampleに記載があります。）
1点分かりにくい点として、`Partition Key` には `/userId` を設定します。
ドキュメントに「infrastructureフォルダー内のARMテンプレートは、アプリ・サービスのデプロイに使用できます。」と記載がある通り、設定に困ったら `infrastructure/deployment.json` を見るのがよいでしょう。
後はREADME記載の環境変数に値を設定すればOKです。ネットワークの設定を適切に行うことも忘れずに。
Azure OpenAIとの接続でプライベートエンドポイントを使用していれば、ネットワークの設定を使いまわせるのでCosmosDB用のプライベートエンドポイントを作るだけでよく楽でした。

## タイトルやロゴなどのUIを環境変数で設定できる

2024年4月時点では以下が設定可能です。

|環境変数|説明|
|-|-|
|UI_TITLE|チャットタイトル（左上）とページタイトル（HTML）|
|UI_LOGO|ロゴ（左上）|
|UI_CHAT_TITLE|タイトル（チャットウィンドウ）|
|UI_CHAT_LOGO|ロゴ（チャットウィンドウ）|
|UI_CHAT_DESCRIPTION|説明（チャットウィンドウ）|
|UI_FAVICON|favicon|
|UI_SHOW_SHARE_BUTTON|共有ボタン（右上）|

`UI_CHAT_*` はアプリを開いた際に中央にでかでかと表示されるものです。
直接プログラムを触らなくてよくなったのがとても嬉しいですね。
特に社内向けに公開するうえで共有ボタンは明らかに不要なので、環境変数で非表示にできるようになってよかったです。

ちなみにカスタマイズする際の独自の画像ファイルは`frontend/public`配下に配置します。
ビルド時に`static`配下にコピーされアプリはそこを参照するので、環境変数には`/static/favicon.ico`のように設定してあげれば表示されます。

これらを設定しても英語の部分は多々あるので引き続きプログラムを修正するのもよいかもしれないですが、これを機に「環境変数で設定できるとこのみUIを変える」と割り切ってしまうのも選択肢かと思います。

## 環境変数でデバッグログの有効化/無効化ができる

これも地味にうれしいアップデートですね。
Azureへのデプロイ時にハマった際は、アプリが立ち上がる前の問題だったのであまり役に立たなかったのですが、今後活躍の場面はありそうです。

ちなみにハマった点としては、Azure portalでApp Serviceを作ってからAzure CLIでREADME記載のコマンドでアプリのデプロイを試みた際、
`ModuleNotFoundError: No module named 'uvicorn'`のエラーが出てサーバーが立ち上がらないというものでした。
結果として、App Serviceを一度削除し、App Serviceの作成からAzure CLIで行ったところうまくいきました。ご参考まで。

## その他

スケーラビリティの強化、Chat with dataの機能やデータソースの充実、Prompt Flowのサポート等、日々様々なアップデートがなされています。
今後も注目していきたいですね。開発者の皆さんに感謝です。
【RotorHazard】LibreOfficeインストール、バックアップ取得、ファームウェア(Kernel) アップデートの方法

# 20. むぅ…、Office系パッケージ入れておくか…

この記事はFPVドローン ラップ計測システム【RotorHazard】をRaspberry Piで作成するにあたってのTipsをまとめたものです。ですが一般的なラズパイ構築方法としても参考になるかと思いますので、ぜひご活用ください。

### 20-1. LibreOfficeの後付けインストール
えー。これを見たユーザさんからは

『なぜここでLibreOfficeを入れる！それなら最初からRaspberry Pi OS Full版を入れれば良かったじゃん？』

なんていう総突っ込みがあるかもしれませんがｗ そこはご愛敬でオネシャス。
RotorHazardを利用した際、出力したCSV形式等のデータを直接編集したいようなシチュエーションが生まれた際には必要かな？と思ってしまったのです。ですが、当然標準版(デスクトップ版)に必要なものを追加する、Full版で要らないものをアンインストールする…どちらが最適か？なんていうのはご自身の感性の違いも出てきますので。今回はとりあえず **追加する** 方面でご紹介したいと思います。

まずは

**スタート(Piマーク) → 設定 → Recommended Software**

を開き **Office → LibreOffice** を選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/bdfc12e0-966c-766e-0816-b3b040b7bab6.png)

最後に **Apply** すればインストールOKです。
以前までは、ここから日本語化の対応が必要だったようですが、現在の **v1.8.5** を見る限りではその作業は要らなそうです。ちゃんと表示も日本語で見えますし、以前日本語入力の **MOZC** をインストールしたので Shift+Spaceで変換もできます。表計算とかで入れてみても問題はありませんでした。

ワイの手元のRaspberry Pi OS 3Bそのものがスペック高くないのもあり、手元で編集作業とかはすることはほとんどないものの、データ確認ぐらいはできるようにってことで今回導入してみた次第です。


# 21. 安心・安全、バックアップを取っておきましょう

### 21-1. 大体落ち着いたと思うので、ここでバックアップを！
一応大体の大きな設定はできたものと思います。また次のアクションでPiファームウェア(カーネル)のバージョンアップをやろうと思っていましたので、ここでバックアップを取っておこうと思います。
今回用意したのはこんな感じのmicroSDが読めるUSB変換アダプタ。まあ皆さん何らかしらでお持ちかと思いますので適当なものをご用意ください。(ちなみに以前は32GBの壁がアダプタにもあって、大容量のmicroSDが読めない、認識しないなんていうのもありましたが、最近はないんですかね？ワイは今回16GBで統一しているので、その問題は多分ないかな？と思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/614f516f-862e-e2e5-bfab-32842a712de4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/6127cc16-6a1d-10f0-c5a0-e5ad458a7436.png)

とりあえず挿しちゃいましょうｗ
そして、下記のように **スタート(Piマーク) → アクセサリ → SD Card Copier** をクリックし、アプリを起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/0095f138-31bb-136c-624b-b91c21fa6613.png)

初めてコピーを作成する場合は、Linux系パーティションとして認識するよう **New Partition UUIDs** はチェックしましょう。後は、コピー元、コピー先のmicroSDを指定して **Start** します。状況によってはかなり時間がかかるものと思いますが、そこは気長にお待ちくださいー。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/1e4eb7e2-9810-88dc-aff0-1882d0317358.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/13d95852-668f-47f9-31e3-908df2037aee.png)



# 22. ラズパイのファームウェアを更新する方法

### 22-1. これをやるには判断迷いますが…
ラズパイは組み込み系IoTデバイスで、Raspberry Pi OSを入れた流れで、その環境であればファームウェア(Linuxカーネル)のアップデート等も可能になります。ですが時と場合によっては **むやみやたらにやるものではない…** なんていうシチュエーションもありますので、実施等は十分にご検討ください。色々なサイトやブログも並行して確認してみてください。(カーネル等、すべて新しいものがすばらしい…という訳ではありません。特にドローン界隈の方はお感じになるとは思いますが、最新版に上げることへのリスクってどうしてもありますからね)

ワイは、この後どこかで記載しようと思いますがUSB-SSDで起動、そちらとのパフォーマンスの違いや耐久性の検証とかも考えていたので、この行為は最初から実施しようと思っていました。そして下記サイトを参考にしました。バージョン比較等はラズパイ3Bで(デバイス的にも)枯れているのもありますし、あまり気にしなかったんですけどねーｗ

https://ichibariki.com/entry/2016/10/22/175302

```
uname -a

sudo apt update
sudo rpi-update

sudo reboot
```

最初のコマンドは現行バージョンを表示させます。一応メモっておくと良いかと思います。

そして **sudo rpi-update** します。まあこれだけっす。
実は今回USB-SSDを使い、USBブートさせるための更新が主目的ではあったのですが、ファームアップをしたことで、microSDカードの読み書きのIO速度が気持ち向上しました。(Twiiterでそこいらは書いた記憶がｗ)
あまりにも古いものはアップすることでの恩恵はあるかもしれませんね。

ラズパイ構築編のつづきはこちら

https://qiita.com/tmac116/items/994a467fb47034f3f64c?1
epub-translatorを使ってEPUBの洋書を日本語に訳した

タイトルで紹介したOSSはこちらです。

https://github.com/sharplab/epub-translator

こちらのドキュメントにも使い方は書いてありますが、日本語で記事にすることも少しは貢献になるかなと思い。
実際に自分が叩いた具体的なコマンドも交えて、記事を書いてみます。


## 何はともあれクローンしましょう
まずはクローンしてください。clone場所はよしなに。

```shell
git clone git@github.com:sharplab/epub-translator.git
```

## DeepLのAPI Keyを取得しましょう

![スクリーンショット_2024-04-16_20_40_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/947bb758-6cb8-d842-38f3-99afcb70f878.png)

無料のアカウントでも、1月500,000文字までは利用可能です。
ここのURLから API Keyは確認できます。

https://www.deepl.com/ja/your-account/keys

## API Keyをコードにセット
`config/application.yml` に DeepLのAPI Keyを設定します。

application.ymlのサンプルファイルがあるのでコピーして書き換えましょう。

```shell
cp config/application.yml.sample config/application.yml
```

上記でコピーを完了したら、API Keyやエンドポイントを書き換えます。

```yml
ePubTranslator:
  deepL:
    apiEndpoint: https://api-free.deepl.com # DeepL無料アカウントの場合は、エンドポイントが、api-free.deepl.comです。
    apiKey: "**********" # DeepLから取得したAPI Keyをここに書く
  language:
    source: en        # 変換前の言語
    destination: ja   # 変換後の言語
```

お好みで、languageの部分も書き換えたら、英語->日本語以外の変換も可能です。

## Buildコマンドを実行

クローンしたリポジトリのフォルダで以下コマンドを実行します。
```shell
./gradlew quarkusBuild -D quarkus.package.type=uber-jar
```

実行すると、以下のような出力がされます。

![スクリーンショット 2024-04-16 20.47.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/33c4640a-246c-4c36-05c2-f1ee57bf5682.png)

これでbuildフォルダが出来上がります。
buildフォルダには、翻訳するために実行するjarファイルが存在します。

## 翻訳コマンドを実行

```shell
java -jar build/epub-translator-runner.jar --src [翻訳したいepubフィアルのパス]
```

buildフォルダに `epub-translator-runner.jar` ファイルが存在すると思います。
そのパスを指定し、翻訳したいepubファイルのパスを指定すると、epubが翻訳されます。

例えば自分の場合は、以下のようなコマンドを実行しました。
```shell
java -jar build/epub-translator-runner.jar --src ~/production_ready_graphql_complete_package/production_ready_graphql_v1.2.epub
```

このコマンドを実行したら、 `~/production_ready_graphql_complete_package/`フォルダに `production_ready_graphql_v1.2.ja.epub`というepubが生成されていました。

## 終わり
手順は全く難しくないと思いますので、洋書を英語で読めない~などの場合には使うと便利かもですね~。
【Dataverse】日時フィールドはUTCタイムゾーン

## はじめに
Power Automate で日時データを Dataverse に登録する、または日時フィールドでクエリしてレコード（行）を取得するという処理を行うことがあります。今回の記事では、そこで Power Platform 初心者の私が勘違いしていた Dataverse の日時フィールドの仕様を備忘録として残しておきます。

## ケース1：Dataverse に保存した日時データの時間が合わない
Power Automate で現在日時を取得する際、しばしば「アクション：現在の時刻」や「関数：utcNow」を使用しますが、これらはUTCであるため、JST（UTC+09:00）に変換した現在日時を Dataverse のテーブルに保存してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3478860/138d080e-f91d-5277-53ec-0306029b2866.png)

実行結果：

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333437383836302f36623832613262642d633839352d323031662d396138362d3237346633663436363338332e706.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3478860/d8357487-d680-1efd-ba61-1c83b9760b2f.png)


UTCの現在日時「2024年4月16日9時14分」に対して、テーブルにはJSTに変換した日時「2024年4月16日18時14分」が入力されていることが確認できます。

テーブル画面：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3478860/fa015381-0f88-9d07-9ba8-1e42db9a9ec9.png)

しかし、Dataverse のテーブルを見てみると **「2024年4月17日3時14分」**。取得したJSTよりさらに**9時間進んだ日時**になってしまいました。

## ケース2：Dataverse の日時フィールドでクエリしても対象のレコードが取得できない
続いて、Power Automate を使用して先ほどのテーブルから「2024年4月17日0時以降」のレコードをクエリして取得してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3478860/12f6b39e-a66e-2eca-d46b-15055f2eec58.png)

実行結果：

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333437383836302f37303166663436352d633738312d323062342d343465622d3738343931363034303032642e7 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3478860/c21c275c-ab8d-f595-0dcc-b7c66c090278.png)


「2024年4月17日0時以降」であれば「2024年4月17日3時14分」のレコードが取得できるはずですが、何も取得できませんでした。

## 日時フィールドの仕様を確認してみる
公式のドキュメントを確認すると、dataverse は**すべての日付と時刻の値をUTCで保存する**とのことでした。

https://learn.microsoft.com/ja-jp/power-apps/maker/data-platform/behavior-format-date-time-field#behavior

また、テーブルの日時フィールドにおいて、[タイムゾーンの調整] が [ユーザーローカル] に設定されている場合、日時フィールドは**ユーザーローカルのタイムゾーンとの差を自動で計算して表示**します。一方、[タイムゾーン非依存] とすると、データベースに保存される日時と表示を一致させることができます。※デフォルトでは [ユーザローカル] に設定されています。

つまり、今回のケースでは、**「2024年4月16日18時14分」をUTCとして保存**しており、[ユーザローカル] の設定により**9時間進んだ「2024年4月17日3時14分」が表示**されていました。そのため、保存した日時と表示の日時が合わない、日時でクエリしたデータがうまく取得できないという事象が発生しているのでした。[ユーザローカル] で使用する場合は、**データの保存もクエリもUTCの日時で行う必要がある**ということです。

## 結論
* Dataverse の日時フィールドは、**内部的にUTCの値を持っている。**
* [タイムゾーン調整] を [ユーザローカル] に設定することで、**表示される日時がユーザローカルのタイムゾーンに変換される。**

## おわりに
一般的なデータベースは、異なるタイムゾーンの日時を一貫して管理するためにUTCを使用しています。また、多くのグローバルなサービスや外部システムもUTCを使用しているため、それらとのデータの統合や連携を行う際にもUTCタイムゾーンで管理しておくとスムーズです。初歩的な内容ではありますが、私を含め Power Platform をきっかけにアプリ開発やデータベースにはじめて触れる方もいらっしゃると思うので記事として残しました。
PL/SQL　#1　～ストアドプロシージャまで

## PLSQL

SQLの拡張機能として「PL/SQL」がある
大きな特徴としては
分岐やfor文が使えることであり、

OracleDatabaseに対しての移植性が高く
また、内部にプログラムを内包できることからパフォーマンス性も高い。

- 無名プログラム
（プログラム本体がDBに格納されないもの）
- ストアドプログラム
（DBにプログラムが格納される）

基本的な構造は
```sql
DECLARE
  宣言部分;
BEGIN
  実行部分;
EXCEPTION
  例外処理部分;
END;
```

で作成されている

感覚としてはその他のプログラムに言語に近く
宣言部で変数等を設定し、
実行部で処理を記載
例外処理部でエラー発生時の処理を記載する

```sql
CREATE PROCEDURE
 --<プロシージャ名>
 TEST_PROCEDURE
IS
 --<宣言部分>
 var1 VARCHAR2(10) := 'Hello';
 var2 VARCHAR2(10) := 'World';
BEGIN
 --<実行部分>
 DBMS_OUTPUT.PUT_LINE( var1 || var2 ); 
EXCEPTION
 WHEN OTHERS THEN
  NULL;
END TEST_PROCEDURE;
```

今回の場合は宣言部分で設定した文章を読み込むだけの
単純な文章だが、
基本構文としてはこの形である。

プロシージャに関しては
```sql
CREATE OR REPLACE PROCEDURE
```

とすることで今あるものを上書きすることが可能である。
処理に応じて使い分ける必要がある。
VSCodeとJupyter NotebookでR言語開発環境を快適にしよう（Windows11）（環境構築）

# はじめに
:::note info
本記事の対象読者は以下を想定しています。

・Rの開発環境をRStudio→VSCodeに移行したい
・すでにVSCode上でRが書ける環境はあるが、Jupyter Notebook形式でも編集できるようにしたい

基本的な環境構築についてはわかりやすい記事が多く出回っているので、下記記事などを参照してください。
:::

https://www.tku.ac.jp/iss/guide/classroom/soft/rrstudio-desktop.html


https://qiita.com/mmake/items/05597e18641ba75fbdbf

ここでは、データ分析に広く使用されているR言語のWindows11における開発環境を、VSCode上のJupyter Notebook(.ipynb)形式で構築する手順を説明します（Macユーザーの方はごめんなさい！）。

従来、RはRStudioによるUIが評価されてきました。私の通う大学でも度々Rstudioが推奨されます。しかしJupyter Notebookの対話型形式を用いればコードと図表の関係で迷子になることは無いですし、また、コードを入力するときもVScodeと連携したGithub Copilot（Rstudioでも一応使えるけど！）の恩恵にあずかることで、コードの構築スピードが格段に上がります。これらを可能にすることを目指します。

:::note warn
R本体との互換性はRStudioほど優れている印象は受けないので、複雑なコードを処理する場合は何かしらのエラーが生じる可能性があります。
:::

# Rの設定
### IRkernelのインストール
RをJupyter Notebookで使用するために、IRkernelのインストールと登録をします。
Rコンソールで次のコマンドを実行します
~~~qitta.r
install.packages('IRkernel')  # IRkernel(Rカーネル)をインストール
IRkernel::installspec()  # JupyterNotebookにRカーネルを登録
~~~

# VSCodeの設定

### 拡張機能のインストール
VSCodeを開き、左サイドバーの拡張機能アイコンをクリックします。
検索バーで「R」を検索し、表示されたR拡張機能をインストールします。

### パス設定
VSCodeでRを使用するためのパスおよびJupyter NotebookがIRkernelを信頼させるためのパス設定をします。（JupyterはもともとPython用に作られているので、Pythonカーネルはデフォルトで信用されています。）

・`r.rterm.windows`：Rスクリプトを対話的に実行するためのターミナルのパスを設定する
・`r.rpath.windows`：Rのヘルプやパッケージ管理などの機能でRを呼び出す際のパスを設定する
・`jupyter.kernels.trusted`：特定のパスをJupyterに信頼させ、アクセスできるように設定する

以下のようにsettings.jsonにパスを追加します。R のインストールパスはWindows では通常
`` C:\Program Files\R\R-X.X.X\bin `` 
のようなパスになります。ここで R-X.X.X は R のバージョン番号です。
``C:\\Users\\user\\AppData\\Roaming\\jupyter\\kernels\\ir\\kernel.json``のパスを獲得する際、AppDataフォルダは隠しフォルダなので、エクスプローラーの「表示」タブをクリックし、「隠しファイル」にチェックを入れることで検索結果に表れるようになります。
~~~qitta.setting.json
"r.rterm.windows": "C:\\Program Files\\R\\R-X.X.X\\bin\\R.exe",
"r.rpath.windows": "C:\\Program Files\\R\\R-X.X.X\\bin\\R.exe",
"jupyter.kernels.trusted": [
    "C:\\Users\\ユーザー名\\AppData\\Roaming\\jupyter\\kernels\\ir\\kernel.json"
    ],
~~~
:::note warn
setting.jsonにもともと記述がある場合、最後の行にコンマを忘れずに追加しましょう。
:::

以上の設定が完了したら、VSCodeを再起動して変更を反映させてください。
左上``ファイル``→``新しいファイル``→``Jupyter Notebook``でノートブックを新規作成します。
下記画像の赤線``カーネルの選択``より、Jupyter Kernel内のRを選択することで、対話型でRのコードが書けるようになっていることを確認してみてください。
![スクリーンショット (81).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675812/775d2ba8-8d65-1e82-b6aa-d0e03244781c.png)
![スクリーンショット (82).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675812/8aae6563-6cbe-8161-74ec-57f0a8521571.png)

# 参考文献
・Windows 11 の VSCode の Jupyter 実行環境の構築
<https://qiita.com/drafts/2e997cb08e724de60e7d/edit>

・「R」と「RStudio Desktop」の導入方法
<https://www.tku.ac.jp/iss/guide/classroom/soft/rrstudio-desktop.html>
Saelsforce動的フォームの欠点？～パス設定による動的フォーム必須化無効について

本橋孝昭です

今回は動的フォームでの欠点？について見つけましたので共有します
それは動的フォームで項目の必須化をした場合、通常のページレイアウトであれば項目の必須化は適応されるようですが、パス設定の変更では必須化ができない　という話です

それではさっそく設定を見ていきましょう

## そもそもSalesforce動的フォームってなんだ？
動的フォームについてはこちらの記事を参考してください

https://qiita.com/Takaa/items/12e08f435594afcb393c

ざっくりいえば、動的フォームの設定により特定の項目の値で項目表示や非表示、項目の有効化などが可能です

## 動的フォームってどうやって有効にするの？
こちらの有効で設定が可能です

https://qiita.com/Takaa/items/62195e5bbc6b44e75ea3


## パスってなんだ？
パスとはこちらのように選択リストの値を上のほうに表示させることができます

https://qiita.com/Takaa/items/fcb733b55fd19afa26ca

商談オブジェクトのパスは見たことある方が多いのではないのでしょうか

以上、前提です

## ここからが本題　動的フォームの項目必須とパス設定を共存させたらどのような不都合が生じるか　解説

さて、動的フォームの有効化とパス設定画面表示によりどのようなことが発生するかというと

・パス設定ではなく通常ページレイアウトでの項目編集では動的フォームの設定により項目必須が効く
・しかしパス設定による選択リスト変更では、動的フォームの項目必須の有効化が効かない（項目が空欄でもパス設定が通ってしまう）


それでは例を見ていきましょう


条件
test項目 選択リスト
testXX項目　テキスト

test項目の選択リストがBの場合testXX項目の入力は必須になる

なお、test項目にパス設定の設定をしております

![条件001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/29dc3624-71db-16df-4725-1abba2293d4c.png)

この場合ページレイアウト上で
・test項目 選択リストがBの場合
・testXX項目　テキストが空欄だとエラー（必須にしないといけない）
という条件になりますが、

![必須001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/f7409e33-6063-0069-e6a0-ae11388c93de.png)



パスでのtest項目の変更の場合

・test項目 選択リストがBの場合
・testXX項目　テキストが空欄だとエラーにならない（必須ではなくても対応可能）

![必須002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/89769b52-83f5-1e00-b4c8-ea8bc7a75ba6.png)



となります

※このあとパスではなくページレイアウトでの編集をした場合、項目必須としてtestXX項目項目が必須にしないとエラーが表示されます

![必須003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/1b923b2a-e304-10a4-3abf-e517e64eedbb.png)



パス設定でも必ず項目必須にしたい場合、別途入力規則の作成が必要かもしれません。
pythonでImportErrorが出た！

pythonファイルを実行した際に...

```
ImportError: cannot import name 'VisibleDeprecationWarning' from partially initialized module 'numpy'
```
翻訳
ImportError: 部分的に初期化されたモジュール 'numpy' から名前 'VisibleDeprecationWarning' をインポートできません


# 解決
参考

https://qiita.com/7shi/items/9c15e2aca88bd40eed2a

パッケージからnumpyをimportするはずが、自分自身のファイル「nampy.py」 をimport してしまったのが原因と思われる。

名前を「num.py」に変更して実行した結果、エラーは出なくなった！
より高度なSEO対策ができるuseSeoMetaを使ってみる

## はじめに

Nuxt.jsの公式ドキュメントを見ていると、useSeoMetaというコンポーザブルがあり、気になったので調べて使ってみました。

## そもそもuseHeadとuseSeoMetaでメタタグ生成するのに違いがあるの？

メタタグの生成時にはuseHeadを使っているのですが、そもそもuseHeadでメタタグ生成するのとuseSeoMetaで生成するのでは何か違いがあるのか分からず、調べてみました。

結論としては、どちらもSEOに関連するメタタグを生成できますが、useSeoMetaの方がより高度なSEO対策をすることができるみたいです。

useHead：Nuxt の標準的なヘッドコンポーネントでメタタグ、リンクタグ、スタイルタグなどを生成できる
useSeoMeta：SEOに関連するメタタグを生成するための専用コンポーネントでuseHeadよりも多くの機能を提供できる

https://nuxt.com/docs/api/composables/use-seo-meta



## useServerSeoMetaとuseSeoMetaの違いは？

もう少し調べてみると、useServerSeoMetaというのもあり、useSeoMetaの違いを調べてみました。

useServerSeoMeta は、SSRで使用することを想定されています。サーバー側でメタタグを生成するため、パフォーマンスへの影響が少なく、カスタマイズが容易です。

useSeoMeta は、SPAで使用することを想定されています。クライアント側でメタタグを生成するため、パフォーマンスへの影響があるものの、カスタマイズが難しいというデメリットがあります。

useServerSeoMeta：サーバー側でメタタグを生成する。つまり、ページのHTML が生成されるタイミングでメタタグが生成される
useSeoMeta：クライアント側でメタタグを生成する。つまり、ユーザーがページを読み込むたびに、メタタグが生成される

https://nuxt.com/docs/getting-started/seo-meta#useseometa-and-useserverseometa



## useServerSeoMetaを使ってみる

使い方はuseHeadで使っていたときみたいに、useServerSeoMetaの中に定義されているプロパティに対する値を入れてあげるだけです。


```js
useServerSeoMeta({
  title: 'test_title',
  description: 'test_description'
})
```



パラメータは100以上あり、詳しくはこちらを参照してください。

https://github.com/harlan-zw/zhead/blob/main/src/metaFlat.ts




## SSGでuseServerSeoMetaを使うと

SSGでどうなるか使ってみたのですが、発見があったのでまとめておきます。

useFetchしてコンテンツを取得して生成するページに関してはuseServerSeoMetaでメタタグ生成されましたが、サービス紹介ページのようなHTMLベタばりのページをSSGした場合は、useServerSeoMetaでメタタグ生成されないことがわかりました。

てっきりSSGの処理的には全ページをサーバー側で静的ページにビルドしていると思っていました。これはSSGでgenerateしてる時に、元々静的なページに関してはサーバー側で呼び出されてないのか分からないのですが、挙動が違ったことがわかりました。

useFetchしない静的ページに関してはuseSeoMetaを使うなどの使い分けが必要なのでしょうか。この辺り詳しい人に裏側でどうなっているのか聞いてみたいです。

## JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからライン登録お願いします👇

https://projisou.jp/
LangchainのTool Callingについて紹介します

先日、Langchainが”Tool Calling”という機能を正式にリリースしましたので、共有したいと思います。

# 1.Tool Callingとは
tool callingはAI-agentのコアになる機能で、LLMが外部ツールを使用することを指します。最初OpenAIから発表されて、当時は”function calling”という名前だったです。
（昨年11月に”tool calling”に変更され、それと同時に複数のツールを並行して呼び出せるようにもなりました。）

tool callingのメリットとしては、ツールを活用することでLLMができない作業もできるようになることです。
例えば、モデルにPythonを使った数式計算を行う関数（ツール）を提供し、そのツールに対して適切な説明を加えれば、モデルはそのコードを使って数学計算ができるようになり、LLMの計算能力の弱点を補うことができます。

# 2.Tool Callingの流れとイメージ
tool callingの処理の流れは、各ツールに詳細な説明用のprompt文を用意し、モデルがユーザーの指示とツールの説明文に基づいて、どのツールを使用するかを判断して処理を実行します。

例えば、ユーザーから「JSONの形式で質問に答えてほしい」というリクエストがあった場合、モデルは自動的にJSONparserというツールを呼び出して回答を生成します。また、「最新の論文情報を知りたい」という質問があれば、arXivなどの関連APIを呼び出して情報を取得します。

今回Langchainが発表した"tool calling"は、各モデルのこのようなツール呼び出しのプロセスを統一化しています。（これまで主要なLLM（chatgpt,gemini,claude,cohereなど）はそれぞれ独自のtool calling形式を持っており、入力、出力、パラメータの設定方法などもバラバラでした。）

ただし、tool callingが適切に機能するかどうかは、主にLLMの能力に依存しています。そのため、小規模なモデルではtool callingを活用することが難しい場合があります。そういった場合は、tool callingのデータを使ってモデルをファインチューニングする必要があります。（tool calling用のオープンソースデータはHugging Faceに多数あります。イメージとしては以下のようなものです。）


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/b4179009-4880-af47-e803-12cf2d55a533.png)

Langchainのgithubコミュニティで、他の人がファインチューニングした結果を見ると、およそ1万件程度のデータを使えば、7B規模のモデルでも特に問題なくtool callingを習得できるようです。私も最近ちょっと試してみたいと思います。

興味ある方：

https://platform.openai.com/docs/api-reference/chat/create

https://blog.langchain.dev/tool-calling-with-langchain/
Django：staticファイルが読み込めない

# 構成
- djnagoのバージョン：　5.0.2
- pythonのバージョン：　3.11.8


# 問題
`{% load static %}`しているが、staticファイルを読み込んでも404エラーが表示される

# 確認したこと
- staticファイルの位置
- 読み込んでいるファイルの名前間違いがないか
- setting.pyにあるSTATIC_URLの記述が`STATIC_URL = '/static/'`になっているか

# 必要だったもの
setting.pyに**STATICFILES_DIRS**の記述が必要だった
```
STATIC_URL = '/static/'

# staticはここの記述も必要
STATICFILES_DIRS = [
    BASE_DIR / "static"
]

```
→ 読み込めるようになった
Unity Catalogにおける関数のサポート

こちらの機能を試します。というか、最近まで気づいていませんでした。

https://docs.databricks.com/ja/udf/unity-catalog.html

:::note info
**プレビュー**
本機能は[パブリックプレビュー](https://docs.databricks.com/release-notes/release-types.html)です。Databricks Runtime 13.2 以降が必要です。
:::

要はSQLやPythonの関数(User-defined function:UDF)をUnity Catalog(カタログエクスプローラ)で管理できる機能です。権限設定やリネージなどの機能を活用できます。

ただ、パブリックプレビューであることもあり、いくつかの制限があります。以下に列挙します。

- Databricks Runtime 13.2 以降が必要です。
- Gravitonインスタンスではサポートされません。
- 従来のPython UDFのスコープはSparkSessionですが、こちらはカタログエクスプローラで管理されるので、権限が許可される限りDatabricksアカウントで共有されます。

# SQLのUDF

以下のSQLを実行すると指定したカタログ、スキーマの配下に関数が作成されます。

```sql
CREATE FUNCTION takaakiyayoi_catalog.default.simple_roll_dice()
    RETURNS INT
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    COMMENT 'Roll a single 6 sided die'
    RETURN (rand() * 6)::INT + 1;
```
![Screenshot 2024-04-16 at 19.44.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/feb7e442-4932-61b1-6e40-ecc0767eba7e.png)

```sql
SELECT takaakiyayoi_catalog.default.simple_roll_dice()
```
![Screenshot 2024-04-16 at 19.44.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/6d628db9-db2e-cf01-d2e7-a827b81d3672.png)

# PythonのUDF

Pythonの方が自由度の高い分、制限も増えます。

- Python UDFは安全で分離された環境で実行され、ファイルシステムや内部サービスにアクセスできません。
- Python UDFはスカラー値を返す必要があります。UDTF(ユーザー定義テーブル関数)やUDAF(ユーザー定義集計関数)はサポートされていません。
- 標準のPythonライブラリをインポートできますが、カスタムライブラリや外部の依存関係を持ち込むことはできません。
- PySparkから呼び出すことはできず、Spark SQLからのみ呼び出すことができます。

```sql
CREATE OR REPLACE FUNCTION takaakiyayoi_catalog.default.roll_dice(num_dice INTEGER, num_sides INTEGER)
RETURNS INTEGER
LANGUAGE PYTHON
AS $$
  import numpy as np

  def roll_die(num_sides):
    return np.random.randint(num_sides) + 1

  def sum_dice(num_dice,num_sides):
    return sum([roll_die(num_sides) for x in range(num_dice)])

  return sum_dice(num_dice, num_sides)
$$
```
![Screenshot 2024-04-16 at 19.48.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/7a5afbd8-e2c5-3b0b-13dd-1aaad50765a1.png)

```sql
SELECT takaakiyayoi_catalog.default.roll_dice(3, 6)
```
![Screenshot 2024-04-16 at 19.49.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/30a5b44e-958e-0242-a3e4-9644dd4b0699.png)


### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)