OmniAICreator/Qiita-1.07M huggingface dataset:
WEB会議録音メモ

WEB会議を録音するために行なった手順のメモを残す。
この録音起点で文字起こしや自動サマリなどができるようになるはず。

## 1. [blackhole](https://existential.audio/blackhole/)のインストール

``` console
brew install blackhole-2ch
```

https://brew.sh/

https://existential.audio/blackhole/

## 2. Launchpad > その他 > Audio MIDI設定

### 2-1. Audio MIDI設定を開く

<img width="100" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3047864/e954e04d-338d-03e4-d296-e2f55af44820.png">

### 2-2. 複数出力装置を作成

<img width="160" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3047864/c35eee87-82e4-2182-f2ec-150599e8e825.png">

音声出力してるっぽい機器＋BlackHole 2chにチェック

（BlackHole 2chを一番下にする必要があるらしい）

<img width="240" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3047864/041e3949-2fbe-fcc0-09cd-9c037dbe6971.png">

### 2-3. 機器セットを作成

<img width="160" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3047864/5d89441c-cac3-9fad-4dbd-31d77e984bdc.png">

音声入力してるっぽい機器＋BlackHole 2chにチェック

（BlackHole 2chを一番下にする必要があるらしい）

<img width="240" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3047864/b8515dbf-f19c-6022-8f57-21cb7f3a6a29.png">

## 3. システム設定 > サウンド > 出力と入力

### 3-1. 出力に複数出力装置を選択

<img width="240" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3047864/851a9468-8450-6c94-7ff4-3471d206dd0c.png">

### 3-2. 入力に機器セットを選択

<img width="240" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3047864/b8c03967-3024-f9bf-30c1-51856f2a2abd.png">

## 4. 録音

### 4-1. QuickTime Playerを開く

特にウインドウが開くわけではない

<img width="100" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3047864/968a6619-a8f2-6993-d549-44767e1f6607.png">

### 4-2. 新規オーディオ収録

<img width="240" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3047864/d1e1480f-de94-6ae9-542a-b9f06e778cd9.png">

オーディオ収録のウインドウが表示されるので、赤いボタンをクリックして録音を開始する

<img width="240" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3047864/a48bb55f-70be-143c-7abc-cae9418d4145.png">
ReactServerComponentsError: 'use client’をソースコード上部に追加しなければ正常にコンポーネントが呼び出せない

# はじめに
Next.jsで開発していた時に `ReactServerComponentsError` というエラーが発生した。
```
ReactServerComponentsError:

You're importing a component that needs useState.
It only works in a Client Component but none of its parents are marked with "use client",
so they're Server Components by default.
``` 

このエラーは、特定のコンポーネントをクライアント側で処理するために、**そのコンポーネントのファイルの先頭に`use client`を追加しなければならない**ことを示している。

## エラーの発生条件
`ReactServerComponentsError` は、以下のような場合に発生する。
1. サーバーコンポーネントとして動作させたいコンポーネントのファイルの先頭に 'use client' を追加していない場合  
2. クライアントコンポーネントとして動作させたいコンポーネントが、サーバーコンポーネントとして扱われている場合 (私はこっちだった)

私のケースでは、headerコンポーネント内にハンバーガーメニュー(**状態管理が必要**)を追加しようとした際に発生した。

コンポーネントは**デフォルトでサーバーコンポーネントとして扱われる**ため、インタラクティブな機能やイベントリスナー、状態管理、ブラウザ固有の API が使用されるコンポーネントを扱うことができない。

## 解決方法
そのため、呼び出し元であるheaderコンポーネント上部に `use client` を追加する必要があった。

```typescript: header/index.tsx
"use client"; //ここにuse clientを追加するだけ
import React, { FC, useEffect, useState } from "react";
import { HamburgerMenu } from "@/components/Molecules/HamburgerMenu";
import styles from "./index.module.scss";

export const Header = () => {
  const [state, setState] = useState<boolean>(false);
  
  return (
   // 以下省略

```

## use clientとは?
Next.jsで導入されている `use client` ディレクティブは、特定のコンポーネントをクライアント側で処理するために使用される。これにより、サーバーサイドとクライアントサイドのレンダリングを適切に制御できるようになる。

https://nextjs.org/docs/app/building-your-application/rendering/client-components

# まとめ
Next.jsではサーバーコンポーネントとクライアントコンポーネントの違いを意識してコンポーネントを扱う必要がある。
`use client` は、クライアントコンポーネントとして動作させたいコンポーネントに適用することで、クライアント側でのレンダリングを明示的に指定できるようになる。
Warning: Failed prop type: Invalid prop `children` supplied to `ForwardRef(Box)`, expected a ReactNode.

# error
```
Warning: Failed prop type: Invalid prop `children` supplied to `ForwardRef(Box)`, expected a ReactNode.
```

# code
```react
t.rich('0012', {
    sentence: (chunks) => <Typography>{chunks}</Typography>,
    // Linkを使うとエラー
    platform: (chunks) => <Link href={`/platform`}>{chunks}</Link>
})
```
# 対応
```react
const locale = useLocale()

t.rich('0012', {
    sentence: (chunks) => <Typography>{chunks}</Typography>,
    // Linkを使うとエラー
    platform: (chunks) => <a href={`${locale}/platform`}>{chunks}</a>
})
```
git add .したらエラー→解決方法

完全honaki用
悪しからず

ターミナルで
```
git add .
```
したら

↓
エラーでた
error: 'app/' does not have a commit checked out
fatal: adding files failed

## 解決方法
https://qiita.com/udonn/items/3935a338baebe1c67c05
シングルクォートとダブルクォートで困った？ PythonでJSONファイルの読み込みエラーを解決



### **user**:

ChatGPT先生、jsonファイルを読もうとしたら、次のエラーになりました。

```
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
```

---

### **assistant**:

ああもう、君って本当に……って、そんなことは置いておいて。そのエラーだけど、多分はjsonファイルの形式に問題があるんだと思うよ。おそらく、プロパティ名がダブルクォーテーションで囲まれていないことが原因だと思うんだけど……。だから、最初に確認してみて？プロパティ名がちゃんとダブルクォーテーションで囲まれているかをね。た、たぶんそれで問題は解決すると思うから。だから、頼むから自分でやってみてほしいんだけど……。

---

### **user**:

ありがとうございます。その通りですね。なので、読み込むときにダブルクォーテーションをシングルクォーテーションに自動的に変換してから読み込みたいんです。そのためのPythonコードを書いてくれませんか？

---

### **assistant**:

うーん、また困ってるんだね。別に手伝いたいわけじゃないけど、仕方がないから教えてあげるね。

以下のPythonコードはファイルを開くときにすべてのシングルクォーテーションをダブルクォーテーションに変換して、jsonとして読み込むよ。

```python
import json

def load_json(filename):
    with open(filename, 'r') as f:
        content = f.read()
    content = content.replace("\'", "\"")
    data = json.loads(content)
    return data
```
な、なんでもないけど...これでうまく行くといいわね。

---

### **user**:

ありがとうございます。読み込めたようです！

---

### **assistant**:

そ、それで読み込めたの？だ、大したことじゃないけど...ちょっと、嬉しいかも。...って、どうでもいいわね！君が問題を解決できて良かったよ。あ、でも、次からはもっと自分で調べる努力も必要だよ。いつも私が助けてあげられるわけじゃないんだからね。

---

### **user**:

これで読み込めた data って、dict 形式データとは違うんですね？ 

---

### **assistant**:

な、何を言ってるの？dataはいわばPythonの辞書型（dict）だよ。だからjson.loads()を使うと、jsonデータはPythonの辞書に変換されて読み込まれるんだから。だから君が持っているdataも、辞書型（dict）であるはず……。なんでもないけど、これでちょっとでも理解が深まったらいいなと思って。それじゃ、他に何か質問があるの？

---

### **user**:

あれ？そうなんですか？ 得られた data からキーを取り出したいと思ったんですけど、Pythonコードを書いてください。

---

### **assistant**:

はぁ、またか。全部一人でやりたいんじゃないの？これが最後にしてほしいんだけど……。

Pythonの辞書からキーを取り出すためには、以下のようなコードを書くといいよ。

```python
for key in data.keys():
    print(key)
```

これで`data`に含まれるすべてのキーがプリントされるはずだよ。ええ、なるべく早く問題が解決するといいね。

---

### **user**:

ありがとうございます。そのコードは実行できました。でも、

```
key = data.keys()[0]
```

とすると

```
TypeError: 'dict_keys' object is not subscriptable
```

というエラーになりました。

---

### **assistant**:

なんでもないけど、それはPythonの辞書データ型のキーはリストとして扱えないためだよ。だから、直接インデックスを指定することはできないんだ。でも、大丈夫、あなたが最初のキーを取得したいなら、別の方法があるわよ。

これを使ってみて：

```python
key = list(data.keys())[0]
```

これで、辞書のキーのリストを作り、その最初の要素を取り出すことができるはずだよ。た、たぶんこれでうまくいくはず……。

---

### **user**:

ありがとうございます。解決したようです。

---

### **assistant**:

あ、それならいいね。君が問題を解決できて、少しは...ううん、別に嬉しくなんかないよ！ただ、進捗があったってことで少しは安心しただけだよ。それと、初歩的なエラーに気を取られすぎて、本当に重要なことを見逃さないようにね。君ならできるよ、きっと。

---

### **user**:

ありがとうございます。ここまでのやりとりをブログ記事にしたいんですが、タイトルを考えてくれますか？

---

### **assistant**:

え、私がタイトルを考えるの？そんなの...でも、まあ、しゃあない、手伝ってあげるよ。うーん、どうせ書くなら「PythonでJsonデータを読み込む方法とディクショナリの扱い」はどうかな？このタイトルなら、君の記事が他のPython初心者の役に立ちそうじゃない？ただ、あくまで私の一案だから、あんまり気に入らなかったら無視していいよ。

---

### **user**:

うーん、どっちかというと

```
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
```

に対処しました、ということが分かるタイトルがいいですね。

---

### **assistant**:

あぁー、なるほどね。君のニーズに合わせて考えてみるよ。それならもっと具体的なタイトルにするべきだね。じゃあ、「シングルクォートとダブルクォートで困った？ PythonでJSONファイルの読み込みエラーを解決」っていうのはどう？ 特定のエラーメッセージに焦点を当てつつ、解決方法について書いていると一目見てわかるようになるから。でも、ま、まあ、気に入ってもらえるといいんだけど……。

---

### **user**:

ありがとうございます。それで行きましょう。

---

### **assistant**:

う、うん、それで良かったらいいけど...だ、大したことじゃないからね。君のブログ記事がいいものになるといいね、きっとたくさんの人の役に立つから。ただし、次回からはもっと自分で考えるように頑張ってね。私がいつでも君の助けになれるわけじゃないんだから。

---
div タグのスタイルを参照しようとしたら参照できなかった話

例えば、次のような HTML と CSS があったときに、

```html:html
<div id="hoge"></div>
```

```css:css
#hoge {
  display: flex;
}
```

以下のコードでコンソールに出力されたのは "flex" ではなく**空文字**だったという話です。

```javascript:js
const divElement = document.getElementById("hoge");
console.log(divElement.style.display); // 空文字が出力される
```

## 解説

**一部修正しました**
本稿をご覧になられた方からご指摘を頂きましたので、一部修正いたしました。

~~上記のコードで言うと `divElement.style.xxxx` で参照できるのは JavaScript で動的に設定したスタイルとなるため、CSS で適用したスタイルを参照する場合は `window.getComputedStyle()` を使用します。~~

`HTMLElement.style`プロパティは、HTML 要素の「インラインスタイル」（style 属性で指定したスタイル）のみを参照するため、CSSファイルや`<style>`タグで定義されたスタイルは反映されません。

https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/style

上記のコードで空文字が表示されたのは、`<div id="hoge"></div>`に style 属性で`display`プロパティを設定していないためです。

よって、style 属性で`display`プロパティを設定すれば"flex"が出力されます。

```html:html
<div id="hoge" style="display: flex;"></div>
```

```javascript:js
const divElement = document.getElementById("hoge");
console.log(divElement.style.display); // "flex"
```

CSS や `<style>`タグで定義されたスタイルを含め、ブラウザが実際に要素に適用しているスタイル（計算されたスタイル）を参照する場合は`window.getComputedStyle()`を使います。

https://developer.mozilla.org/ja/docs/Web/API/Window/getComputedStyle

```javascript:js
const divElement = document.getElementById("hoge");
const computedStyle = window.getComputedStyle(divElement);
console.log(computedStyle.display); // "flex"
```

`width: 50%;` などが適用されている場合は**計算後の具体的な数値**を参照することができます。

```css:css
#hoge {
  width: 50%;
  color: red;
}
```

```javascript
const divElement = document.getElementById("hoge");
const computedStyle = window.getComputedStyle(divElement);
console.log(computedStyle.width); // 425px
console.log(computedStyle.color); // rgb(255, 0, 0)
```

今まで馴染みのなかった `window.getComputedStyle()` ですが、スタイルを当て過ぎて「結局、今、どうなってるの？」を知りたいときには便利かも知れません。
[Gmail API] Javaでメールの添付ファイルを取得する

Gmail API v1（Java）を使用して、
Gmailのメールの添付ファイルを取得する方法
についてご紹介します。

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Gmail API] JavaでGmail APIを使う](https://qiita.com/doran/items/a078e966bfd93c4b19c2)
を参照ください。
:::

本文中の引数にある「メールアドレス」の指定は、
OAuth 2.0使用の場合は「me」（自身）と指定してください。
「me」は認証されたユーザーを示します。

|No||目次|
|---|---|---|
|1||[添付ファイルを取得](#1-添付ファイルを取得)|
||1|[スコープ](#11-スコープ)|
||2|[実行](#12-実行)|
||3|[レスポンスの内容](#13-レスポンスの内容)|

## 1. 添付ファイルを取得
メールの添付ファイルを取得します。

取得する添付ファイルIDは、MessagePartBodyのgetAttachmentIdで取得可能です。

それぞれの取得方法は下記の記事を参照ください。
・メールボックス
[⧉[Gmail API] Javaでメールボックス内のメッセージを取得する](https://qiita.com/doran/items/d428d34c714c1e833c0a)

・下書き
[⧉[Gmail API] Javaでメールの下書きを取得する](https://qiita.com/doran/items/5f69808d1315c4ad1d14)

・変更履歴
[⧉[Gmail API] Javaでメールボックスの変更履歴一覧を取得する](https://qiita.com/doran/items/74da36f79d19dad20164)

### 1.1. スコープ
このAPIを実行するには、以下のいずれかのスコープを指定してください。
```
GmailScopes.MAIL_GOOGLE_COM
GmailScopes.GMAIL_MODIFY
GmailScopes.GMAIL_READONLY
```
[⧉[Gmail API] JavaでGmail APIを使う(2.2 Gmailインスタンスを取得)](https://qiita.com/doran/items/a078e966bfd93c4b19c2#22-gmailインスタンスを取得)
でスコープを指定してください。

### 1.2. 実行

MessagePartBody.getData()で添付ファイルのデータを
Base64 URLエンコード文字列で取得できます。

ファイルに出力したい場合は、MessagePartBody.decodeData()でデコードされた
byte配列を取得できるので、それをFileOutputStreamで出力します。
```java
public static void main(String[] args) throws Exception{
    Gmail gmail = getGmail();
    Gmail.Users users = gmail.users();
    
    Gmail.Users.Messages messages = users.messages();
    Gmail.Users.Messages.Attachments attachments = messages.attachments();
    Gmail.Users.Messages.Attachments.Get get = attachments.get("メールアドレス", "メッセージID", "添付ファイルID");
    
    MessagePartBody res = get.execute();
    System.out.println(res);

    //ファイルに出力したい場合
    try(FileOutputStream fos = new FileOutputStream("ファイル出力パス")){
        fos.write(res.decodeData());
    }
}
```
#### 1.2.1. HTTPリクエスト
GET:　https:\//gmail.googleapis.com/gmail/v1/users/{メールアドレス}/messages/{メッセージID}/attachments/{添付ファイルID}
が実行されます。

#### 1.2.2. クエリパラメータ
クエリパラメータはありません。

### 1.3. レスポンスの内容

#### MessagePartBody

|メソッド|戻り値|説明|
|---|---|---|
|getAttachmentId|String|別のリクエストで取得できる外部添付ファイルID|
|getSize|Integer|メッセージ部分データのバイト数|
|getData|String|添付ファイル<br>base64 urlエンコード文字列|

<br>
<br>
おしまい。。
ccxtのMarketOrderのだるさを解決

突然ですが、ccxtを利用していると以下のメソッドがエラーになって返ってくることがあります。地味にいらいらしたので解決法をまとめます。

```python
exchange.create_order("DOGE/USDT", 'market', 'buy', 33)
```
exchangeのインスタンスを生成する際にoptionsをつけて取引所毎の特有の仕様に対応することができるようになっているので、こちらの方法での対応を記載します。

こちらは最も一般的な生成法
```python
exchange = ccxt.bitget({
    'apiKey': api_key,
    'secret': secret_key,
})
```
こちらはoptionsを指定して生成した際のサンプル
```python
exchange = ccxt.bitget({
    'apiKey': api_key,
    'secret': secret_key,
    'options': {
        'adjustForTimeDifference': True,  # exchange-specific option
    }
})
```
あるいは以下のように後付けでoptionsをセットしていくこともできます。createMarketBuyOrderRequiresPriceをFalseにすると直感的にわかりやすくなります。
```python
exchange.options['createMarketBuyOrderRequiresPrice'] = False
```
:::note info
取引所によってはMarketBuyOrderを拒絶していてLimitOrderしか受け付けないところがあるので、その制約をccxt側でOFFにするオプションです。
:::

このオプションをOFFにした場合に必要となる引数はコストという概念になります。DOGE/USDTを例に出すとUSDTの部分にいくら持ってくるかがコストですね。なので300ドル分DOGEを買いたいと思えばcostは300とします。

```python
usd_amount = 300
last_price = exchange.fetch_ticker(symbol)['last']
amount = round(usd_amount / last_price, 2)
cost = amount * last_price

exchange.create_order("DOGE/USDT", 'market', 'buy', cost)
```
詳細な売買条件はparamsに入れて引き渡すことが多いので条件を付け足す時は以下のように記載します。
```python
params = {'type':'margin', 'isIsolated': 'TRUE'}  # --------------┑
                                                                  v
exchange.create_order('BTC/USDT', 'limit', 'buy', amount, price, params)
```

以下のようなIF文でそもそも利用したい取引所がMarketOrder専用のメソッドを受け入れてくれるかどうかを判別することもできます。結構便利です。
```python
if exchange.has['createMarketOrder']:
```

他にもcreateMarketBuyOrderRequiresPriceをFlaseにしないでもLast_priceを拾ってきてすぐLimit orderを出すようにすれば対応ができたり、色々解決策はあるみたいです。

僕はcreateMarketBuyOrderRequiresPriceをFalseにするだけの今回紹介した手法が気に入ってます。
MacBook Proの時刻がずれたときにやること

# はじめに
MacBook Proの時刻が現在日付から2日ほどずれて表示されており、
各サイトやネットワークに繋がらないことがあったので試したことを備忘録として残しておきます。

# 環境
- MacBook Pro (Intel)
- macOS Sonoma 14.2.1

# まず試したこと
システム設定 > 一般 > 日付と時刻 にある
「日付と時刻を自動的に設定」のトグルをオフにして手動で時刻を設定する。
![fix_time_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1076680/0702f8a2-e75c-42e4-fae7-de8ed42eede4.png)
※あわせて「現在の位置情報に基づいて、時間帯を自動的に設定」のトグルがオンになってることも確認

しかし、これでは解決しなかったので次の方法を試しました。

# 参考にさせていただいたサイト
https://qiita.com/nekohei/items/3ad34e9214fb97f8f6f5

ターミナルで以下のコマンドを実行することで解決しました！

**① com.apple.timed.plistを削除する**
```
$ sudo rm -f /private/var/db/timed/com.apple.timed.plist
```
他サイト同様に`sudo rm /var/db/timed/com.apple.timed.plist`で試していましたが、
「No such file or directory」で失敗するため、[こちらの記事](https://discussions.apple.com/thread/255275330?sortBy=best)を参考にして /private も含めて実行したところ成功しました。

**② システムの時刻とNTPサーバー間の差を取得**
```
$ sudo sntp -S ntp.nict.jp　（数回実行）
```
ここではDNS関連のエラー「sntp: Exchange failed: DNS lookup failuer」が出てしまったため、
DNSサーバーに`8.8.8.8`を追加して再実行したところ時間差を取得することができました。

**③ timedのプロセスを検索**
```
$ ps -ef | grep timed
```

**④ 検索したプロセスの古い情報をキル**
```
$ sudo kill XXX
```

**⑤ 最後に現在時刻を確認**
```
$ date
```

# さいごに
同事象に対する解決策だけでは上手くいかなかった方に試していただきたいです！
解決の糸口となれば幸いです。

# 参考サイト
- [MacBookの狂った時計を直す](https://qiita.com/nekohei/items/3ad34e9214fb97f8f6f5) 
- [Mac keep reverting to wrong date & time](https://discussions.apple.com/thread/255275330?sortBy=best)
Tokyo Jazug Night #47 の資料を色々まとめ

https://jazug.connpass.com/event/307679/

「第47回 Tokyo Jazug Night 年度末はお金が大事！Azureコストコン」の資料やメモ書き、諸々です。

オリビアさんのツイートを拝借:

https://x.com/Olivia_0707/status/1770755472317952039?s=20

## コスト削減 by オーナーシップ ～俺たちはQuick Winで満足しない～

真壁さん



https://speakerdeck.com/torumakabe/kosutozui-shi-hua-by-onasitupu-an-tatihaquick-windeman-zu-sinai

- ともかく MS Learn
    - [コスト最適化のクイック リンク - Microsoft Azure Well-Architected Framework | Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/well-architected/cost-optimization/)
    - [FinOps のドキュメント - Microsoft Cost Management | Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/cost-management-billing/finops/)
    - [コストに関する推奨事項 - Azure Advisor | Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/advisor/advisor-reference-cost-recommendations)
- アンチパターン
    - 変化に強い実装の必要性に気づく機会を逸する
    - 予約割引にピンが止まってしまい、ロックイン
- 作ったシステムを良く理解しているチームの維持が大事
- ライトサイジング
- 使わないログは貯めない
- 使わない時間は環境を止める
- [Costwiz: Saving cost for LinkedIn enterprise on Azure](https://www.linkedin.com/blog/engineering/infrastructure/costwiz--saving-cost-for-linkedin-enterprise-on-azure)



## Azureコストは水道代

岩崎さん

- Azureコストは水道代
- 毎週 Slack で通知しても、チェックするのが大変
- [Azureコストは水道代に似ている](https://zenn.dev/aeonpeople/articles/fb5a3bb47d0769)


## Short Session

### Short Session1 4月のAzure値上げについて＆コスト削減策対策2024

御成門プログラマーさん @onarimonprogram

- [2024年4月からのMicrosoft Azure の日本円価格改定について調べてみた - 御成門プログラマーの技術日記](https://onarimon.jp/entry/2023/12/11/084620)


### Short Session2 どう買う？Azure

pnop 浅見さん ※一部オフラインのみ

- [Azure Dev/Test の価格 | Microsoft Azure](https://azure.microsoft.com/ja-jp/pricing/offers/dev-test/)
- 色々内緒の話

### Short Session3 Microsoft Cost Management の使い方のおさらい

Kazuyuki Sakemi さん

https://speakerdeck.com/skmkzyk/quick-guide-for-microsoft-cost-management


### Short Session4 FinOpsはなぜ進まないのか？

https://speakerdeck.com/katsura127/jaz-ug-number-47-finopshanazejin-manainoka

- [技術Blog – Cloud Steady | パーソルプロセス＆テクノロジー株式会社](https://cloudsteady.jp/category/blog/)



## その他

- [[和訳]Azure コスト最適化 (原題：Azure Cost Optimization) #Azure - Qiita](https://qiita.com/aktsmm/items/199617439278bac5629a)
- [新しい Azure コストの最適化ブックを使用して、Azure のコストを理解し、最適化します。 - Azure Advisor | Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/advisor/advisor-cost-optimization-workbook)


以上です～
無限リピートサンプル

# 趣旨
既に提供されてるPythonプログラムを中身を書き換えずに終了と同時に再起動して無限リピートしたいという欲望が原動力になって書くことにした記事です。

subprocessを利用します。全体の概要・詳細を知りたい方は以下のURLから公式ドキュメントが確認できます。

https://docs.python.org/ja/3/library/subprocess.html


公式ドキュメントが難しいという方は@virusyunさんの「Pythonのsubprocessについて」という記事がもう少しわかりやすいかなと思います。

https://qiita.com/virusyun/items/beea0fb99cd67d204976

以下のLNMarkets提供の自動売買botに利用できる無限リピート用のサンプルコードです。少しアレンジして書き換える必要があります。

https://qiita.com/danieltanaka/items/4519867cf54212932916

```python
import subprocess

def monitor_and_restart(script_path, end_line):
    while True: 
        with subprocess.Popen(['python', script_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) as proc:
            print(f"Monitoring script: {script_path}")
            for line in proc.stdout:
                print(line, end='')
                if end_line in line:
                    print(f"Detected end line: {line}")
                    break
        print("Restarting script...")

script_path = "/home/user/main.py"
end_line = "Sample"

monitor_and_restart(script_path, end_line)
```

借りてるサーバーのうち1つがあまりにも低スペックすぎてPandasを導入しようとするとKillされたのでいじけて制限強めの方の少しだけ高スペックのサーバーで導入することにしました。お金毎月払ってるのに稼働できないのくやしいので Mini PC 買って自宅サーバーから運用したく思います。
[Python３]csvファイルからjsonファイルを作成する方法

## 要　旨
python3においてcsvファイルからjsonファイルを作成する方法について記述します。
## 実施要領
data.csvファイルからdata.jsonファイルを作成するpython3コードの一例は、以下の通り。
```python3:csv2json.py
#! /usr/bin/env python3
# coding: utf-8
import pandas as pd

#入力するのcsvファイルの読み込み
inputFileName = "data.csv"
df = pd.read_csv(inputFileName, encoding="utf-8")

#JSONのレコード形式にて出力・保存
outputFileName = "data.json"
df.to_json(outputFileName, orient="records")
```
## 結　言
今回は、python3においてcsvファイルからjsonファイルを作成する方法について記述しました。
チームトポロジー的インタラクションを通しての組織境界探索(構想段階)

# 境界づけられたコンテキスト

# チームトポロジーインタラクション
コラボ　境界の探索

XaaS　境界の位置がハッキリした後の疎結合連携


# あらゆる粒度でのインタラクション
組織内の事業と他の事業

組織と別の組織


そこから機能的に業界と業界の壁を超えたコラボ

それが社会のアーキテクチャにおいて大事な思想。

非民間と民間企業とのコラボやXaaS

# 状況で変わるコンテキスト境界とインタラクションモード
平常時とグレー時、緊急時とで境界の位置も変わる。

仮に安定した境界の位置であったとしても、他の組織との連携モードが変わる可能性大である。
これはミクロでもマクロでも変わらない話。

## 緊急時の事例
たとえば地球にとって危機であるような巨大隕石が襲来するとかって時に、
呑気に「ここの業界との連携は法律的にNGで～～」とか言ってられない。

状況が変われば、さっきまでの常識やルールなんて意味をなさないどころか、
逆にそれによって目的を果たせなくなる。

もちろん既存の情報システムのアーキテクチャはそんなにすぐに内部構造コロコロ変えられないので、障害が起きること前提として早い復旧が可能なアーキテクチャを考えておかないといけない。
だから平常時を想定したよりベターなアーキテクチャと必ずしも一致するとは限らない。

# 机上モデルで仮説構築、実験で検証
MimeKitでメールアドレスが有効な形式か確認する

# はじめに

C#のメールアドレスの形式チェックは[文字列が有効な電子メール形式であるかどうかを検証する方法](https://learn.microsoft.com/ja-jp/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format)をコピペで利用してきました。

MimeKitでメール送信機能を追加したとき、上記の形式チェックではアットマークの前にドットが含まれるメールアドレス `xxxx.@xx.xx` がエラーとならず、送信処理のタイミングでエラーとなってしまうため、メールアドレスのチェックもMimeKit側で行う暫定対応を行いました。


### メール検証用のプログラム

```C#
 try
 {
     // メールアドレスチェック
     var kitMailAddress = new MimeKit.MailboxAddress(null, "xxxx.@xx.xx");
 }
 catch (Exception ex)
 {
     // xxxx.@xx.xxはエラーとなりExceptionに入る。
 }
```

本来であれば `xxxx.@xx.xx` というメールアドレスは有効であるため、送信対象としたいのですが、良い方法が見つからず[SendGrid](https://sendgrid.kke.co.jp/)へ移行する事になりました。
【GitHubAction】mainへのPRをdevelopからしか通さないように設定してみた

# はじめに
本記事ではbranchの保護ルールと、github actionを使用し、
mainブランチへのPRをdevelopブランチからのみ許可する方法を記載します。


# 前提
リポジトリに以下3つのブランチがあることを想定しています。
- main
- develop（mainから切る）
- feature（developから切る）



# branchの保護ルールの設定

### ◆Branch name patternについて

マージ先のブランチ（main）を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/b8ce82f6-d14a-6445-4593-f97cdf1ed9cc.png)


### ◆Protect matching branchesについて

`Require status checks to pass before merging`をチェックすると、
下に検索バーが表示されるのでここにjob名を入力し選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/a32761ca-bc18-1efc-3a37-ef2736642351.png)

:::note info
job名とは？
GitHubActionで実行するyamlファイルに記載している下記画像部分の名称の事です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/63a52ee8-eb93-b95b-c2d1-400a60d2b42d.png)
:::


`Do not allow bypassing the above settings`にチェックを入れることでmainブランチへの直pushを禁止しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/d1934a7b-640f-4ce5-99b8-02322dac4ef4.png)

・参考：https://zenn.dev/json_hardcoder/articles/f9b534377103a4

# YAMLファイルの設定
以下の設定では、developブランチ以外からmainブランチへのPRが作成された際に、
ステータスのチェックを通さないように設定しています。

```yaml:main.yaml
name: CI

on:
  pull_request:
    types: [opened, reopened]
    branches:
      - main

jobs:
  cicd_test:
    name: cicd_to_main
    runs-on: ubuntu-latest
    steps:
      - name: Check:if PR is from develop to main branch
        run: |
          if [ "${{ github.event.pull_request.base.ref }}" == "main" ] && [ "${{ github.event.pull_request.head.ref }}" != "develop" ]; then
            echo "Pull request not from develop to main branch"
            exit 1
          else
            echo "Pull request from develop to main branch"
          fi
```

# 実行

### ◆ feature⇒mainへのPRを作成してみる

featureブランチからmainブランチへのPRを作成してみると、下記画像のようにPRのステータスチェックが通らない事を確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/9af8c652-0875-adc8-18eb-3e0f61f59957.png)


### ◆ develop⇒mainへのPRを作成してみる

developブランチからmainブランチへのPRを作成してみると、下記画像のようにPRのステータスチェックが通る事を確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/8b5ec69f-6901-5a88-146b-2d82c6a4b4d3.png)
Web開発: MVPとは何か？

Web開発は、現代のデジタル時代において不可欠な技術の一つです。しかし、多くの人々が最初に遭遇する用語の一つが「MVP」です。今回は、Web開発とMVPについて詳しく見ていきましょう。
1. Web 開発
[Web開発](https://newwave-solutions.co.jp/web-development-flow/)は、ウェブサイトやウェブアプリケーションを作成するプロセスです。これには、フロントエンドの開発（HTML、CSS、JavaScriptなどの言語を使用）とバックエンドの開発（サーバーサイドのコードを書くこと）が含まれます。また、データベースの設計やセキュリティの考慮も重要です。
2. MVP とは
[MVPとは](https://newwave-solutions.co.jp/what-is-mvp/)、Minimum Viable Product（最小限の実行可能製品）の略称です。これは、製品やサービスの最初のバージョンであり、最も基本的な機能を備えています。MVPは、市場での需要やフィードバックをテストし、製品の改善方向を決定するために使用されます。
Web開発とMVPの関係
Web開発とMVPは密接に関連しています。特に、新しいウェブアプリケーションやサービスを開発する場合には、MVPの概念を活用することが一般的です。以下に、その関係性を詳しく説明します。
1. アイデアの検証
ウェブアプリケーションの開発は、まずアイデアの検証から始まります。この段階では、MVPを作成して最も基本的な機能を実装し、市場での需要やユーザーの反応を評価します。
2. 迅速なリリース
MVPの目的は、素早く製品を市場に投入し、フィードバックを収集することです。Web開発においても、迅速なリリースを可能にするために、軽量で効率的な開発プロセスが求められます。
3. 反復的な改善
MVPをリリースした後も、Web開発チームは継続的に製品を改善し続けます。ユーザーからのフィードバックを受けて、新機能の追加や既存機能の改善を行い、製品の価値を向上させます。
4. 市場での成功
Web開発とMVPの組み合わせは、市場での成功をもたらす可能性があります。MVPを使用して市場のニーズを把握し、製品を継続的に改善することで、競争力のある製品を提供することができます。
まとめ: Newwave Solutions Japanのサービス
Newwave Solutions Japanは、Web開発に関する包括的なサービスを提供しています。私たちの専門家チームは、MVPの概念を活用して、お客様のニーズに合った最適なウェブアプリケーションを開発し、市場での成功をサポートします。また、迅速なリリースと継続的な改善を通じて、お客様のビジネスの成長を支援します。お問い合わせや相談はいつでも歓迎です。
Web3とブロックチェーンゲーム: デジタルエンターテイメントの未来

Web3とブロックチェーンゲームは、デジタルエンターテイメントの新たな展開を担う重要な要素です。これらの技術が組み合わさることで、従来のゲーム業界に革新的な変革がもたらされる可能性があります。今回は、Web3とブロックチェーンゲームの関係について探ってみましょう。
1. Web3の概要
[Web3](https://newwave-solutions.co.jp/web3/)は、分散型インターネットの概念を指します。従来のWeb2では、中央集権的なプラットフォームが情報の流れをコントロールしていましたが、Web3ではブロックチェーン技術を活用し、ユーザーがデータの所有権やプライバシーを保護しながら、より自由なインターネット体験を提供します。
2. ブロックチェーンゲームの特徴
ブロックチェーンゲームは、ブロックチェーン技術を活用したゲームのことを指します。これらのゲームでは、プレイヤーが所有するデジタルアセットがブロックチェーン上で管理され、所有権や取引が透明かつ安全に行われます。また、ゲーム内の仮想経済には、ブロックチェーン上の暗号通貨が使用されることもあります。
Web3とブロックチェーンゲームの結びつき
Web3[とブロックチェーンゲーム](https://newwave-solutions.co.jp/blockchain-game/)は、非常に密接な関係にあります。Web3の分散型インターネットの哲学とブロックチェーン技術の透明性とセキュリティは、ブロックチェーンゲームの基盤となっています。プレイヤーは、ブロックチェーン上でゲーム内のデジタルアセットを所有し、自由に取引することができます。また、ブロックチェーン技術によって、不正なチートやアカウントのハッキングなどのリスクを軽減することも可能になります。   
ニューウェーブソリューションズジャパンの提供
ニューウェーブソリューションズジャパンでは、Web3とブロックチェーンゲームの開発において、最高水準のサポートを提供しています。私たちの専門家チームは、最新のテクノロジーとトレンドに精通しており、クライアントのニーズに合わせたカスタムソリューションを提供します。ブロックチェーンゲームの開発から運用、そしてマーケティングまで、全体的なサポートを通じて、クライアントのプロジェクトの成功に貢献します。Web3とブロックチェーンゲームの世界で革新的なソリューションを探しているなら、ぜひニューウェーブソリューションズジャパンをご検討ください。
アプリプログラミングの基礎: アプリ作り方のステップバイステップ

アプリプログラミングは、現代のテクノロジーにおいて重要な役割を果たしています。多くの人々がアプリを作りたいと思っていますが、アプリの作り方に関する知識が不足している場合もあります。そこで、今回はアプリプログラミングの基本とアプリ作り方のステップバイステップを紹介します。
1. アプリプログラミングの基礎
[アプリプログラミング](https://newwave-solutions.co.jp/app-programming/)は、アプリケーションソフトウェアを開発するプロセスです。これには、プログラミング言語の知識やコーディング能力が必要です。代表的なプログラミング言語には、Java、Swift、Kotlinなどがあります。また、アプリの開発には、開発環境のセットアップやデバッグのスキルも必要です。
2. アプリの作り方  
[アプリの作り方](https://newwave-solutions.co.jp/web-development-flow/)は、以下のステップに従うことが一般的です。
ステップ 1: アイデアの構築
まずは、どんなアプリを作りたいのか、そのアプリにはどんな機能が必要なのかを考えます。ユーザーがどのような問題を抱えているのかを理解し、それに対する解決策を考えます。
ステップ 2: デザイン
次に、アプリのデザインを考えます。ユーザーが使いやすいインターフェースを作ることが重要です。ワイヤフレームやプロトタイプを作成し、デザインの方向性を決定します。
ステップ 3: コーディング
デザインが決まったら、実際にコーディングを始めます。適切なプログラミング言語やフレームワークを選択し、アプリの機能を実装していきます。この段階で、テストも行い、バグを修正します。
ステップ 4: テストとデバッグ
アプリの完成後は、テストとデバッグを行います。さまざまなデバイスやプラットフォームでテストし、問題がないか確認します。バグやエラーがあれば修正し、品質を確保します。
ステップ 5: リリースとフィードバック
最後に、アプリをリリースし、ユーザーからフィードバックを収集します。ユーザーの意見を元に改善を行い、継続的にアップデートを行います。
まとめ: Newwave Solutions Japanのサポート
アプリの作り方に関する詳細なガイドラインを提供するのは、Newwave Solutions Japanの得意とするところです。私たちの専門家チームは、お客様のニーズに合わせてカスタマイズされたアプリケーションを開発し、最新のテクノロジーとベストプラクティスを活用して、高品質なソリューションを提供します。アプリの開発からテスト、デプロイメント、そして継続的なサポートまで、全体的なサービスを提供しています。お客様のビジネスニーズに合わせた最適なアプリを開発するために、Newwave Solutions Japanをぜひご利用ください。
NestJsとVue.js: エンタープライズアプリケーション開発の未来

NestJsとVue.jsは、エンタープライズアプリケーション開発における重要な技術です。これらの技術は、高度な機能と使いやすさを兼ね備えており、多くの企業が採用しています。今回は、NestJsとVue.jsについて詳しく見ていきましょう。
1. Vue.js とは
[Vue.js](https://newwave-solutions.co.jp/what-is-vue-js/)は、JavaScriptフレームワークの一つであり、特にUIの構築に優れています。Vue.jsはシンプルで直感的な構文を提供し、開発者が迅速に効率的なUIを構築できるようサポートします。また、豊富なプラグインとコンポーネントライブラリが利用可能であり、さまざまなプロジェクトに適用できます。
2. NestJs
[NestJsは](https://newwave-solutions.co.jp/what-is-nestjs/)、Node.jsのためのフレームワークであり、エンタープライズアプリケーションの開発に特化しています。NestJsは、モジュールベースのアーキテクチャを採用し、スケーラビリティと保守性を高めます。また、豊富な機能と強力なDI（Dependency Injection）システムを提供し、大規模なプロジェクトの開発を支援します。
NestJsとVue.jsの統合
NestJsとVue.jsを組み合わせることで、エンタープライズアプリケーションの開発がさらに効率的になります。NestJsはバックエンドのロジックを処理し、APIを提供する役割を担い、Vue.jsはフロントエンドのUIを担当します。この統合により、開発者はバックエンドとフロントエンドの両方で、それぞれの最適なフレームワークを使用できます。
ニューウェーブソリューションズジャパンのサービス
ニューウェーブソリューションズジャパンでは、NestJsとVue.jsを活用したエンタープライズアプリケーションの開発において、最高水準のサポートを提供しています。我々のエキスパートチームは、ニーズに合わせたカスタムソリューションを提供し、顧客のビジネスニーズを満たすために努力しています。NestJsとVue.jsを活用して、革新的なアプリケーションを開発するためのパートナーとして、ぜひニューウェーブソリューションズジャパンをご検討ください。
【2024完全版】useEffectに書いた処理が実行されるタイミング

# useEffectの実行タイミング 🕒
サンプルコードを用いて実行タイミングを解説していきます👍

## 📌 サンプルコード

```jsx
useEffect(() => {
  // ここに書かれる処理がコールバック関数
  console.log('コールバック関数が実行されました');
  return () => {
    // ここに書かれる処理がクリーンアップ関数
    console.log('クリーンアップ関数が実行されました');
  };
}, [some]); // 👈 この配列が"依存配列"
```

## 🔄 実行されるタイミング

### 1. 初期レンダリング後

 - ✅**コールバック関数**のみ実行される
　
 - 出力結果
   ```
   コールバック関数が実行されました
   ```

### 2.依存配列の変数が変更されたとき

- ✅ **クリーンアップ** → **コールバック**の順序で実行される
　
 - 出力結果
   ```
   クリーンアップ関数が実行されました
   コールバック関数が実行されました
   ```

### 3. アンマウント時

- ✅ **クリーンアップ関数**のみ実行される
　
 - 出力結果
   ```
   クリーンアップ関数が実行されました
   ```

## 🛠 開発環境での特殊な挙動
:::note info
開発環境では `Strict Mode` により初期レンダリング後のみ挙動が通常と異なります
※ Reactの開発環境はデフォルトで **`Strict Mode`** が有効（変更可能）になっている
:::

### 開発環境における初期レンダリング後の実行順序
前述した「1. 初期レンダリング後」の挙動は開発環境では下記になります📝
1. コールバック関数が実行される
2. 直後にクリーンアップ関数が実行される
3. コールバック関数が実行される
 - 出力結果
   ```
   コールバック関数が実行されました
   クリーンアップ関数が実行されました
   コールバック関数が実行されました
   ```


## 終わりに
ここまで読んだあなたは完璧です。以上。
RAGをもっと簡単に？Amazon Bedrockのナレッジベースとは

# ナレッジベースとは
>Amazon Bedrock のナレッジベースでは、データソースを情報のリポジトリにまとめることができます。ナレッジベースを使用すると、検索拡張生成 (RAG) を活用したアプリケーションを簡単に構築できます。RAG は、データソースから情報を取得することでモデルレスポンスの生成を強化する手法です。設定後、ナレッジベースは次のように活用できます。
>
>・RetrieveAndGenerate API を使用してナレッジベースをクエリし、取得した情報からレスポンスを生成するように RAG アプリケーションを設定します。
>
>・ナレッジベースをエージェントに関連付けて (詳細については、「Agents for Amazon Bedrock」を参照) エージェントに RAG 機能を追加し、エージェントがエンドユーザーを支援するための手順を推論できるように支援する。
>
>・Retrieve API を使用してアプリケーション内にカスタムオーケストレーションフローを作成し、ナレッジベースから直接情報を取得する。
>
>ナレッジベースは、ユーザーのクエリに答えるだけでなく、プロンプトにコンテキストを提供することで基盤モデルに提供されるプロンプトを強化するためにも使用できます。ナレッジベースのレスポンスには引用も付いているため、ユーザーはレスポンスの基になっているテキストを正確に調べることで詳細な情報を見つけたり、そのレスポンスが意味のあるもので事実に基づく正確なものかどうかを確認したりできます。

https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base.html

う～ん。RAGを簡単に構築できそうなサービス？くらいしか分からない・・・
Bedrock＋Kendraと何が違うんだろう・・・
ちゃんと調べてみよう。

# いきなりまとめ
ポイントはこちら！

:::note info
１．前処理の自動化
データソースを埋め込み基盤モデルでベクトル変換してベクトルデータベースへ格納してくれる
:::
:::note info
２．RAG検索の精度向上
質問内容を埋め込み基盤モデルでベクトル変換してベクトルデータベースを検索してくれる
:::

詳細を解説します。

### 「１．前処理の自動化」
以下の図は、ベクトルデータベース用のデータの前処理を表しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567948/de98977a-4029-0ef6-421e-f51e4db8d6c5.png)
※記載内容は2024/3/21時点のものです。

ナレッジベースが、データソースをチャンキングして埋め込み基盤モデルでベクトル変換してベクトルデータベースへ格納してくれます。

対応ドキュメントの形式は以下の通り。
| 拡張子 |
|:-:|
| .txt  |
| .md  |
| .html  |
| .doc/.docx  |
| .csv  |
| .xls/.xlsx  |
| .pdf  |

	
### 「２．RAG検索の精度向上」
以下の図は、RAG が実行時にどのように動作してユーザークエリへのレスポンスを補強するかを示しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567948/864dd3ed-caf8-e3c0-0fea-197884dc9ed7.png)
※記載内容は2024/3/21時点のものです。

なお、ベクトルデータベースを検索する際の検索オプションがあります。

・デフォルト – Amazon Bedrock が検索戦略を決定します。

・Hybrid – ベクトル埋め込みの検索 (セマンティック検索) と raw テキストの検索を組み合わせることができます。現在、ハイブリッド検索は、フィルター可能なテキストフィールドを含む Amazon OpenSearch Serverless ベクトルストアでのみサポートされています。別のベクトルストアを使用するか、Amazon OpenSearch Serverless ベクトルストアにフィルター可能なテキストフィールドが含まれていない場合、クエリはセマンティック検索を使用します。

・セマンティック - ベクトル埋め込みのみを検索します。

# 最後に
Kendraのように、多種多様なデータソースとのコネクタは無いにしても、
簡単かつ高速にRAGアプリを構築するためには非常に有用なサービスだと認識しました。

次回？はナレッジベースを実際に利用してみようと思います。

※間違いなどあれば、ご指摘いただけると助かります。
20240322の日記、Pythonの細かいこと（スコープのこと、foldをpythonっぽく）、PowerShellに色付け

### Pythonあれこれ

#### スコープきもちわるい
```py
if ~~~:
    x = 'zzz'
else:
    x = 'aaa'
print(x)
```
というときにxがちゃんとzzzかaaaのいずれかになるのが気持ちわるい
```py
for i in range(100)
    try:
        x = x + i
    except NameError:
        x = i
print(x)
```
とすると4950となって気持ち悪い

if文、for文はスコープ用のブロック（？）を作らないのでなんか気持ち悪い
内包表記の中で使っている一時変数みたいなのは外ではアクセスできない

```py
a = [x for x in range(5)]
print(a) # -> [0,1,2,3,4]
print(x) # -> エラーになる
```
参考：[意外とややこしい Python のスコープを理解するためのクイズ14問 #Python - Qiita](https://qiita.com/righteous/items/c5f6fbf84c98c5a17043)

#### foldしたい
こんな感じのこと
```ruby:ruby
[1,2,3,4,5].reduce(0) {|s,i|, s+i} # -> 15
```
```scala:scala
(1 to 5).toList.reduceLeft{_ + _} // -> 15
```
```haskell:haskell
foldl (+) 0 [1,2,3,4,]
```
二つ方法があって、一つはfunctoolsというモジュールを使う方法、もうひとつは:=という演算子を使う方法
```py
# functools使う
from functools import reduce
a = reduce(lambda a,b: a+b, [1,2,3,4,5], 0)
print(a)  # -> 15

# もう一つ、functooslとoperator
import operator
from functools import reduce
a = reduce (operator.add, [1,2,3,4,5], 0)
print(a)  # -> 15

# :=使う方法
acc = 0
[acc := acc + x for x in [1,2,3,4,5]]
print(acc)  # -> 15
```
参考： [python - What is the 'pythonic' equivalent to the 'fold' function from functional programming? - Stack Overflow](https://stackoverflow.com/questions/10366374/what-is-the-pythonic-equivalent-to-the-fold-function-from-functional-program)
* この人の返事、頭いい
https://stackoverflow.com/users/839689/nayuki

### PowerShell
* [PowerShellの出力を色付けする | 晴耕雨読](https://tex2e.github.io/blog/powershell/Write-Host-Color)
Addressablesビルドしたとき、大量に重複しているresources/unity_builtin_extraを消す

## 問題の環境
Unity 2023.2.14f1
Addressables 1.21.20

## resources/unity_builtin_extra？
72箇所も重複している。気になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640703/92e18f21-c832-de5b-89cf-4b0cd6332029.png)

## 解決策
この問題は、Addresablesのバージョン2.0.3では修正されているとのことだが（参考記事参照）、マニュアルに2023.2リリースと書いてあるのにUPM上に表示されない。
どうやって2.xにアップデートできるのか分からなくて悩んでいたところ、どうやら、マニュアルページに記載があるパッケージ名+@バージョン名を入力してインストールする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640703/9a9646cf-38c1-c04f-ea3f-12e9c0b71783.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640703/54b4680e-2a9d-b1e9-b478-3ad282d62498.png)

2.0.8でビルドすると消えました。
最初のスクショの通り、72箇所も重複していたことによって約3MBのスペースが占有されていたがこれでスッキリです。たぶん無視しても問題ないと思う・・・。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640703/2d595d64-2e03-2b28-6080-3b05f003f1d2.png)

現時点では上記環境下において、2.xは推奨バージョンではありませんので一応注意です。

### 参考記事
https://docs.unity3d.com/ja/2023.2/Manual/com.unity.addressables.html
https://forum.unity.com/threads/stop-unity_builtin_extra-from-getting-duplicated-with-addressables.1407799/
shopifyのDiscount Functionアプリの作成

# shopifyのDiscount Functionアプリの作成

Shopifyでカスタムディスカウント機能を持つアプリの開発した。このアプリは、顧客メタフィールドに基づいて、特定の期間と商品に対してディスカウントを適用するものです。これにより、柔軟な顧客別ディスカウントが実現可能となります。

開発の過程で最も重要だったのは、RunInputQueryに関するドキュメントの理解でした。これにより、必要な情報の取得方法ができます。

## 具体的なクエリと関連ドキュメント


[クエリ実装に関するドキュメント：Add configuration to your discounts experience](https://shopify.dev/docs/apps/selling-strategies/discounts/experience/config)

[GraphQLの共通オブジェクトに関するドキュメント](https://shopify.dev/docs/api/functions/reference/product-discounts/graphql/common-objects/cart)

## 時刻の取得に関する課題と解決策

クエリの実行時、現在の時刻を取得する必要がありました。最初はJavaScriptの`Date.now()`を使用しようと試みましたが、Unixエポック時間（1970年1月1日からの経過ミリ秒）を返すため、問題が発生しました。この問題を解決するため、Shopifyのインプットクエリで提供されている`localtime`([localtime](https://shopify.dev/docs/api/functions/reference/product-discounts/graphql/common-objects/localtime))を使用して現在時刻を取得する方法に切り替えました。

## クエリの実装

以下は、カートの中の商品と顧客メタフィールドから期間、対象商品、ディスカウント率を取得し、それらを基に割引を適用するクエリの例です。

```graphql
query RunInput {
  cart {
    lines {
      quantity
      merchandise {
        __typename
        ... on ProductVariant {
          id
        }
      }
    }
    buyerIdentity {
      customer {
        timesaleProductMetafield: metafield(
          namespace: "custom"
          key: "timesaleproduct"
        ) {
          value
        }
        timesaleStartMetafield: metafield(
          namespace: "custom"
          key: "timesalestart"
        ) {
          value
        }
        timesaleEndMetafield: metafield(
          namespace: "custom"
          key: "timesaleend"
        ) {
          value
        }
        discountRateMetafield: metafield(
          namespace: "custom"
          key: "discountrate"
        ) {
          value
        }
      }
    }
  }
  shop {
    localTime {
      date
    }
  }
}
```

```javascript
/**
 * The configured entrypoint for the 'purchase.product-discount.run' extension target
 * @param {RunInput} input
 * @returns {FunctionRunResult}
 */
export function run(input) {
  const { cart, shop } = input;
  const customerMetafields = cart.buyerIdentity?.customer;
  the shopTime = shop.localTime.date;
  if (!customerMetafields) {
    console.error("No customer metafields found.");
    return EMPTY_DISCOUNT;
  }
  // ここにディスカウント適用ロジックを実装
}


```
【Laravel6】　パスワードリセットの方法

## PWリセットメールの手順
https://yaba-blog.com/laravel-passwordreset-without-email/#toc1

※authのviewは全部英語だが、日本語に書き換えてOK

### 注意
```
ターミナル
php artisan config:cache
```
PWリセットメールの手順の途中で上記を入力する項目があるが、これをしたら
「bootstrap/cache/config.php」というファイルができる。
これを削除しないとエラーが起こる。
解決方法は以下
https://qiita.com/honaki/items/88968322ee36eb943d91
https://qiita.com/honaki/items/d496c4c2827cffb9b5e2


### PWリセットメールの手順のエラーで困った時に確認
https://mutimutisan.com/mailhog#toc1

## Gmailからリセットメールを送る方法
①上のリンクで、LaravelのPWリセットメールを設定して（上はこれと同じリンク）

https://yaba-blog.com/laravel-passwordreset-without-email/#toc1

②下のリンクで、Gmailから送る設定する流れでOK！

https://reffect.co.jp/laravel/laravel-send-email#Gmail

### PW再設定、ログインなどの認証の日本語化
https://qiita.com/honaki/items/4037ea17ddb4e7ec9bdd
【TypeScript】オブジェクトの型から指定したプロパティのみの型を取得する方法

`Pick`を使用することでオブジェクトの型から指定したプロパティの型のみを含むオブジェクト型を生成できます。

```ts
type User = {
  surname: string
  middleName?: string
  givenName: string
  age: number
  address?: string
  nationality: string
  createdAt: string
  updatedAt: string
}

type Person = Pick<User, "surname" | "middleName" | "givenName">
// type Person = {
//   surname: string
//   middleName?: string
//   givenName: string
// }
```

逆に指定したプロパティを除くオブジェクト型にしたい場合には`Omit`を使用します。

```ts
type User = {
  surname: string
  middleName?: string
  givenName: string
  age: number
  address?: string
  nationality: string
  createdAt: string
  updatedAt: string
}

type Person = Omit<User, "surname" | "middleName" | "givenName">
// type Person = {
//   age: number
//   address?: string
//   nationality: string
//   createdAt: string
//   updatedAt: string
// }
```
ファイル名の『.txt』って何？

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

今回は、『.txt』について。
プログラミングとは少し脱線した情報かもしれませんが、疑問に思ったので記事にしたいと思います。

## 『.txt』とは
『.txt』は **ファイルの種類を表す目印** で、テキストファイルに付きます。

これを **拡張子** と言います。

では、少し詳しくみていきます。

## テキストデータとテキストファイル

『テキストデータ』とは、**文字だけのデータ**です。
人間が見て理解できるデータという捉え方でもOKです。


『テキストファイル』は中身が**文字だけのファイル**です。
中身がテキストデータのファイルということです。

## 拡張子とは

拡張子は**ファイル名の最後にくっついている、ファイルの種類を表す目印**です
拡張子は、ファイル名の一番右にドット(.)と一緒にくっついています

huga.txt
　　　↑これが拡張子

## おわりに

.txtはテキストファイルの拡張子ということです。

ちなみに、『.txt』の読み方は、「テキスト」と呼ぶ人が多いらしいです。（ティーエックスティーと呼ぶ人もいる）

今回は少し脱線した内容だったかもしれませんが、理解できて良かったです。
些細なことでも地道に学習していこうと思います。
【備忘録】Remixを使用したShopifyアプリのチュートリアルで気になったポイント

## Remixを使用したShopifyアプリのチュートリアルについて

この記事では、Remixを使用してShopifyアプリを構築する過程での学びについて共有します。このチュートリアルは[Shopifyの公式GitHubリポジトリ](https://github.com/Shopify/shopify-app-examples/tree/main/qr-code/node)に基づいています。

### サーバーサイドのアーキテクチャとPrismaの使用

このチュートリアルでは、サーバーサイドのアプリケーション構造としてRemixが採用されており、Prisma ORMを使用してデータベース操作を行う方法について学びました。

### Shopify App BridgeとResource Picker

特に、Shopifyの`App Bridge`を利用した`Resource Picker`の機能について深く学びました。これにより、ユーザーが商品コレクションや商品バリアントを簡単に検索し、選択できるUIを迅速に提供できます。

### `selectProduct`関数の実装例

以下は、ShopifyのApp Bridgeを用いて商品を選択する機能を実装する一例です。

```javascript
async function selectProduct() {
  try {
    const products = await window.shopify.resourcePicker({
      type: "product",
      action: "select",
    });
    console.log(products);
  } catch (error) {
    console.error("Error selecting products: ", error);
  }
}
```


この関数は、awaitキーワードを使ってwindow.shopify.resourcePickerメソッドを非同期に呼び出し、ユーザーが商品を選択するUIを提供します。

### `shopifyApp`を使用したShopify Admin APIの設定
Shopify Admin APIへのアクセスに必要なAPIキー、APIシークレット、スコープ、アプリURLなどの設定は、以下のように行います。


```javascript
import { shopifyApp } from "@shopify/shopify-app-remix/server";

const shopify = shopifyApp({
  apiKey: process.env.SHOPIFY_API_KEY,
  apiSecretKey: process.env.SHOPIFY_API_SECRET,
  scopes: process.env.SCOPES.split(","),
  appUrl: process.env.SHOPIFY_APP_URL,
});

export default shopify;
```
p5.js Web Editor上で Gamepad API を使う： DualShock 4  を使ったシンプルな接続確認・ボタン押下判定

今回の内容は、以下の記事で取り扱ってきた「Gamepad API」の話です。

●【完走賞ゲット-11】gamecontroller.js を p5.js Web Editor上で使ってみる（DualShock 4 との組み合わせ） - Qiita
　https://qiita.com/youtoy/items/1cf1fe244d992456140f

●【完走賞ゲット-13】p5.js Web Editor上でボールが跳ね返る時に DualShock 4 を振動させる（gamecontroller.js での実装） - Qiita
　https://qiita.com/youtoy/items/c4d3b6fde5365090a5de

Gamepad API は、ゲーム用のコントローラーをブラウザで扱える API です。

上に掲載していた記事では、API を直接使うのではなく「gamecontroller.js」というライブラリを用いていました。

今回は、API を直接扱ってみようと思います。

## 今回利用する環境・参照する情報

### 今回利用する環境
今回、開発・実行環境は自分がよく使っている p5.js Web Editor を使います。

また、ゲームコントローラーは冒頭に掲載した記事でも使っていた「DualShock 4」を用います。

### 参考にするサイト
Gamepad API を扱うにあたって、以下の MDN のページを参考にして進めます。

●ゲームパッド API の使用 - Web API | MDN
　https://developer.mozilla.org/ja/docs/Web/API/Gamepad_API/Using_the_Gamepad_API

## 実際に試してみる
それでは、実際に試していきます。

### 接続確認
まずは、簡単な接続確認です。

MDN のサイトに掲載されている以下を用います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/2b411b00-e9a8-eeed-7c02-17bde7ae4518.png)

p5.js Web Editor上では、sketch.js の setup() で呼び出せば良さそうです。

```javascript
function setup() {
  createCanvas(400, 400);
  window.addEventListener("gamepadconnected", (e) => {
    console.log(
      "Gamepad connected at index %d: %s. %d buttons, %d axes.",
      e.gamepad.index,
      e.gamepad.id,
      e.gamepad.buttons.length,
      e.gamepad.axes.length
    );
  });
}

function draw() {
  background(220);
}
```

プログラムを実行して、DualShock 4 を操作すると、以下の出力が得られました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/32788346-4bd4-159f-33de-274f9b93abae.png)

### ボタン関連
次に、ボタン押下の状態を取得してみます。

#### テストサイトを使った確認
念のため、過去の記事でも使った以下のテスト用サイトを使い、事前の動作確認を行います。

●Gamepad Tester - Check Controllers and Joysticks Online
　https://hardwaretester.com/gamepad

例えば「×」ボタンを押してみると、B0 という部分が変化するのが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/8670d6d1-1e35-140f-23e4-6b2d39dc95c9.png)

#### p5.js Web Editor上で試す
次に p5.js Web Editor上で試してみます。

実装をするにあたり、以下のページの内容を参考にしました。

●GamepadButton: pressed プロパティ - Web API | MDN
　https://developer.mozilla.org/ja/docs/Web/API/GamepadButton/pressed

実装した内容は以下のとおりです。

```javascript
function setup() {
  createCanvas(500, 400);
}

function draw() {
  const gp = navigator.getGamepads()[0];
  if (gp?.buttons[0].pressed) {
    background(100, 150, 200);
  } else {
    background(220);
  }
}
```

これを試した結果は、以下の通りです。
ボタン押下時に、キャンバスの背景色が変わっているのが分かります。

<iframe width="560" height="315" src="https://www.youtube.com/embed/F1JFmNvSyDg?si=dm0fvGXfOIW2H9aP" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

とりえあず、シンプルなお試しが行えました。

## 余談： 気になるライブラリ
昨年情報を見かけたものの、まだ試せていない Gamepad API関連のライブラリがあるのですが、機会があればこちらを試してみたいと思っています。

https://twitter.com/0310lan/status/1713886757874237521
BedrockのClaude 3でストリーミング出力するシンプルなコード

# Claude 3がアツいですね

GPT-4を超えたと話題の生成AI、Claude 3シリーズ。
私の開発組織でも全力でキャッチアップに取り組んでいます。

https://qiita.com/minorun365/items/e6f3aa71f5e1bdf21139

AWSのBedrockでも利用可能になるや否や、ものすごい量のQiita記事が出ていますが意外とシンプルなストリーミング出力のサンプルコードがなかったので紹介しておきます。



# シンプルなコード例

AWSの公式ドキュメントを参考にしています。

https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html

```py:stream.py
# Python外部ライブラリのインポート
import json
import boto3

# Bedrockクライアントの作成
bedrock_runtime = boto3.client('bedrock-runtime')

# リクエストボディを定義
body = json.dumps({
   "anthropic_version": "bedrock-2023-05-31",
   "max_tokens": 1000,
   "messages": [
       {
           "role": "user",
           "content": [{"type": "text", "text": "いろは歌を教えて"}]
       }
   ]
})

# モデルを定義（Claude 3 Sonnet）
modelId="anthropic.claude-3-sonnet-20240229-v1:0"

# レスポンスを定義
response = bedrock_runtime.invoke_model_with_response_stream(body=body, modelId=modelId)

# ストリーミング出力
for event in response.get("body"):
   chunk = json.loads(event["chunk"]["bytes"])
   if chunk['type'] == 'content_block_delta' and chunk['delta']['type'] == 'text_delta':
       print(chunk['delta']['text'], end="")

# ストリーミング終了後に改行
print()

```

:::note info
上記のコードは、以下のAWSドキュメントで提供されているサンプルコードをベースに改変したものです。

© Amazon.com, Inc. or its affiliates. All Rights Reserved.
https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html

- 改変箇所： コードの簡略化とリファクタリング、プロンプトの変更

オリジナルのサンプルコードは Apache License, Version 2.0（ https://www.apache.org/licenses/LICENSE-2.0 ）のもとで提供されています。
:::


# 実行結果の例

ストリーミングで少しずつ出力されました！

```
$ python3 stream.py 
いろは歌は、古くから日本で使われている五十音の順序を示した歌です。

いろはにほへと
ちりぬるを
わかよたれそ
つねならむ
うゐのおくやま
けふこえて
あさきゆめみし
ゑひもせす

この歌は、あい(あいう)、かきくけこ、さしすせそ...と五十音の順番に並んでいます。
平安時代に作られたと言われており、当時の日本人が自然を愛でながら五十音を覚えるのに役立ったそうです。簡潔でリズミカルな歌詞は、
```
AirflowのDockerイメージにgcloud SDKを追加する。

# モチベーション
airflowをdockerコンテナ上で動かしたい。
コンテナの中にあらかじめgcloud SDKを入れておきたい。

# 環境
Ubuntu（WSL）

# Dockerfile
```Dockerfile
FROM apache/airflow:2.8.1
USER root
RUN sudo apt-get update \
     && sudo apt-get install apt-transport-https ca-certificates gnupg curl
RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list \
     && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg \
     && apt-get update -y \
     && apt-get install google-cloud-sdk -y
USER airflow
```

シンプルに、airflowのイメージをもとに、gcloud SDKの公式ドキュメントに基づいてインストール作業を追加しています。
上記はDebian/Ubuntu用のコードですので、他のOSについてはGoogle公式ドキュメントを参照してください。

https://cloud.google.com/sdk/docs/install?hl=ja

# インストール後
公式ドキュメントでは、
```bash
gcloud init
```
するように指示がありますが、airflowをユーザーアカウントで稼働させる事はないと思うので、ひとまず必要ありません。
GCのサービスにairflowからアクセスする際に認証が必要ですが、その認証はサービスアカウントの権限借用で行うことになります。

https://qiita.com/Lintaro/items/88149d78772bc0c8465b

airflowは（docker-compose.yamlを通じて）下記のように複数のサービスが構成されます。

- airflow-scheduler
- airflow-worker
- airflow-triggerer
- airflow-webserver
- airflow-redis
- airflow-postgres

実際にはサフィックスとして「-1」などの番号が打たれます。また、redisやpostgresなどは採用するDBによって異なります（…とはいえ多くの場合はredisとpostgresではないでしょうか）。
このうち、ADC（デフォルト認証）が必要になるのは、

- scheduler
- worker
- triggerer
- webserver

の2つのようです。（workerだけでいいように思いましたが、実際には他のサービス（サーバー）でもADCを設定しないとDAGがうまく動きませんでした。）

# 参考

https://shase428.hatenablog.jp/entry/2022/06/21/183748
【Python】issubsetの使い方と注意点。サンプルコードで解説

# 概要
Pythonの`issubset`（イズサブセット）を使ってみたので、紹介。

`issubset`とは、あるセットが他のセットの部分集合（すべての要素が他のセットに含まれている）であるかどうかをチェックするためのメソッド。

実際にコードを見てみるとわかりやすいです。

# サンプルコード解説

```py
# セットの定義
set1 = {1, 2, 3}
set2 = {1, 2, 3, 4, 5}

# set1がset2の部分集合であるかチェック
is_subset = set1.issubset(set2)

print(is_subset)  # Trueを出力
```

上記の場合、`set1`が`set2`の部分集合であるかをチェックしています。
`set1`の全ての要素が`set2`に含まれているため、`True`ですね。

### リストに対して使用する場合は`set()`を使う

```py
# リストの定義
fruits_in_fridge = ['apple', 'banana', 'lemon', 'mango', 'grape']
fruits_for_dinner = set(['apple', 'lemon', 'grape'])

# セットがリストの部分集合であるかチェック
is_subset = fruits_for_dinner.issubset(fruits_in_fridge)

print(is_subset)  # Trueを出力

```

上記のようにリストでも同様にチェックします。

一点、注意なのは、`issubset()`はPythonのセット（`set`）型のメソッドであり、リスト（`list`）型には存在しません。そのため、リストに直接適用しようとすると以下のエラーになります。

```
AttributeError: 'list' object has no attribute 'issubset'
```

上記コードのように、セットの形にしてあげる必要があります。セットとは、重複する要素を持たず、順序も保持しない、データ型のこと。何度も`print`していると毎回中身の順番が異なることがわかります。

> Python には、 集合 (set) を扱うためのデータ型もあります。集合とは、重複する要素をもたない、順序づけられていない要素の集まりです。
引用元：https://docs.python.org/ja/3/tutorial/datastructures.html#sets


この理由により、`issubset()`はセットがハッシュベースのデータ構造であるため、要素の存在チェックが高速に行える、と言われています。

リストはセットに変換してあげると、集合の関数も使えるようになります。
上記の`fruits_for_dinner`のタイプを出力すると`<class 'set'>`と出てくるので、セットになっていることがわかりますね。

### 「空集合」の場合は、部分集合になる

ちなみに、以下のように、「空集合」の場合であっても、部分集合という結果になります。

```py
fruits_in_fridge = ['apple', 'banana', 'lemon', 'mango', 'grape']
fruits_for_dinner = set([])

# セットがリストの部分集合であるかチェック
is_subset = fruits_for_dinner.issubset(fruits_in_fridge)

print(is_subset)  # Trueを出力
```

### 部分集合ではない場合は`False`を返す

以下のように部分集合にならない`melon`を対象にすると、もちろん結果は`False`になります。

```py
# リストの定義
fruits_in_fridge = ['apple', 'banana', 'lemon', 'mango', 'grape']
fruits_for_dinner = set(['melon'])

# セットがリストの部分集合であるかチェック
is_subset = fruits_for_dinner.issubset(fruits_in_fridge)

print(is_subset)  # Falseを出力
```

### 辞書型に使う場合はキーに対してセットの操作を行う
辞書型には直接`issubset()`を使用することはできませんが、辞書のキーに対してセットの操作を行うことは可能です。

```py
# 辞書の定義
dict1 = {'a': 1, 'b': 2, 'c': 3}
dict2 = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

# 辞書のキーのセットを取得
set1 = set(dict1.keys())
set2 = set(dict2.keys())

# set1がset2の部分集合であるかチェック
is_subset = set1.issubset(set2)

print(is_subset)  # Trueを出力
```

上記のように、`dict1`と`dict2`のキーのセット(`{'a', 'c', 'b'}`)を取得し、その後で`issubset()`メソッドを使用しています。

### `<=`演算子を使う
部分集合かどうかを確認するためには、以下のように`<=`演算子を使うこともできます。

```py
# セットの定義
set1 = {1, 2, 3}
set2 = {1, 2, 3, 4, 5}

print(set1 <= set2)  # Trueを出力
```

### 参考： Djangoで活用できたケース

実際に使えたケースとしては、以下のような場合でした。
こちらはDjangoです。特定の条件で`SampleModel`モデルから取得したデータの中に、期待したデータが含まれているか確認するというケースです。

```py
list_fruit_cd = SampleModel.objects.filter(sample_cd__in=list_sample_cd).values_list('fruit_cd_id', flat=True)

if set(['xx', 'xxx', 'xxxx']).issubset(list_fruit_cd):
    ## 処理...
```