OmniAICreator/Qiita-1.07M huggingface dataset:
MacのCaps Lockを入力切り替えとして使う

## デフォルト設定ではいけないの？
Appleキーボード設定で `caps lock` を入力切り替えキーとして扱うことができるのは確かです。

<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582278/32f91260-5d38-b150-7196-8631e7ab32f5.png">

**しかし、以下のような問題点があります。**

`caps lock` がONのままパスワードなど英字のみでしか入力できない入力欄にいくと当然、シフト固定とみなされ大文字入力になります。

---
🤓：それなら `caps lock` がONになってるか確認してONならOFFにすればいいのでは？

😐：いやいや、結構めんどくさいんすよ

---
なので、`caps lock` を無効化し入力切り替えのみ行うキーに設定していきます！


## [Karabiner-Elements](https://karabiner-elements.pqrs.org) をインストール
1. 公式サイトからダウンロード
1. ダウンロードしたdmgを開く
1. pkgを選択してインストールしていく
1. アプリ（下のアプリ）を開くと権限が要求されるので権限をあげる
 
    <img width="150" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582278/39db2839-7ea7-a5b2-e024-97f1b9907ecd.png">


## 設定していく(๑•̀ㅁ•́๑)✧
下記の設定コードを手順通り設定してください。

> 手順
1. Complex Modificationsを開く
1. 中央上にある「Add your own rule」をタップ
1. デフォルトコードを削除し、下記の設定コードを入力
1. 右上の「✔︎Save」を選択する

    以上

> 設定方法.mp4（これ見れば一発）

https://youtu.be/ksxYIuliE_I?si=DV8qpLZKaF6__0WW

> 設定コード

```json
{
   "description": "capsを入力切り替えにする",
   "manipulators": [
      {
         "conditions": [
            {
               "input_sources": [
                  {
                     "language": "ja"
                  }
               ],
               "type": "input_source_if"
            }
         ],
         "from": {
            "key_code": "caps_lock",
            "modifiers": {
               "mandatory": [
                  "any"
               ]
            }
         },
         "to": [
            {
               "key_code": "japanese_eisuu"
            }
         ],
         "type": "basic"
      },
      {
         "conditions": [
            {
               "input_sources": [
                  {
                     "language": "ja"
                  }
               ],
               "type": "input_source_unless"
            }
         ],
         "from": {
            "key_code": "caps_lock",
            "modifiers": {
               "mandatory": [
                  "any"
               ]
            }
         },
         "to": [
            {
               "key_code": "japanese_kana"
            }
         ],
         "type": "basic"
      }
   ]
}
```

問題なければ `caps lock` 又は `他キー ＋ caps lock` を入力することでシフト固定されないまま入力切り替えをすることができます。

:::note warn

`caps lock` を連打すると空白が入力される場合があります。
その場合は下記の設定箇所が「Caps Lock」になっていることを確認してください。

<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582278/8c879dc6-5340-dc0f-2130-3b1295de2f96.png">
:::


## 最後に
無料で神アプリあればコメント欄に投げてください。

有料かつ安くてあんまり人気はないけど実は結構優れているアプリがあればコメント欄に投げてください。
無平方数（Squarefree number）と メビウス関数（その２）

[前回（その１）](https://qiita.com/masa0599/items/02a0f29cc572a475a7e7)では無平方数（Squarefree number）の数がメビウス関数を使うと簡単に求まるということを紹介しました。今回はその応用編です。

### 平方因子を１個だけ持つ数を数える

例としては$2^2 \times 3$は平方因子が１個で$2^2 \times 3^2 \times 5$は２個になります。

**【例題】N以下の平方因子を１個だけ持つ数をsp(1,N)と表すときsp(1,$10^8$)を求めよ**

まず前回のように平方因子が$4,9,25$の3つの場合で考えてみます、平方因子が$4$のみの数の個数をSS(4)とすると以下のように表されます。（ベン図を書いてみると分かりやすいかもしれません）

```math 
\begin{align}
&ss(4) = m(4)- (m(4 \times 9)+m(25 \times 4))\\
&+ m(4 \times 9 \times 25)\\
\end{align}
```
同様にss(9)とss(25)を求めて足し合わせれば良いので、

```math 
\begin{align}
&sp(1,40) = ss(4)+ss(9)+ss(25) \\
&= m(4)+m(9)+m(25)\\
&- \color{red} {2} \times (m(4 \times 9)+m(9 \times 25)+m(25 \times 4))\\
&+ \color{red} {3} \times m(4 \times 9 \times 25)\\
\end{align}
```
この式は前回と似ていますが赤で表される係数がつきました。この係数はそれぞれ２個と３個から１個に与える影響ということで、$\large \binom{2}{1}, \binom{3}{1}$で求められます。

これを前回と同様に変形します。ここではnの素因数の数をnf(n)で表します。

```math 
\begin{align}
&sp(1,40) = -\binom{1}{1}(\mu(2) m2(2) + \mu(3)  m2(3) + \mu(5)  m2(5))\\
&+ \binom{2}{1}((\mu(6)m2(6))\\
&= \sum_{k=1}^{\lfloor \sqrt{40} \rfloor} (-1)\mu(k) m2(k) \binom{\mathrm{nf(k)}}{1}\\
&= \sum_{k=1}^{\lfloor \sqrt{40} \rfloor} (-1)\mu(k)  \lfloor 40/k^2 \rfloor \binom{\mathrm{nf(k)}}{1}\\
\end{align}
```
これを一般化すると以下の式が得られます
```math 
\begin{align}
& \mathrm{sp(1,N)} = \sum_{k=1}^{\lfloor \sqrt{n} \rfloor} (-1)\mu(k)  \lfloor N/k^2 \rfloor  \binom{\mathrm{nf(k)}}{1} \cdots (1)\\
\end{align}
```
さらに平方因子を増やして考えます

### 平方因子をr個だけ持つ数を数える

**【例題】N以下の平方因子をr個だけ持つ数をsp(r,N)と表すとき$\mathrm{sp(r,10^$)}$を求めよ**

式(1)の符号はrが奇数と偶数で変わるのと、係数が、$\large \binom{\mathrm{nf(k)}}{r}$になるだけなので以下の式になります。

```math 
\begin{align}
& \mathrm{sp(r,N)} = \sum_{k=1}^{\lfloor \sqrt{n} \rfloor} (-1)^r\mu(k)  \lfloor N/k^2 \rfloor  \binom{\mathrm{nf(k)}}{r} \cdots (2)\\
\end{align}
```
これを素直にpythonのコードにして$\mathrm{sp(r,10^$) \ (r=0, \cdots ,6)} $を求めました。kの素因数の数$\mathrm{nf(k)}$はsympyのprimefactorsを使っています。

```python 
import sympy as sp

def SP(r, N):
  ret = 0
  for k in range(1, int(N**(0.5))+1):
    ret += sp.mobius(k)*(N//k**2)*sp.binomial(len(sp.primefactors(k)),r)
  return (-1)**r*ret

N = 10**8
print(f"N = {N}")
for r in range(0,6+1):
  print(f"SP({r},N) = {SP(r, N)}")
# N = 100000000
# sp(0,N) = 60792694
# sp(1,N) = 33539196
# sp(2,N) = 5329747
# sp(3,N) = 329028
# sp(4,N) = 9257
# sp(5,N) = 78
# sp(6,N) = 0
```

今回は平方因子を$r$個持つ数を正確にかぞえる方法を考えましたが、[次回（その３）](https://qiita.com/masa0599/items/c39e6084ef281d41250f)では$N \rightarrow \infty$としたときに平方因子を$r$個持つ数の割合を、確率の考え方を用いて求めます。

（開発環境：Google Colab）

この考え方はProject Euler、Problem 632: Square Prime Factorsを解くのに役に立ちます。
Symbol-SDK@3.2.2でNEMる01 -アカウント生成-

NEM時代はニーモニックでアカウントを作成するウォレットは無かったのかもしれませんが（あったらスミマセン）、今はSymbol-SDKがあるのでSymbolと同じように出来ます。

symbol-sdk@3.2.2です。
ちょっと使い方が変わりました。

## ニーモニック生成
SymbolとNEMは秘密鍵は共用出来るので、ニーモニックも共通です。
```typescript
import { Bip32 } from 'symbol-sdk'

/** ニーモニック生成 */
const bip32 = new Bip32()
const mnemonic = bip32.random()
console.log(`mnemonic: ${mnemonic}`)
```

## アドレス生成
Envにはtesutnetとかニーモニックが格納されているだけです。
```typescript
import { Bip32 } from 'symbol-sdk'
import { NemAccount, NemFacade } from 'symbol-sdk/nem'
import { Env } from './Env.js'

const facade = new NemFacade(Env.NEM_NETWORK_IDENTIFIER)
const maxAccounts = 10
const mnemonic = Env.MNEMONIC

/** ニーモニックからアカウント生成 */
const passwd = ''
const bip32Node = new Bip32().fromMnemonic(mnemonic, passwd)
for (let i = 0; i < maxAccounts; i++) {
  const bip32Path = facade.bip32Path(i)
  const childBip32Node = bip32Node.derivePath(bip32Path)
  const keypair = NemFacade.bip32NodeToKeyPair(childBip32Node)
  const account = new NemAccount(facade, keypair)
  console.log(`PrivateKey : ${account.keyPair.privateKey}`)
  console.log(`PublicKey  : ${account.publicKey}`)
  console.log(`Address    : ${account.address}`)
  console.log(
    '============================================================================='
  )
}
```

とりあえず、アカウント生成まで。
BGP Third-Party Next Hopってなんだ？

## eBGPのNext Hop
Third-Party Next Hopについて語る前にまずは通常のeBGPのNext Hopについておさらいします。
eBGPでは経路情報を広報する時にNEXTHOPを自身のアドレスに書き換えます。
例えば以下ネットワークにおいて、AS1のルータはAS2のルータに対して、192.0.2.0/24のネットワークを広報する時にNEXTHOPを198.51.1.1に書き換えます。
つまり、AS2のルータのルーティングテーブルには192.0.2.0/24宛てのネクストホップは198.51.1.0となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768522/ba8d6a69-3c5a-3e7b-e2f8-5a5a3f2622c9.png)

## Third-Party Next Hop
CMLで以下のようなLABを作成しました。
R1-R2、R1-R3でeBGP Peerを張り、**R2-R3ではeBGP Peerを張りません**。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768522/11ae0497-a54d-9d49-bc38-ee185c9087e1.png)

先に記載した通り、eBGPで経路情報を広報する時はNEXTHOPを自身のアドレスに書き換えます。
その為、R2は1.1.1.1宛ての経路を100.0.0.1として学習しています。(R3も同様)

```
R2#sh ip bgp 1.1.1.1
BGP routing table entry for 1.1.1.1/32, version 3
Paths: (1 available, best #1, table default)
  Not advertised to any peer
  Refresh Epoch 1
  65001
    100.0.0.1 from 100.0.0.1 (1.1.1.1)
      Origin IGP, metric 0, localpref 100, valid, external, best
      rx pathid: 0, tx pathid: 0x0
R2#
```

では、R2がR3のループバックアドレス3.3.3.3を学習する時の挙動を考えます。
R2とR3はeBGP Peerではない為、R3→R1→R2の順に広報されます。
普通に考えれば、R1はR2にR3のループバックアドレスを広報する時に自身のアドレスに書き換える為、NEXTHOPは100.0.0.1となるはずです。
しかし、NEXTHOPは100.0.0.3になっています。学習元はR1だしAS Pathも65001を経由しているように見えるのにNEXTHOPだけがR3に向いています。
```
R2#sh ip bgp 3.3.3.3
BGP routing table entry for 3.3.3.3/32, version 4
Paths: (1 available, best #1, table default)
  Not advertised to any peer
  Refresh Epoch 1
  65001 65003
    100.0.0.3 from 100.0.0.1 (1.1.1.1)
      Origin IGP, localpref 100, valid, external, best
      rx pathid: 0, tx pathid: 0x0
R2#
```
このように他のASを経由した場合においても、同一セグメント内の経路広報であればNEXTHOPを書き換えないという仕様がThird-Party Next Hopです。
上記のようにハブアンドスポークでPeerを張った場合でもスポーク間で直接通信を行います。
しかし、BGPの経路広報はハブを経由する(他ASを経由している)点には注意が必要です。
例えば、R2で発出したMED値はR1からR3に経路広報される時にクリアされます。

### 参考
https://datatracker.ietf.org/doc/html/rfc4271#section-5.1.3
Swift　TableViewを検索してデータを絞り込む（Realm使用）

# はじめに
Realmで保存してあるデータがTableViewに既に表示されている状態のとき、UISearchBarを用いた検索機能を実現したいと考えている人向けの記事です。Realmをデータベースとして用いたのでこのように謳っていますが、別にRealmじゃなくてもやることは一緒です。

# コード
今回はUISearchbarの文字列が変わる度に検索をかけるときを想定しています。
肝心の絞り込みはRealmの.filter関数を用いています。
何を用いてデータを保存しているかに応じてフィルタリングを行うときの関数の形は変わりますが、変わるのはそれだけで、
1. 文字列に応じてフィルタリングを行う
1. 上記の結果を配列に格納する
1. tableViewをリロードする

の手順を踏めばOKです。

```Swift
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        if searchBar.text?.count == 0 { // 検索されている文字列がない時
            configureTableView()
            DispatchQueue.main.async {
                searchBar.resignFirstResponder()
            }
        } else {
            let realm = try! Realm()
            self.itemList = realm.objects(TimeCapsuleModel.self).filter("title CONTAINS[cd] %@", searchBar.text!) //itemListにフィルタリングした結果を格納する
        }
        tableView.reloadData()
    }
    func configureTableView() {
        let realm = try! Realm()
        self.itemList = realm.objects(TimeCapsuleModel.self)
        
        self.tableView.reloadData()
    }
```
Power AppsフォームでSharePointリストのユーザー列選択肢を限定する方法

## やりたいこと
Power Appsのフォームで、SharePointリストのユーザー列に紐づくカードおよびコンボボックスコントロールで選択できるメンバーを限定したい（通常は全社員可能）。
Authoring version: 3.24083.14 

## 方法
::: note info
正攻法はセキュリティグループやSharePointグループを使った方法ですが、グループ管理が面倒だったり動的に変化させたい場合等に使えるテクニックかと思います。[yoshioさん](https://x.com/yoshio_440044/status/1829856624519102803)、[ヨウセイさん](https://x.com/youseibubu/status/1829892609747402793)アドバイスありがとうございます。
:::
１．まずはコンボボックスの`Items`プロパティに限定したいメンバーのメールアドレスを含むテーブルを指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/b2f11042-3817-ba17-148b-5b4cc1f6118a.png)
↓の例では特定部署メンバーをとってくる`DirectReportsV2`を使用。
```
Items: =Office365Users.DirectReportsV2("特定部署上司のメルアド").value
```
↓みたいなのでも良い。
```
[
    {name:"Aさん",mail:"a@hogehoge.com"},
    {name:"Bさん",mail:"b@hogehoge.com"},
    {name:"Cさん",mail:"c@hogehoge.com"}
]
```

２．このままだと`SubmitForm`した際にユーザー列と型が違って保存されないので、カードコントロールの`Update`プロパティをユーザー列が受けいれてくれる書式にしておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/ecb2a507-4068-e913-9ab9-59976cb4be82.png)

```
Update: ={
    Claims:"i.0#.f|membership|"& DataCardValue1.Selected.mail
}
```

ユーザー列は`JobTitle`や`Picture`等、他のKeyも持ってるけど`Claims`だけ指定すれば受け入れてくれる。

## 所感
コンボボックス非常に便利だけど不可解な挙動しがちなので落ち着いて欲しい。。。
ヴァンダービルト大学のPrompt Engineering for ChatGPTの講義を終わらせた感想

## 概要

オンライン講義のCourseraでヴァンダービルト大学のPrompt Engineering for ChatGPTの講義を終わらせました。ヴァンダービルト大学はアメリカ合衆国テネシー州ナッシュビルに位置する名門私立大学です。1873年に設立され、慈善家で鉄道王として知られるコーネリアス・ヴァンダービルトによって寄付を受けたことから、その名が付けられました。


Prompt Engineering for ChatGPTは3つのコースから成っています。
・Prompt Engineering for ChatGPT：基本的なpromptの書き方。
・ChatGPT Advanced Data Analysis：コードインタープリタ(当時)の使い方
・Trustworthy Generated AI：AIを使うことに対する倫理観など

個人的には、promptの書き方のレベルが上がり、有意義な時間を過ごせました。特に生成された結果に対して、懐疑的な質問を投げかけて、更に精度を上げる方法が良かったです。

あと、「AIはカンニングやズルをするために使うと短期的には利益を得られるが、長期的には自分に不利益になる」という言葉は印象的でした。

リンク：https://www.coursera.org/learn/prompt-engineering?specialization=prompt-engineering

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36629/f6987f81-654c-bcc4-fb08-53fcd21adcac.png)

## コース全体の概要
こちらは、GPT4oを使って要約しています。

このコースでは、Generative AIを利用して人間の創造性や批判的思考を強化する方法を学びます。コース終了時には、Generative AIを「心の外骨格」として使用する技術を身につけることができます。実践的な講座を通じて、大規模言語モデルの能力を活用し、仕事、教育、日常生活での生産性を向上させるスキルを習得します。初級から始まり、プロンプトエンジニアリングの高度なスキルへと進みます。このスペシャリゼーションを修了することで、以下のような様々な自動化や知能増強アプリケーションでモデルの推論能力を活用できるようになります：

・書作成やアウトライン作成を10倍速で行う
・問題解決の新たな方法をブレインストーミングする
・複雑なイベントや旅行、プロセスの計画を行う
・Excelデータから自動的にPowerPointプレゼンテーションやビジュアライゼーションを生成する
・PDFやドキュメントからの重要情報を抽出する
・トランスクリプトやビデオからマーケティングコンテンツを生成し、特定の顧客にパーソナライズする

## Prompt Engineering for ChatGPTコース

ChatGPTのような大規模言語モデルを効果的に使用するためのプロンプトエンジニアリングの適用方法

プロンプトパターンを使用して、大規模言語モデルの強力な機能を利用する方法

生活、ビジネス、または教育用の複雑なプロンプトベースのアプリケーションを作成する方法

## ChatGPT Advanced Data Analysisコース

ChatGPTコードインタープリタで仕事や生活のタスクを自動化

PDF、PowerPoint、Excel、画像、動画などの読み取りと作成を自動化

## Trustworthy Generative AIコース

ジェネレーティブAIで解決する意味がある問題とは？

Generative AIからより信頼できる結果を得るための問題の組み立て方とエンジニアの促し方
go-redis/cacheの使い方

Redisバックエンドのキャッシュライブラリ、[go-redis/cache](https://github.com/go-redis/cache)についてまとめました。

このライブラリの良さそうなところ:point_up:
- ローカルキャッシュ(多層キャッシュ)がサポートされている
- Onceメソッドが便利

## 初期化
[redis/go-redis](https://github.com/redis/go-redis)のクライアントを渡して初期化します。

```go
func newCache() *cache.Cache {
	addr := fmt.Sprintf("%s:%s", os.Getenv("REDIS_HOST"), os.Getenv("REDIS_PORT"))
	client := redis.NewClient(&redis.Options{
		Addr: addr,
		DB:   0,
	})
	return cache.New(&cache.Options{
		Redis:      client,
	})
}
```

## 基本操作

```go
const testKey = "go-redis-cache-test-key"

type TestObject struct {
	ID   int
	Name string
}

func TestGoRedisCache(t *testing.T) {
	c := newCache()
	ctx := context.TODO()

    // ===== (1)Set =====
	err := c.Set(&cache.Item{
		Key: testKey,
		Ctx: ctx,
		Value: &TestObject{
			ID:   1,
			Name: "TEST",
		},
		TTL: time.Hour, // キャッシュ有効期間
	})
	assert.NilError(t, err)

    // ===== (2)Get =====
	var want TestObject
	err = c.Get(ctx, testKey, &want)
	assert.NilError(t, err)
	t.Log(want) // {1 TEST}

    // ===== (3)Exists =====
	exists := c.Exists(ctx, testKey)
	t.Log(exists) // true

    // ===== (4)Delete =====
	err = c.Delete(ctx, testKey)
	assert.NilError(t, err)

	exists = c.Exists(ctx, testKey)
	t.Log(exists) // false
}
```

## ローカルキャッシュ[^1]

[^1]: ローカルキャッシュ(多層キャッシュ)については、[こちら](https://tech.gunosy.io/entry/go-multi-layered-cache-implementation)の記事の説明がわかりやすいと思います :bow: 


`go-redis/cache` では、オプションでローカルキャッシュを設定できます。
ローカルキャッシュを使う場合、初期化時に指定します。

```diff_go
	return cache.New(&cache.Options{
		Redis:      client,
+       LocalCache: cache.NewTinyLFU(1000, time.Minute),
	})
 ```

 このライブラリで用意されてるローカルキャッシュは、[TinyLFU](https://github.com/vmihailenco/go-tinylfu)というインメモリキャッシュですが、インターフェースを満たせば他のアルゴリズムでローカルキャッシュを実装することも可能です。

 ```go
 type LocalCache interface {
	Set(key string, data []byte)
	Get(key string) ([]byte, bool)
	Del(key string)
}
```

## Onceメソッド
`go-redis/cache`の`Once`メソッドは、指定されたキーに対してキャッシュされた値を取得するか、キャッシュに値が存在しない場合は引数で指定した関数を実行してその結果をキャッシュし、同時にその結果を返すメソッドです。

```go
	cache := newCache()
	var want TestObject
	err := cache.Once(&cache.Item{
		Key:   testKey,
		Value: &want,
		TTL: time.Hour, // キャッシュの有効期限
		Do: func(*cache.Item) (any, error) {
            // 実際にはここでDBから値を取得する
			return &sqlc.Member{
				ID: 1,
    			Name: "TEST",
			}, nil
		},
	})
	assert.NilError(t, err)
 	t.Log(want) // {1 TEST}
```

シンプルな要件であれば、このOnceメソッドだけでキャッシュ機能を十分に実現できそうです。

このメソッドは、Goのsingleflightパッケージを利用しており、複数の呼び出し元から同時に同じキーに対するリクエストがあった場合に、最初のリクエストが完了するまで他のリクエストが待機する仕組みになっています。これにより、キャッシュが期限切れとなった際に一斉にバックエンドにリクエストが殺到するのを防ぐことができ、システムの負荷を軽減する配慮がされています。

## おわり
キャッシュライブラリ[go-redis/cache](https://github.com/go-redis/cache)についてご紹介しました！すでにgo-redisを導入している場合、簡単にキャッシュ機能を追加できるため、試してみる価値はありそうです。両ライブラリは同じ組織によって開発されてるので、相性もいいと思います（多分）。

また、今回は試せてませんが、go-redis/cacheはOpenTelemetryによるモニタリングもサポートしているようなので、キャッシュのヒット率を調べてチューニングしたい場合にも一手間省けて良いのでは無いでしょうか:grinning:
生成AIプロンプトエンジニア検定を受けてみた

# はじめに

昨年は生成AI元年と呼ばれ、ChatGPTをはじめとした、様々な生成AIサービスが注目されました。

今後はシステム開発において、要件定義から実装・テストまで、多様な観点から、AIを活用する流れになるかな、と感じています。

私は昔、ディープラーニングのG検定に合格していたのですが、先日AI関係の資格を調べたところ、新しいものがいくつか登場してきたので、受験していくことにしました。その第一弾が、「生成AIプロンプトエンジニア検定」です。

# 生成AIプロンプトエンジニア検定とは

以下に紹介されていますが、生成AIプロンプト研究所というところが提供している検定です。

https://exp-p.com/aitest

プロメトリックのような組織を通しているわけではなく、一民間企業が独自に作った検定のため、情報処理技術者試験ほどの権威性があるわけではありません。

ただし、個人的には、このような理解度チェックの仕組みが提供されていることはありがたいと感じました。本を読んで終わりだと、自分が本当に理解できたのか分からないので。

ちなみに、受験料は無料（公式テキストを買う必要がある）であり、合格したら、証明書をPDFでもらえます。

# プロンプトエンジニアリングとは

以前、firebaseを使ったプログラミングをした時に、ChatGPT（バージョンはおそらく4）に聞きながらやっていたのですが、トンチンカンな回答をされることが多かったです。:sweat_smile:

その時は、AIってまだまだこんなものかな、と思っていたのですが、この本を読んだところ、どうやらAIとの会話にもコツがあるのだということがわかりました。

**ChatGPTは流暢に返答するので、つい、人間相手にチャットする時のように書いてしまうのですが、どうやら、それだと欲しい回答が得られないようです。**

肝心のそのコツについてはテキストに書かれているのですが、同時にネットでも公開されているので、リンクを貼っておきます。

https://exp-p.com/account/6997/article/168

# 絵を描いてみる

上記の公式ですが、私は頭の中で絵を描いて覚える癖があるので、備忘録も兼ねて、ここに描いてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680908/9abf04ad-537e-fc54-34c9-bc71f287c0cf.png)

# 最後に

次は10月に「生成AIパスポート試験」を受けます！

https://guga.or.jp/outline/
【ABC367】コンテストメモ【AtCoder】

## はじめに

自分が参加した「AtCoder Beginner Contest」の感想をまとめていきます。

:::note
使用言語はC++
:::

:::note
「未着手」は手を付けていない問題
「未提出」は手を付けたけれど提出はしていない問題
:::

## 結果

- 順位: 7200th / 12999
- 点数: 600点
- 時間: 82:37
- pef: 410相当
- R: 327 → 335 (+8) Highest更新！
- 完問数:3完 ABC

## 問題別評価

### A問題

- AC 7:13
- [実行結果](https://atcoder.jp/contests/abc367/submissions/56783081)

日付をまたいで寝る時と日付を**またがない**で寝るときとで処理が変わるため注意が必要

### B問題

- AC 9:30
- [実行結果](https://atcoder.jp/contests/abc367/submissions/56786912)

C++であれば入力をそのまま出力するだけでよい。

### C問題

- AC 82:37
- [実行結果](https://atcoder.jp/contests/abc367/submissions/56826065)

解くのに時間がかかってしまったが分かってしまえばとても簡単な問題だった。日々の精進が足らないなと反省。


### D問題
- 未提出

累積和っぽさは感じていたものの実装方法がわからず断念。

## 総評・まとめ

茶pefではあるもののC問題で足踏みしてしまったことは反省。灰色、茶色の問題はサクッと解けるように日々精進しようと思います。
【Pal2Discord】PalworldとDiscordのチャットを連携するアプリ作ってみた

# 概要
閲覧ありがとうございます！

DiscordからPalworld鯖を操作するアプリは見かけたのですが、チャットを連携させるアプリを作っている人はいなかったので今回作ってみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564700/a6166b16-f29d-36ca-78f5-9981b1ff0ef9.png)

https://github.com/natunayu/pal2discord

(マインクラフトとかだとよく使われているイメージ)


# 仕組み
Palworld自体にはもともとシステムログを保存する機能がありません。
そのため、journaldを叩いて最新のログを書き出しログファイルを生成→内容をフィルタリングしてDiscordへ送信 という流れで処理しています。
DiscordからのメッセージはRestAPIでワールドへ転送しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564700/da91a3a9-ad24-8231-8827-83c597b4cc3d.png)


# 準備
### 1. 専用サーバの構築とSystemdへの登録
大前提として、Palworldのサーバをデーモン化する必要があります。
こちらの記事を元に専用サーバを構築すると、後で設定が楽になります。

https://qiita.com/naoya-i/items/e907a6b949e5da36d532

### 2. ログの出力先設定と権限付与
#### ログの保存先設定
journaldのログはデフォルトでは揮発性領域へ保存するため、リブートすると破棄されます。
```/var/log/journal``` にディレクトリを作成することで、自動的に保存先が変更されます。

```ruby
mkdir -p /var/log/journal
```

journaldに関する詳しい記事
[journaldの詳しい説明](https://qiita.com/thaim/items/5d0cc595fce4ac0858e4 "journalログをきちんと保存する")

#### 権限付与
このままだとアプリケーション側からログファイルへアクセスできないのでアクセス権限を設定します。
また、journalctlを実行するためにユーザへjournalの実行権限を与えます。

:::note warn
仮想環境だとsudo pythonができないための処置です。
もし仮想環境を使わないのであれば、以下の設定は必要ありません。
:::



```ruby
# 権限付与
sudo chmod 777 /var/log/<palworld service name>.log

# ユーザへjournalctlの許可
sudo usermod -aG systemd-journal <username>
```

### 3. RestAPIの許可

https://tech.palworldgame.com/ja/api/rest-api/palwold-rest-api/

```Steam/palworld/Pal/Saved/Config/LinuxServer``` にある ```PalWorldSettings.ini``` からRestAPIを許可することでAPIを叩く事ができるようになります。
```RESTAPIEnabled=True``` にしてください。 


### 4. Pal2Discord のインストール
こちらからダウンロードしてください。

https://github.com/natunayu/pal2discord

環境に合わせてrequirementsを使ってください。
```
pip install -r requirements.txt
```

### 5. Settings.iniの設定

次に```Settings.ini```の設定を行ってください。
未入力があるとエラーになります。

```ini
[default]
; discord botのtoken
token = 
; palworldと交信する専用チャンネルのID
channel_id = 
; logファイルのディレクトリ
logs_path = /var/log/ 
; palworldサーバのサービス名
service_name = palworld-dedicated      

[restapi]
restapi_port = 8212
restapi_user = admin
restapi_passwd = ; adminpasswd
```

### 6. 実行
```python run.py```


# 機能
設定したチャンネルでチャットができる以外に以下の機能が使えます。
鯖の起動に関する機能は追加しなかったのですが、時間があったらパーミッション設定の追加とともに鯖の再起動などもできるようにしようと考えています。

```
コマンド一覧:
!list ログインプレイヤー一覧
!info      サーバ情報
!metrics   サーバ状態
!settings  サーバ設定
!phelp     ヘルプ
```

# おわりに
意外と外でゲーム内の人とやりとりできるのって便利なんですよね。
〇時からレイドいこーとか、昨日○○集めておいたよーとか。

少しでもパルワールドが盛り上がる一因になったら嬉しいなと思っています。
閲覧ありがとうございました！
統計学の中心極限定理の理解を深めるためのPythonコード

## 概要
中心極限定理（Central Limit Theorem, CLT）は、統計学や確率論で非常に重要な概念です。この定理は、どんな母集団分布からのサンプルでも、そのサンプルの平均が十分に大きい場合、分布が正規分布に近づくというものです。本記事では、Pythonを用いて中心極限定理を視覚的に理解するためのコードを紹介します。元の分布として複数の異なる分布を混合し、それらのサンプル平均が徐々に正規分布に近づく様子を観察します。文章とコードはChatGPT4oで作成しています。


## コード全文
以下は、中心極限定理を視覚化するためのPythonコードです。元の分布として複数のランダムな分布を混合し、そのサンプル平均がどのように正規分布に近づくかを確認します。

```python
import numpy as np
import matplotlib.pyplot as plt

# 元の分布として複数の分布を混合
np.random.seed(0)  # 再現性のためのシード
n_samples = 10000  # サンプルの数
sample_size = 50   # 各サンプルのサイズ

# 異なる分布を組み合わせて混合分布を作成
distribution1 = np.random.exponential(scale=2.0, size=(n_samples, sample_size))
distribution2 = np.random.gamma(shape=2.0, scale=2.0, size=(n_samples, sample_size))
distribution3 = np.random.triangular(left=0.0, mode=2.0, right=4.0, size=(n_samples, sample_size))
distribution4 = np.random.normal(loc=3.0, scale=1.5, size=(n_samples, sample_size))
distribution5 = np.random.beta(a=2.0, b=5.0, size=(n_samples, sample_size)) * 6  # スケール調整

# よりランダムな混合分布を作成
distribution = 0.2 * distribution1 + 0.2 * distribution2 + 0.2 * distribution3 + 0.2 * distribution4 + 0.2 * distribution5

# 平均を取り出す回数のリスト
mean_iterations = [100, 500, 1000, 5000]

# 図の設定
plt.figure(figsize=(15, 12))

# 元の混合分布のヒストグラム
plt.subplot(3, 2, 1)
plt.hist(distribution.flatten(), bins=50, density=True, alpha=0.6, color='blue')
plt.title('Original Complex Mixed Distribution')
plt.xlabel('Value')
plt.ylabel('Density')

# 平均を取り出す回数に応じたヒストグラムを描画
for i, n_means in enumerate(mean_iterations):
    sample_means = np.mean(np.random.choice(distribution.flatten(), size=(n_means, sample_size)), axis=1)
    
    plt.subplot(3, 2, i+2)
    plt.hist(sample_means, bins=50, density=True, alpha=0.6, color='g')
    
    # 理論的な正規分布を重ねる
    mu = np.mean(sample_means)
    sigma = np.std(sample_means)
    x = np.linspace(mu - 3*sigma, mu + 3*sigma, 100)
    plt.plot(x, (1/(sigma * np.sqrt(2 * np.pi))) * np.exp( - (x - mu)**2 / (2 * sigma**2) ), color='red')
    
    plt.title(f'Number of Means = {n_means}')
    plt.xlabel('Sample Mean')
    plt.ylabel('Density')

plt.tight_layout()
plt.show()

```

## 出力結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36629/00e7382f-4c03-6c18-99bb-3c9ad6b68250.png)

## コードのステップ・バイ・ステップの説明
このセクションでは、上記コードの各ステップを詳しく説明します。

### 1.ライブラリのインポートと基本設定:

numpyを使用してランダムな分布を生成し、matplotlibを用いて結果を視覚化します。
np.random.seed(0)で乱数生成のシードを固定し、再現性を確保します。
n_samplesはサンプル数、sample_sizeは各サンプルのサイズです。

### 2.複数の分布を組み合わせた混合分布の作成:

distribution1: 指数分布。
distribution2: ガンマ分布。
distribution3: 三角分布。
distribution4: 正規分布。
distribution5: ベータ分布をスケール調整したもの。
これらの分布を同じ比率で混合し、複雑でランダムな分布を作成します。

### 3. 元の分布のヒストグラム表示:

plt.subplot(3, 2, 1)で元の混合分布を表示します。これにより、サンプル平均を取る前のランダムな分布を確認できます。

### 4. サンプル平均の分布を表示:

mean_iterationsリストにある回数（100回、500回、1000回、5000回）に応じてサンプル平均を計算します。
np.mean()を用いて、各回数でサンプル平均を計算し、その分布をヒストグラムとして表示します。
各ヒストグラムには理論的な正規分布を重ねて表示し、分布がどのように正規分布に近づくかを視覚化します。

### 5. プロットの配置と表示:

plt.tight_layout()を使用してプロットのレイアウトを調整し、プロットが重ならないようにします。
最後に、plt.show()で全てのプロットを表示します。

## おわりに
このコードを使うことで、中心極限定理の概念をより直感的に理解できるはずです。ランダムな分布からサンプルを取り出し、その平均がどのように正規分布に近づくかを視覚的に確認することで、理論だけでは得られない深い理解が得られるでしょう。
５０代女子？がゼロから始めるエトセトラ-Kali導入して最初にしたこと

はじめて、Qiitaに投稿します
５０代の女子？（おばさんは嫌だな）がゼロから始めるエトセトラ

間違いがあったら教えてください

# メモリの追加
2Gから4Gへ
パスワードクラックするときはこれくらいあれば大丈夫かな？

# rootとしてログインできるように設定する
~~~
$ sudo su
# passwd root
New passwrd:
Retype new password:
passwd: password updated successfully
~~~

# キーボードの設定
日本語配列のキーボードレイアウトにする
~~~
ドラゴンマーク(ウィンドウ左隅のマーク）
→　Settings　→　Keyboard　→　Layoutタブ
→　Use System default」のチェックを外す 
→　+Add　→　Japaneaseを選択　→　English(US)を選択
→　Remove
~~~

# 時間の設定
 日本時間にする
~~~
$ timedatectl set-timezone Asia/Tokyo
~~~

# 自動ロックの解除をする
Kaliを放置していても自動ロックにはならないようにする
~~~
ドラゴンマーク
→　PowerManager　→　Displayタブ　→　Display power managementをOFF
→　Securityタブ　→　Automatically lock the sessionをNeverに変更
→　Lock screen when system is going to sleepのチェックをはずす
~~~

# ターミナルの設定
terminatorが好き
tmuxを使ってみたいと思うけど、ちょっとよくわからない
~~~
$ sudo apt-get install terminator
~~~
~~~
ドラゴンマーク　→　Settings→Default Application　
→　Utilitiesタブ　→　Terminal EmunlatorでTerminatorを選択
~~~

# スナップショットを作成

今日はここまでです
ARM版Windowsで近似最近傍探索ライブラリfaissが使えなかった話

# 経緯

先日、今後の知見向上も兼ねて、ノートPCの買い替えで、Snapdragon X EliteのARM版WindowsPCを購入。

RAGを試すためのコードをpythonで、faissで書いていたのですが、動かなくなり、最終的にAnnoyを使用することにしたので備忘録。

slackもzoomも、ARM用のアプリケーションを出しているし、大企業が提供するライブラリは、当たり前に、ARMでも簡単に使えると思っていましたが、考えが甘かったです。


# 近似最近傍探索ライブラリについて

試したのは下記の3つ。できるだけ大手のものを試そうと。

下記は、Perplexityのまとめです。

:::note info

Annoy、Faiss、ScaNNのどれが優れているかは、具体的な用途や要件によって異なります。以下にそれぞれの特徴をまとめて比較します。

Annoy
- 特徴: AnnoyはSpotifyによって開発されたライブラリで、高次元空間での近似最近傍探索に特化しています。ツリー構造を利用して高速な検索を実現し、特に大規模なデータセットにおいて効率的です。
- 利点:
    - メモリ効率が高く、軽量
    - 簡単に統合可能
    - 静的ファイルとしてインデックスを扱える
- 欠点:
    - GPUのサポートがない
    - バッチ処理のサポートがない
    - インクリメンタルなデータ追加ができない

Faiss
- 特徴: FaissはMeta（旧Facebook）のAI研究チームによって開発されたライブラリで、密なベクトルの類似性検索とクラスタリングに特化しています。大規模なデータセットの処理に優れ、GPUを利用した高速処理が可能です。
- 利点:
    - 高性能で、GPUアクセラレーションによりさらに効率的
    - 大規模なベクトルセットを扱うのに適している
    - オープンソースで広く利用されている
- 欠点:
    - 主にベクトル操作に特化しており、他のデータベース操作には不向き
    - 技術的な知識が必要

ScaNN
- 特徴: ScaNNはGoogle Researchによって開発されたライブラリで、大規模データセットに対する近傍探索を効率的に行います。TensorFlowと相性が良く、高精度なベクトル検索を提供します。
- 利点:
    - 高性能で、TensorFlowと統合しやすい
    - 大規模データセットに効率的
- 欠点:
    - セットアップとチューニングが複雑

結論
どのライブラリが最適かは、以下の要素に依存します。
- 速度と精度: FaissはGPUを活用した高速な処理が可能で、精度も高いです。Annoyは軽量で高速ですが、精度が若干劣る可能性があります。ScaNNは高精度な検索が可能ですが、設定が複雑です。
- スケーラビリティ: FaissとScaNNは大規模データセットに対してスケーラブルです。Annoyはメモリ効率が高いですが、非常に大きなデータセットには不向きです。
- 使いやすさ: Annoyは簡単に統合でき、軽量なアプリケーションに適しています。FaissとScaNNはより高度な設定が必要です。

用途や環境に応じて、これらのライブラリの中から最適なものを選ぶと良いでしょう。

:::

# 結論


faissは、ImportError: cannot import name '_swigfaiss_avx2' from 'faiss'を解決できず。

ScaNNは、jitterや、tiktokenにエラーが出て、コツコツ解決していきましたが、最終的に、AttributeError: module 'scann' has no attribute 'ScannBuilder'を解決できず。




最終的には、Annoyでうまくいきました。性能や精度はこれから試してみます。
【豆知識】has_manyの設定について少し理解

# はじめに
アプリ作成課題のなかで都道府県に関するモデルファイル作成中、`has_many`について少しわからなくなってしまったので、調べて学んだことをアウトプットしたいと思います。

## 環境
- Windows, WSL
- Docker
- Ruby 3.2.3
- Rails 7.1.3


## 疑問に思ったこと
### 1:`has_many :users`が必要かどうか
```ruby
class Prefecture < ApplicationRecord
  has_many :posts
end
```

都道府県に関するモデルファイルが上記のようになっているがここにhas_many :usersは不要かがわからなくなりました。
ついでにファイルを行ったり来たりしているのもありだんだんとコードの意味があいまいに💦


### 2：ますはコードの意味から

- **`has_many :posts`**:
    - `Prefecture` モデルは、`Post` モデルと一対多の関係を持っています。
    - つまり、1つの `Prefecture` に対して、多くの `Post` が関連付けられることを示しています。
    - 例えば、東京都に関連するすべてのポストを取得することができます。


### 3：では次に`has_many :users` の必要性について

- **`has_many :users` の追加**:
    - `Prefecture` が `User` モデルと関連している場合、`has_many :users` を追加する必要があります。
    - 現在のポストモデルの定義には、`Prefecture` から `User` への関連が明示的には含まれていません。
    - 一般的に、都道府県（`Prefecture`）はユーザー（`User`）に直接関連しないため、`has_many :users` は通常不要です。

### 5：`has_many :users` を追加すべきか

- **必要な場合**:
    - もし `Prefecture` モデルが `User` モデルと一対多の関係を持つ場合（例えば、各都道府県に複数のユーザーが属しているなど）、`has_many :users` を追加する必要がある
- **不要な場合**:
    - 現在のコードに `has_many :users` を追加する必要がない場合が多い。ポストモデルの定義や仕様に基づくと、ユーザーと都道府県が直接関連しているわけではないため、`has_many :users` は不要


### 6：私の見解があっているか確認してみる

路線名で検索をかけた時はユーザーからではなくあくまでポストに記載されいる路線名をサーチして該当する路線名がかかれたポストの一覧を表示するのであって、路線名が複数のユーザーを持っているわけではないという事であっているのか？

A：正しい

### 7：あらためて路線名での検索の意図

- **ポストに記載される路線名**:
    - ポストモデルに `line` という属性があり、そこに路線名が記載されます。
    - 路線名で検索をかけると、ポストモデル内の `line` 属性を対象に検索します。
    - つまり、ユーザーに関連する路線名ではなく、ポスト自体に含まれる路線名に基づいて検索が行われます。


### 8：検索の仕組み

- **検索処理**:
    - ポストモデルのスコープ `search_by_line` を使用して、ポストの `line` 属性を部分一致で検索します。
    - これにより、指定された路線名が含まれるポストの一覧が表示されます。

### 9：ユーザーとの関連性

- **ユーザーと路線名**:
    - `line` 属性はポストに関連しており、ユーザーと直接的な関係はありません。
    - ユーザーが複数のポストを作成する可能性があるが、路線名がユーザーに直接関連するわけではありません。


### 10：コードの確認

ポストモデルのスコープ `search_by_line` を確認してみる

```ruby
scope :search_by_line, ->(line_name) { where('line.name LIKE ?', "%#{line_name}%") if line_name.present? }
```
このスコープは、ポストの `line.name` 属性を検索対象としており、ユーザーとは関係ないことがわかる


### まとめ
- **検索対象**: ポストモデルの `line` 属性（ポストに記載されている路線名）
- **検索結果**: 指定された路線名が含まれるポストの一覧
- **ユーザーとの関係**: ユーザーは路線名検索に直接関与しない


## さいごに
不要なコードはなるべくなくしたいし、エラーが発生しないようにもしたい。自分の見解が正しいかいろんなサイトをみたりGPTを利用するなど、様々な手段でコードを誰にでもわかるように作成していきたいです。
今回の記事が何か参考になれば幸いです。
動くWebデザインアイデア帳のコードを試してみた

# サマリ
動くWebデザインアイデア帳のコードを試してみました。

# 背景
自分でHTMLやCSSを書いてWebページ作りたいと思って早数年、、
気になっていた[動くWebデザインアイデア帳](https://coco-factory.jp/ugokuweb/)さんのコードを
ついに使わせていただくことにしました。

# ゴール
サンプルコードをローカル環境にコピーし、ブラウザで動作することを確認する。

# 対象読者
- かっこいいWebページを作りたいけど実装方法がわからない人
- とにかくできたという経験を積みたい人

# 前提
必須：ブラウザ、テキストエディタ
推奨：基本的なHTML,CSS,Javascriptの知識
# 環境
- ホストOS：Window10 Home
- ブラウザ：Google Chromeバージョン: 127.0.6533.120（Official Build） （64 ビット）
# そもそも

https://coco-factory.jp/ugokuweb/

そもそも動くWebデザインアイデア帳とは、
> 「動くWebデザインアイデア帳」は、デジタルハリウッドSTUDIO 講師の久保田涼子と杉山彰啓がjQueryやCSSアニメーションをはじめたばかりの方へ向けて、近年のウェブサイトで利用されている基本的な動きをまとめたサイトです。

> 「サイトに動きをつける時、同じ内容を何回も検索をしてソースコードを探している」
「サイトで見つけたソースコードをそのままコピペしてみたけど、動かない」
「JavaScript の本を購入してみたが、実際のサイトにどう組みこめばいいか具体的なイメージがわかない」
「動きの原理を最低限理解して、とにかく早く実務にいかしたい」

> スクールで教えていると、このような声をたくさんいただきます。
「必要な情報がひとつにまとまっていて、講師が受講生さんに教えるために便利なサイトがあればいいな」という気持ちでつくりました。

> 1 つの動きを実現する方法は様々ありますが、なるべくわかりやすい方法を選んでいます。
サイトを利用して「動いた！嬉しい！」という気持ちを、
その後のさらなる動きの仕組みへの探求心につなげて頂ければ幸いです。

（[公式ページ](https://coco-factory.jp/ugokuweb/about/)より引用）


めちゃくちゃいいサイトすぎます…！

ただ、なんと本日（2024/8/31）に一般公開は終了し、
以降は書籍購入すれば見られるということで、
たまたま一般公開最終日に滑り込むことに成功（？）しました。
また書籍は購入したいと思います。

# 試してみた

手順は、公式ページから好きな機能・デザインのページに遷移し、
そのコードを自分の環境で試す（html,css,javascriptのファイルを作ってコピペする）だけです。

利用規約でも商用・非商用にかかわらず基本的には使用してよいとのことであまりにも良心的すぎます。。
（詳細は[公式ページ](https://coco-factory.jp/ugokuweb/termsofuse/)を参照ください）

機能と

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/cbd4a9a2-fecd-c42c-41ec-174fffe67009.png)


印象で

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/0489c8df-3c03-32a1-fc73-715a086c470c.png)

分かれていて、自分がやってみたいものを選択することでコードがあるページに遷移できます。
（すごすぎる。。


ということで、さっそく試してみます。

#### プログレスバー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/df5936be-b4df-df84-e995-36f1dc7a7b93.png)

おお、表示できた…！

サンプルコードについて、以下のように<!--自作のJS-->と書いている部分も動くWebデザインアイデア帳のソースで書かれていますが
（デモで動くようにだと思いますが）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/302f4e1b-3cb6-a4a8-e45f-8cc9f5971fab.png)

もちろんこのままでも動くWebデザインアイデア帳のリソースにアクセスしに行くので動きますが
（8/31以降はできないかもしれません）
今回この部分を自分のローカルファイルのパスに書き換えました。

#### ハンバーガーメニュー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/1f43afb9-3d91-88f4-cbe7-a528d4d5d68b.png)

おぉ…！あの憧れのハンバーガーメニューがローカル環境で…（感動しすぎ
当たり前ですがコピペするだけなので簡単にできます。

#### 液体シェイプ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/532c20e0-6a5c-7ff9-0b5f-fe4cd85504ac.png)

画像なのでわかりませんが、黄色い丸の形がうねうねと変わります。
これHTMLとCSSだけなんですね、すごい…！

#### 波打つ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335813/d5ef0967-9043-a38c-3fe9-1dee6422abee.png)

こんな感じの波打つ動きも簡単に表現できました。


# 結果
4つのパターンを試して実際に動かすことが出来ました。

# まとめ
薄っぺらい内容になってしまいましたが
まずは自分の環境で動くということの楽しさを実感できましたので良しとします。（おい
最近は生成AIの普及により自動でコード生成もできるようになってきていますが、
自分でやる楽しさや仕組みを理解するということも大事かと思うので、
引き続き利用させていただきながら勉強していきたいと思います。
VSCodeのContinueからPerplexity APIを使う

「DifyからPerplexity APIを使う」の記事の続編です。

https://qiita.com/inakano_ojisan/items/5a020d612ce48f8cc234

## Continueとは
2023年の暮れでしょうか。
VSCodeの拡張機能であるGitHub Copilotを無料で1ヶ月試したのですが、チャットでのコーディングがとても便利で驚いた記憶があります。

https://github.com/features/copilot

GitHub Copilotは個人利用であっても、有料プランしか無いです。
お金が掛かるので、代替えツールが無いか探していました。
そこで見つけた拡張機能がContinueです。

https://www.continue.dev/

これは無料である上に、色々なモデルを登録して、用途に応じて切り替えながら使えます。
しかも完全なオンプレミスで使えます。

## Continueの使い方

詳しくは割愛しますが、以下の流れです。

```mermaid
graph TD
    A[拡張機能Continueをインストール] --> B[好きなモデルのAPIを登録]
    B --> C[チャットからプロンプト入力など]
```

## モデルの選定
メジャーなのはOpenAIのgpt-4oかと思います。
しかし、従量料金制なのでお金がやや心配です。

お金を掛けずにやりたい方は、Ollamaと、ローカルLLMの組み合わせになるかと思います。コーディングが得意なモデルを使うと良いと思います。
そして、外部にデータを漏らしたくないが、生成AIを使ってチャットしながらVSCodeでコーディングしたい、といった要件を満たしてくれます。

https://qiita.com/Tadataka_Takahashi/items/0485159e444056892529

ここで紹介するPerplexity APIをContinueで使うメリットは、何といってもインターネットの情報を元にコーディングができる点でしょうか。
なので、たとえばリリースされたばかりの新機能を、いきなりチャットでコーディングしてもらう事が出来たりするのかなと想像します。

## Perplexity APIの登録方法
モデルの登録方法は幾つかありますが、今回はconfig.jsonを直接編集する方法で進めます。

Continueの画面の下の方にある歯車ボタンを押します。

![スクリーンショット 2024-08-31 19.38.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202767/b54a0b34-d0c0-caaa-8269-74fced50375e.png)

config.jsonの"models"へ、以下を追記します。

```json

    {
      "title": "llama-3.1-sonar-small-128k-online",
      "model": "llama-3.1-sonar-small-128k-online",
      "systemMessage": "あなたはソフトウェア開発のエキスパートです。あなたは親切で簡潔な回答をします。",
      "contextLength": 127072,
      "apiBase": "https://api.perplexity.ai/",
      "apiKey": "pplx-f************9b",
      "completionOptions": {
        "temperature": 0
      },
```

systemMessageはシステムプロンプトになります。ここでは出力結果が良くなるような呪文を記述しておきます。

プログラムコードはかなり長いケースがあります。
そこでcontextLengthは、最大の127072としています。

apiKeyは適宜変更してください。

コーディングの場合はtemperatureをなるたけ低くすることで、硬いコードを生成してくれる傾向があります。
completionOptionsで、temperatureを0としています。

他にも色々なオプションがあり、下記に記されています。
自分好みにカスタマイズすると面白いかと思います。
https://docs.continue.dev/reference/config

## 動作確認
現在、2024年8月31日です。
先日2024年8月27日にStreamlitのバージョン1.38.0がリリースされました。
バージョン1.38.0で新たにPolarsデータフレームがサポートされました。
Polarsデータフレームを使ったStreamlitのサンプルコードをPerplexity APIのllama-3.1-sonar-small-128k-onlineを使って生成してみます。

```text
streamlitのバージョン1.38.0でサポートされた
データフレームPolarsを使ったサンプルコードを生成する
```

![スクリーンショット 2024-08-31 19.16.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202767/5ad42f4d-c764-a641-f163-4865410e2379.png)

無事生成されたましたので、実行してみます。

![スクリーンショット 2024-08-31 19.18.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202767/29e27cb0-b4ad-9921-71c5-12260dd86fb3.png)

一発で動きました！

まあデータフレームなのでPandasさえ知っておけば、特にチャットでなくても良いのですが。

## 最後に
ContinueからPerplexity APIを使う最大の目的である、最近出たばかりの新機能をチャットでコーディングしてみました。

もっとどえらい新機能が出てきた時に、Perplexity APIの実力を試してみるのも良いかもしれません。
STM32 VS Code Extension with macOS

完全に私のメモですが...

- macOS Monterey 12.7.6
- VScode Version: 1.92.2 (Universal)

https://marketplace.visualstudio.com/items?itemName=stmicroelectronics.stm32-vscode-extension

導入する。ドキュメントに従い、以下もインストール
- STM32CubeMX
- STM32CubeCLT
- ST-MCU-FINDER

機能拡張の設定 私はこんな感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/b202544a-1725-a4d2-e41c-9db2a6ce68cf.png)

コピペ用

`/opt/ST/STM32CubeCLT_1.16.0`

STM32CubeMXを使って、プロジェクトを保存。ドキュメントにあるように、ToolchainはCMakeを指定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/cb8d2350-5cb0-4580-40d5-dbf305e1ffc0.png)

Import CMake project を選び、プロジェクトを開く。コードを修正。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/a652435c-1a70-0433-fc63-eaf0e59113c9.png)

CMakeの設定をする。ドキュメントに書いてある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/9f7b29db-3ef9-f993-9b34-7afad0d63bde.png)

VScode コマンドパレットで以下2つを実行
- `CMake Select Configure Preset` - Debug を選択
- `CMake Add configure Preset` - 誘導に従って選択していく。

ここで左下の Build が押せるようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/e8ca8a98-b645-eae7-2058-668e96fd8716.png)

NUCLEOを接続。ST-LINKのファームが最新であれば、<br>
Run and Debug をクリックして、...ST-Link を選ぶとデバッグができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/e0731928-f3c9-c64b-5804-f3a9f8cf13f3.png)

止めてレジスターの状況も確認できる。やったね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/95155f8b-6621-1968-e625-95a34e3e4198.png)
[Python]SciPyを用いた凸最適化スクリプト

# 目的
SciPyを用いた簡単な凸最適化スクリプトを紹介する。

# 解いている最適化問題
① y = (x1-1)^2 + (x2-2)^2 においてyが最小となるx1とx2を求める・・・厳密解はx1=1, x2=2
② 制約条件 x1 < 0.5, x2 < 3のもとで①の最小化問題を解く・・・厳密解はx1=0.5, x2=2

# 使用する関数
SciPyのminimize()

# 最適化結果
問題なく最適化できている。
① x1, x2: [0.99999999 1.99999999]・・・厳密解はx1=1, x2=2
② x1, x2: [0.5        1.99999999]・・・厳密解はx1=0.5, x2=2

# Pythonスクリプト
``` a01_Scipy_minimize.ipynb
import numpy as np
from scipy.optimize import minimize

#------------------制約なし最適化-------------------
# 目的関数の定義
def objective_function(x):
    return (x[0] - 1)**2 + (x[1] - 2)**2 

# 初期値の設定
x0 = [0, 0]  # 初期値を [0, 0] に設定

# 最適化の実行
result = minimize(objective_function, x0)

# 結果の表示
print("最適解 x1, x2:", result.x)

#------------------制約付き最適化-------------------
# 制約条件の定義
constraints = (
    {'type': 'ineq', 'fun': lambda x: 0.5 - x[0]},  # x1 < 0.5
    {'type': 'ineq', 'fun': lambda x: 3 - x[1]}     # x2 < 3
)

# 初期値の設定
x0 = [0, 0]  # 初期値を [0, 0] に設定

# 最適化の実行
result = minimize(objective_function, x0, constraints=constraints)

# 結果の表示
print("最適解 x1, x2:", result.x)
```
【UnrealEngine】レイアウトが崩れないウィジェットの作り方

## はじめに
UnrealEngineでウィジェットを作るときに、スクリーンサイズが変わってもレイアウトが崩れないように作りたいですよねぇ。
[historiaさんの記事](https://historia.co.jp/archives/5322/)を読んで作り方はわかったのですが、それぞれのウィジェットの意味を自分の中で噛み砕きたくて記事を書きました。

:::note info
historiaさんの方法は直観的で、UI初心者には実装しやすいですが、Xで最適化に関するご意見をいただいたので最後に追記しています。
:::

<font color="gray">※「自分用のメモをちょっと綺麗にして出してる...」くらいのノリなので、わかりづらい部分もあるかもしれません。X(Twitter)なりコメントで質問は大歓迎です。</font>

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しUnrealEngineエンジニア
- WBP初心者

## テーマ
レイアウトの崩れないウィジェットの作り方を理解しよう
👉ウィジェットの最適化の話もいただけたので追記

## 結論
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115955/e44f5f45-37bb-30d7-5cf9-9d65e98d75c5.png)

ポップアップなどのひとまとまりごとに、
- Overlay
    - SizeBox
        - ScaleBox
            - Overlay
                - コンテンツの中身を格納する

こういう階層構造にしたら使い勝手が良かったです。

## 詳細

### Overlay
子ウィジェットを複数格納できます。
PaddingとAlignmentによって、位置を決めることができます。
子ウィジェットのサイズについては、子ウィジェット側の設定に基づいて決まります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115955/15f32830-d2d7-b42b-35ab-db55f7bede79.png)


### Size Box
子ウィジェットのサイズを設定できます。
親ウィジェットのOverlayのサイズと1920p*1080pとみなして設定すると期待していた見た目になりました。
これがあることで、下の階層のパーツを丸ごとサイズ管理することができます。
これを挟まないと、「ポップアップを丸ごとサイズ変更したいのに、パーツごとに調整しなきゃいけなくて大変💦」みたいなことが起きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115955/6b0326f0-faa6-3910-545c-660571ead600.png)

:::note info
後に追記しますが、SizeBoxは負荷が高いみたいです。Spacer使ったほうが軽そう
:::

### Scale Box
子ウィジェットのレイアウトが崩れるのを防いでくれます。
これがないと、スクリーンが小さくなった時などのタイミングでUIが崩壊します。


![2024-08-31_18h53_21.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115955/7c24e627-3a65-04b9-4b70-dd01935dbba5.gif)
<font color="gray">↑ ScaleBoxの有無による挙動の違い</font>

### Overlay
この子ウィジェットに、構成パーツを格納しまくったら完成！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3115955/783c35b7-4da9-3eea-3dca-7518ab9ccb8b.png)


:::note info
ちなみに、パーツのデザインをPhotoshopなどで作る際は、スクリーンサイズが1920p×1080pの想定で作成して、そのまま出力するのがオススメです。
Overlayに配置する時、image sizeに画像のサイズを設定すれば、画面全体に対しても正しいサイズで配置されて楽ちんです。
:::

<br>

## 追記！最適化の話
記事を公開したところ、最適化の観点のお話をXでいただけました。

https://x.com/o_y_g/status/1829845854234296759

簡単に要点をまとめると、

- そもそもSize Boxは負荷が重い
- Size BoxとScale Boxを組み合わせると、さらに処理負荷が重くなる

ようです。
SizeBoxの代わりにSpacerを使用することが最適化の観点では推奨されているみたいです！

となると、
- Overlay
    - ScaleBox
        - HorizontalBox
            - Spacer
            - Overlay
                - コンテンツの中身を格納する
            - Spacer

とかが良さそうですかね！

<br>

## おわりに
というわけで、レイアウトが崩れないウィジェットの作り方、、、からの最適化のお話でした。
動いたらヨシ！👈🐱⛑
と思っていましたが、ちょっとした工夫でゲームが軽くなるならそれに越したことはないですな！
それでは！

## 参考記事

https://historia.co.jp/archives/5322/

https://shuntaendo.hatenablog.com/entry/2020/11/11/230000

https://dev.epicgames.com/documentation/ja-jp/unreal-engine/optimization-guidelines-for-umg-in-unreal-engine#%E3%82%B5%E3%82%A4%E3%82%BA%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%81%AE%E4%BB%A3%E3%82%8F%E3%82%8A%E3%81%AB%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B5%E3%83%BC%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%80%82
【Python3エンジニア認定基礎試験】9. クラス

9.クラス
---
クラスは、データと機能を組み合わせる方法を提供し、オブジェクト指向プログラミングの基盤となる概念です。
新しいクラスを作成することで、独自の型を定義し、その型に基づいたインスタンスを生成できます。これにより、各インスタンスは自分自身の状態を保持し、その状態を操作するメソッドを持つことが可能になります。

9.1 名前とオブジェクト
---
Pythonにおけるオブジェクトには「個体性」があります。
つまり、同じオブジェクトに対して複数の名前を割り当てることができます。
この概念は「別名付け（aliasing）」として知られています。
Pythonでは、特にリストや辞書などの変更可能な型で、この別名付けが重要な役割を果たします。

9.2 Python のスコープと名前空間
---
クラスの動作を理解するためには、Pythonのスコープと名前空間のルールを知る必要があります。

名前空間: 名前からオブジェクトへの対応付けのこと。Pythonでは通常、名前空間は辞書として実装されます。
スコープ: プログラムのテキスト上で、特定の名前空間にアクセスできる範囲を指します。
Pythonでは、スコープは静的に決定され、動的に使用されます。つまり、プログラムの実行中には、常に入れ子になったスコープの中から最も内側のスコープから順に検索が行われます。

```
def scope_test():
    def do_local():
        spam = "local spam"

    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"

    def do_global():
        global spam
        spam = "global spam"

    spam = "test spam"
    do_local()
    print("After local assignment:", spam)
    do_nonlocal()
    print("After nonlocal assignment:", spam)
    do_global()
    print("After global assignment:", spam)

scope_test()
print("In global scope:", spam)
```

```
After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam
```

このように、do_local()ではローカルスコープ内でのみ変数spamが変更され、do_nonlocal()では外側のスコープの変数が変更されます。そして、do_global()ではグローバルスコープの変数spamが変更されます。

9.3 クラス初見
---
Pythonのクラス定義は、他の多くの言語と同様にclassキーワードを使用して行います。クラスは、関連するデータとメソッドをまとめた一種のテンプレートであり、それを使って新しいオブジェクトを生成します。

```

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>
```

クラス定義を実行すると、新しい名前空間が作成され、そこにクラスの属性やメソッドが格納されます。クラス定義が終了すると、クラスオブジェクトが生成され、定義された名前で結びつけられます。

9.3.1 クラスオブジェクト
---
クラスオブジェクトは、属性参照とインスタンス生成の2つの主要な操作をサポートしています。

```
class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'
```

上記のクラスでは、MyClass.iは整数、MyClass.fは関数オブジェクトを返します。また、クラスのインスタンス化は以下のように行います。

```
x = MyClass()
```

クラスに__init__()メソッドが定義されている場合、インスタンス生成時にこのメソッドが自動的に呼び出され、オブジェクトを初期化することができます。

```
class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart

x = Complex(3.0, -4.5)
```

このように、__init__()メソッドを使って、インスタンスを初期化し、特定の属性を設定することができます。

9.3.2 インスタンスオブジェクト
---
クラスのインスタンスは、データ属性とメソッドという2種類の属性を持つことができます。データ属性は、クラス内で宣言する必要はなく、インスタンス生成後に動的に追加することが可能です。

```
x.counter = 1
while x.counter < 10:
    x.counter = x.counter * 2
print(x.counter)
```

メソッドは、インスタンスオブジェクトに属する関数であり、インスタンス固有のデータにアクセスして操作するために使用されます。

Pythonのクラスとインスタンスは、非常に柔軟であり、動的に属性やメソッドを追加、削除することができます。
また、オブジェクト指向プログラミングの基本的な機能を全てサポートしており、複数の基底クラスを持つことができるなど、高度な継承機能も備えています。

https://qiita.com/FT_log/items/29ef80cd2c294b293b21
【Python3エンジニア認定基礎試験】8. エラーと例外

8.エラーと例外
---
Pythonプログラミングでは、コードを実行する際に発生するエラーには大きく分けて2つの種類があります。それは 構文エラー と 例外 です。

8.1. 構文エラー
---
構文エラーは、コードがPythonの文法に従っていない場合に発生します。構文エラーが発生すると、Pythonはエラーメッセージを表示してコードのどこでエラーが発生したかを示します。

```
while True print('Hello world')
```
このコードは構文エラーを引き起こします。Pythonは、while文の後に:が必要であることを示しています。

8.2. 例外
---
一方、例外は、コードの構文が正しくても、実行時に何らかの問題が発生した場合に生じます。例外は通常、特定のエラーメッセージとともに表示され、プログラムの実行が中断されます。

```
10 * (1/0)
```
これはZeroDivisionErrorという例外を引き起こします。他にも、未定義の変数を使用した場合はNameErrorが、異なるデータ型を不適切に結合しようとするとTypeErrorが発生します。

8.3. 例外を処理する
---
Pythonでは、try...exceptブロックを使用して例外を処理できます。これにより、プログラムが予期しないエラーで停止するのを防ぎ、適切にエラーを処理することができます。

```
while True:
    try:
        x = int(input("Please enter a number: "))
        break
    except ValueError:
        print("Oops! That was no valid number. Try again...")
```
この例では、ユーザーが無効な入力をした場合に例外をキャッチし、再度入力を促します。

8.4. 例外を送出する
---
プログラムの中で明示的に例外を発生させたい場合、raise文を使います。

```
raise NameError('HiThere')
```
これはNameErrorを強制的に発生させます。

8.5. 例外の連鎖
---
例外が別の例外によって引き起こされる場合、その連鎖を明示的に示すためにfrom句を使用できます。

```
try:
    func()
except ConnectionError as exc:
    raise RuntimeError('Failed to open database') from exc
```
この例では、RuntimeErrorがConnectionErrorによって引き起こされたことが示されます。

8.6. ユーザー定義例外
---
Pythonでは、独自の例外クラスを定義することもできます。これは、特定のエラー条件を表現するために便利です。通常、これらのクラスはExceptionクラスを継承して作成されます。

8.7. クリーンアップ動作を定義する
---
try...finallyブロックを使用すると、例外の発生にかかわらず、常に実行されるクリーンアップコードを定義できます。例えば、ファイルを開いた後に必ず閉じる操作などです。

```
try:
    raise KeyboardInterrupt
finally:
    print('Goodbye, world!')
```
このコードでは、KeyboardInterrupt例外が発生した後でもfinallyブロックが実行されます。

8.8. 定義済みクリーンアップ処理
with文を使用すると、リソースのクリーンアップが自動的に行われます。これは、ファイルの処理などで特に便利です。

```
with open("myfile.txt") as f:
    for line in f:
        print(line, end="")
```
このコードでは、ファイルが自動的に閉じられます。

8.9. 複数の関連しない例外の送出と処理
---
PythonのExceptionGroupクラスを使うと、複数の例外を一度に送出し、それらを処理できます。
これは、並行処理や複数のエラーが同時に発生する可能性がある場面で役立ちます。

https://qiita.com/FT_log/items/b9c15228594b1b8c49cc
【Python3エンジニア認定基礎試験】7. 入力と出力

7.入力と出力
---
プログラムの出力方法にはいくつかの種類があります。データを人間が読める形で出力することもあれば、将来使うためにファイルに書き込むこともあります。この章では、さまざまな出力方法について説明します。

7.1. 出力を見やすくフォーマットする
---
Pythonでは、出力をフォーマットするためにいくつかの方法が提供されています。

7.1.1. フォーマット済み文字列リテラル
---
フォーマット済み文字列リテラル（f-string）は、Pythonの式を {} 内に記述することで、その式の値を文字列に埋め込むことができます。文字列の最初に f または F を付けて使用します。

```
year = 2016
event = 'Referendum'
print(f'Results of the {year} {event}')
```

```
Results of the 2016 Referendum
```
オプションのフォーマット指定子を使用して、値の表示形式を細かく制御できます。例えば、次のコードでは、円周率を小数点以下3桁まで表示します。


```
import math
print(f'The value of pi is approximately {math.pi:.3f}.')
```

```
The value of pi is approximately 3.142.
```

7.1.2. 文字列の format() メソッド
---
str.format() メソッドを使用すると、出力のフォーマットをより柔軟に制御できます。{} で囲まれた部分が置換フィールドとなり、format() に渡された引数に置き換えられます。

```
print('We are the {} who say "{}!"'.format('knights', 'Ni'))
```

```
We are the knights who say "Ni!"
```
引数の順番を指定することもできます。

```
print('{1} and {0}'.format('spam', 'eggs'))
```

```
eggs and spam
```

7.1.3. 文字列の手作業でのフォーマット
---
手作業でフォーマットすることも可能です。
例えば、文字列を右寄せで表示するには、str.rjust() メソッドを使用します。

```
for x in range(1, 11):
    print(repr(x).rjust(2), repr(x*x).rjust(3), repr(x*x*x).rjust(4))
```

```
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000
```

7.1.4. 古い文字列書式設定方法
---
古い書式設定方法として % 演算子を使う方法があります。
次の例は、%5.3f を使って円周率をフォーマットしています。


```
import math
print('The value of pi is approximately %5.3f.' % math.pi)
```

```
The value of pi is approximately 3.142.
```

7.2. ファイルを読み書きする
---
ファイルを開いて読み書きするには、open() 関数を使用します。
例えば、書き込み用にファイルを開く場合は次のようにします。


```
f = open('workfile', 'w', encoding="utf-8")
```
ファイルの内容を読み取るには、f.read(size) を使用します。
size は読み取るデータのサイズを指定します。


```
f.read()
```
すべての行をリストとして読み取る場合は、f.readlines() を使用します。
また、with 文を使用してファイルを操作することで、処理が終わった後に自動的にファイルを閉じることができます。

```
with open('workfile', encoding="utf-8") as f:
    read_data = f.read()
```
ファイルに書き込むには、f.write(string) を使用します。

```
f.write('This is a test\n')
```
書き込んだ後は、必ず f.close() を呼び出してファイルを閉じるようにしましょう。
with 文を使用すれば、自動的にファイルが閉じられます。

https://qiita.com/FT_log/items/3e561f2c843192176dbd
plunkerでshadertoy sandbox その 7

# 概要
plunkerでshadertoyのglsl動かしてみた。

# 参考にしたページ

https://qiita.com/ayaha401/items/1809d600afaf433ef743

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/fe10a343-5d30-806d-81e7-f661a9b69b85.png)


# 成果物

https://embed.plnkr.co/plunk/GbEas5tHuQ2WHtaE


以上。
【Python3エンジニア認定基礎試験】6. モジュール

6.モジュール
---
Pythonで長いプログラムを書く際、コードの再利用やメンテナンスを考えると、コードをいくつかのファイルに分割し、それらをモジュールとして扱うのが効率的です。モジュールは、Pythonのコードをまとめたファイルで、他のスクリプトやモジュールから簡単に再利用できます。

6.1 モジュールの定義とインポート
---
モジュールは、Pythonの定義（関数、変数など）をまとめた .py ファイルです。例えば、以下のようなファイル fibo.py を作成します:

```
# Fibonacci numbers module

def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while a < n:
        print(a, end=' ')
        a, b = b, a+b
    print()

def fib2(n):   # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while a < n:
        result.append(a)
        a, b = b, a+b
    return result
```
次に、このモジュールをPythonインタプリタで使用するには、import文を使います。

```
>>> import fibo
```
このインポートは、モジュール fibo 内で定義された関数や変数を参照可能にします。ただし、モジュール名を使ってアクセスする必要があります。

```
>>> fibo.fib(1000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
```
よく使用する関数があれば、ローカル名に割り当てることもできます。


```
>>> fib = fibo.fib
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
```

6.1.1 モジュールの初期化
---
モジュールには関数定義に加え、初期化用のコードを含めることができます。インポートされたときにこのコードは1回だけ実行されます。

6.1.2 他のモジュールをインポート
---
モジュールは他のモジュールをインポートできます。通常、import文はモジュールの先頭に書かれます。


```
import sys
import os
```

6.1.3 名前空間の操作
---
特定の関数だけをインポートするには、以下のようにします。


```
from fibo import fib, fib2
fib(500)
```
また、モジュール名を別の名前でインポートすることも可能です。


```
import fibo as f
f.fib(500)
```

6.2 コンパイル済みファイル
---
Pythonは、モジュールの読み込みを高速化するために、コンパイル済みの .pyc ファイルを自動的に作成します。
これにより、次回以降のインポート時にモジュールの読み込みが速くなります。

6.3 標準モジュール
---
Pythonには多くの標準モジュールが同梱されており、sysモジュールやosモジュールなどはその例です。
標準モジュールは、Pythonインタプリタに直接ビルトインされているため、即座に利用可能です。


```
import sys
sys.ps1 = 'C> '
```

6.4 dir() 関数
---
dir()関数を使うと、モジュールが定義している名前の一覧を取得できます。


```
>>> import fibo
>>> dir(fibo)
['__name__', 'fib', 'fib2']
```
引数を指定しない場合、現在の名前空間にあるすべての名前が返されます。


```
>>> dir()
['__builtins__', '__name__', 'fibo', 'sys']
```
https://qiita.com/FT_log/items/2f70c8b59179974b3c3a