OmniAICreator/Qiita-1.07M huggingface dataset:
日本で働く: 異文化間コミュニケーションの壁をどう乗り越えるか

　私は現在、多国籍、多文化の従業員を持つグローバル的な企業で働いています。またBrseというポジションで、主にオフショアプロジェクトに携わっているため、コミュニケーション、特に異文化コミュニケーションは非常に重要な要素です。
そこで今日は、日本企業で働く外国人として感じる、日本人の同僚との“コミュニケーションの壁”をご紹介し、その壁をどのように越えるかを自分で考えたことをみなさんに共有したいと思います。

 　さらに、日本人の方に向けて、もっと外国人の同僚とスムーズにコミュニケーションできるように、覚えておきたいポイントも共有したいと思っています。

## 1. 見えない壁
### ■言語の障壁
 私は数年日本語の勉強を続けていますが、なかなか日本語が難しいと感じています。

なぜ日本人とうまく話せないのかをよく考えてみると、以下の問題があることに気づきました。

 #### 聞き取りきれない
　日本で働いている外国人の日本語の能力は、日本語能力試験のだいたい~N2レベルだと思います。そのレベルであれば、日本語をかなりよく使えて、普通のコミュニケーション（生活のコミュニケーション） について問題なくできると思います。
　しかし、日本人の話す日本語を理解するためには、さらなる壁を越えなければなりません。職場では、日本人の同僚がよく長い文章を使ったり、難しい言葉を使ったりします。また、話すスピードが早いことがあります。
　そのために、ある程度日本語の能力を持っている外国人の方でも、聞き取れず困ることが多いと思います。

#### 聞き取ったと思ったけど、実は別の意味に理解してしまう
さらに、これはちょっと危ないケースですよね。これもやっぱり日本人とコミュニケーションをするときに、よくあるケースです。
前述した通り、外国人は、日本人の同僚が話した際、内容を100％聞き取ることは難しいです。そのため、聞き取れた80%、または70％の内容から、残りの部分を判断します。そうすると、判断が少しずれ、話がかなりずれることがあります。

同じ言語を話し、似たような文化背景で育ってきた日本人同士では、１から10まで話さなくても、相手の言いたいことが何となくわかることがよくあります。
日本には「空気を読む」「行間を読む」という言葉があるように「言葉でコミュニケーションを取らずとも、相手の考えや気持ちを汲み取る」という日本独特のコミュニケーション方法もあります。
しかし、異なった文化で育った外国人材にとっては、言葉で伝え合わずして、これらの情報をキャッチすることはなかなか難しいことです。


### ■コミュニケーション力の問題
日本で働いている外国人はだれでもコミュニケーションの能力が高いわけではありません。
その上、母国語ではない日本語を考えて、テンポよく話さないといけないから、話している内容が混乱するケースが多いです。
混乱してしまうと、本来もっている日本語の能力を発揮できなくなるので、うまく話せなくなってしまいます。

## 2.壁を越える

壁は多くて、高いですが、越えないといけません。

ただ、どうやって越えるか？人によって、いろいろな方法があると思いますが、自分の経験から、以下にいくつかのポイントを共有したいと思います。

### ■日本語の勉強を積極的に続けること
日本語の勉強は必要だと思います。いつでも、どこでも（職場、生活、日本語クラス、また自習など）多くの言葉、文法をできる限り勉強したほうがいいと思います。
しかし、勉強に終わりはありません。勉強できたことをよく活かして、話していきましょう。

### ■大切な話なら、終わりにメインの内容を復唱する
大切な話なら、話の終わりに、メインの内容が漏れないように復唱して、相手に確認してもらうと安心だと思います。

### ■話したい内容を準備すること
事前に話の内容が準備・整理できたら、話す時に、自信を持って、あまり混乱せずに、スムーズにコミュニケーションできると思います。

### ■日本の文化を理解するだけでなく、同僚を理解する
日本で働いている外国人が日本の文化を理解しなければならないことは当然だと思います。
ただ、文化理解だけではなくて、できる限り日本人の同僚を理解して、スムーズにコミュニケーションできるようになった方がいいと思います。また良い関係を構築しましょう。

### ■自分のコミュニケーション力をアップするべき
日本語のひとつひとつに問題がなくても、伝え方が良くないと、話したいことをなかなか伝えられないということを経験しました。
難しい問題だと思いますが、ある程度効果があるいくつかのTipsを共有したいと思います。

- もっと簡単な言葉で考える
- 伝えたい内容(一番大切な内容)をまず伝える
- 難しい話しなら、小さく分割して、１つずつ説明する

## 3.日本の同僚のみなさまにお願いしたいこと
外国人の方々に向けたTipsを書いてきましたが、さらに、日本人の同僚のみなさまにも、意識的に心掛けることで、外国人社員とのコミュニケーションをスムーズに進められるコツを紹介しようと思います。

- 思っているよりも、さらにゆっくり、はっきり発音する
 

- 一つの長文よりも、複数の短い文にして伝える
→ 外国人にはより話の内容が分かりやすくなります

- 主語や目的語を明確にするように意識する
- よりわかりやすい、シンプルな言葉を選ぶ
→意味が同じ（似てる）言葉がたくさんあると思いますが、その中で一番わかりやすい（普段よく使われる言葉）を使ったほうがいいと思います。とくに打ち合わせをするときです。
- 打ち合わせなどの結果を復唱させる
→ 打ち合わせの際、話のポイントなどについて、外国人社員に声を出して復唱してもらいます。そうすると、積極性を養えて外国人社員が質問しやすくなる効果があると思います。
- 一緒に働いている外国人の同僚の国を少しだけでも知る
- 相手の日本語能力を理解する
→ 相手の日本語能力を理解することで、それにあった話し方・言葉を意識できるようになると思います。

 
## 4.最後に
日本で働いている外国人には、コミュニケーションの壁がたくさんあります。

 
苦労すると思いますが、「もっとスムーズにコミュニケーションできるようになりたい気持ち」が大事です。それを持って、１つずつ問題を改善しながら、紹介した壁をドンドン越えていきましょう。

 

また、一緒に働く日本人の同僚からの理解や支援も大事だと思います。ご紹介したTipsを使ってコミュニケーションがスムーズにできると、より良い結果がでると思います。

 

コミュニケーションはよくキャッチボールに例えられます。伝えたいことを相手に投げたり、相手から受け取ったりすることによって情報交換し、お互いを分かりあうことですね。

つまり、1人だけで頑張ってもコミュニケーションになりません。

会社では日本人社員と外国人社員がスムーズにコミュニケーションできるために、相互理解したり文化や言葉の障壁をひとつずつ越えたり、お互いに協力することは大事です。それができれば、素敵なグローバル企業への第一歩になると思います。

一緒に頑張りましょう!
pythonで双曲線の書き方

# 特殊相対論でもよく出てくる双曲線。

初めに設定を描く。
文書は書くのは今回初めてでたぶん汚いコードだけどなんかあれば
無視してください。あくまでも参考程度の
感想文より技術文書のほうが書きやすいけどｗ
まずは設定
```
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 10))
plt.grid()
plt.xlim(-3,3)#x=3からx=3までの範囲を表示
plt.ylim(-3,3)
```
次にx軸,y軸
```
xx=np.linspace(-5,5)

#ｙ軸
y=0*xx
plt.plot(xx,y)

#x軸
xx=np.repeat(0,50)#xを５０個0を作る
y4=np.linspace(-5,5)
plt.plot(xx,y4)
```
次に二次曲線
```math
\frac{x^2}{a^2}-\frac{y^2}{b^2}=1
```

移行すると
```math
y^2=\frac{b}{a}\sqrt{x^2-a^2}



```




```
"""
二次曲線を描く
"""
import math


#y=sqrt(x*x-1)
def square_root_function(x):
    return np.sqrt(x*x-1)

#
def square_root_function2(x):
    return np.sqrt(x*x-2*2)


# xの範囲を指定 (xは非負である必要があります)
x_values = np.linspace(1, 5, 100)

# 平方根関数の計算
y_values = square_root_function(x_values)

# グラフの描画
plt.plot(x_values, y_values, label='y = sqrt(x)')
plt.plot(x_values, -y_values, label='y = sqrt(x)')

plt.plot(-x_values, y_values, label='y = sqrt(x)')
plt.plot(-x_values, -y_values, label='y = sqrt(x)')

```
ここまで
![f1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354057/55dc2b37-8c18-d057-da56-ce9d22e001dc.png)
双曲線をもう２つ書く
a=2 b=2とa=1.5とb=1.5の時の曲線

```
a=2
b=2
x = np.linspace(2, 5, 100)
#x*x/a/a-y*y/b/b=1
y=b/a*np.sqrt(x*x/a/a-b/a)
# グラフの描画
plt.plot(x, y)
plt.plot(x, -y)
plt.plot(-x, y)
plt.plot(-x, -y)

a=1.5
b=1.5
x = np.linspace(1.5, 5, 100)
#x*x/a/a-y*y/b/b=1
y=b/a*np.sqrt(x*x/a/a-b/a)
# グラフの描画
plt.plot(x, y)
plt.plot(x, -y)
plt.plot(-x, y)
plt.plot(-x, -y)


#y=x y=-x
xx=np.linspace(-3,3)
plt.plot(xx, xx, label='y = sqrt(x)')
plt.plot(xx, -xx, label='y = sqrt(x)')
```
![f2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354057/19fbb1e6-b867-5347-b97d-ffe521b2c573.png)
最後に
双曲線から接線の式を描く
x=2での接線
双曲線の式は
```math
\frac{x^2}{1^2}-\frac{y^2}{1^2}=1
```



#------------------------------------------
#双曲線上で接する直線
#x=2での接線
#式はy-y1=x1/y1(x-x1)
#------------------------------------------
xx=np.linspace(0,3)
y=2/3*1.732*xx-1.732/3
plt.plot(xx, y)

plt.title('curve double')

plt.grid(True)
plt.show()

```
![f3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354057/9a550ec6-bbeb-976b-6c32-54ad5481838a.png)
eagle 自動インポート



https://romptn.com/article/15861#toc3

をやれば、以下の設定は必要なし。



# 自動インポートでハマった

説明もわかりづらいけど、まぁ、メモ。

ctrl + k  で環境設定を開く

まずは自動インポートをオフにする。

aipic_li を作成

フォルダ名は削除してそのまま保存。

デスクトップに ai_pictest を作成。

ctrl + k  で環境設定を開く

自動インポートで 自動インポートにチェックをいれ、ai_pictestフォルダを選択

すると、 ai_pictestの中に aipic_li というフォルダができる。

この中に画像を入れることで、自動でインポートされていく
Salesforce認定アドミニストレーターを受験することになったから過去問を解いてアウトプットしていこうと思う。Q1 ~ Q10

4月の頭にSalesforce認定アドミニストレーター資格試験を受験することになったので, 過去問を解いて, そのアウトプットというかメモがわりに執筆していこうと思う.

# Q1. Salesforceのレポート機能を使用して, 営業チームが顧客エンゲージメントの効果を分析するために, 管理者が設定することが推奨されるレポートタイプとは？
A: キャンペーンレポート
### 解説
キャンペーンレポートは, マーケティング活動を通じた顧客エンゲージメントの効果を分析し, どのキャンペーンが最も効果的であったか, どのようにリードが生成されたかを管理するのに最適なツールである.
よって, 設問の答えは「キャンペーンレポート」.

# Q2. システム管理者は, ログイン試行の失敗が特定の回数を超えた場合に, Salesforce組織からユーザーをロックアウトすることは可能か？
A: 可能
### 解説
システム管理者は「パスワードポリシー」の設定を通じて, ログイン試行の失敗が特定の回数を超えた場合にユーザーをSalesforce組織からロックアウトする機能を有効にすることができる.

# Q3. Salesforceユーザーのグローバルチームをサポートす管理者は, 会社の設定を構成するよう求められた. 管理者が構成する必要がある2つのオプションとは？
A: 1 現地通過 2 デフォルト言語
### 解説
グローバルチームをサポートする際には, 現地に合わせて通貨を設定する必要がある.さらに, デフォルト言語の設定をすることで, 各地のSalesforceユーザーが自分の言語でSalesforceを使用できるようになる.

# Q4. 管理者は, Salesforce用にカスタマイズされたページを作成する必要がある. 管理者がLightningアプリケーションビルダーを使用して作成およびカスタマイズできるページのタイプは？
選択肢 : 1 ユーザーページ　2 ダッシュボードページ 3 レコードページ 4 アプリページ
A: 3 レコードページ 4 アプリページ
### 解説
Lightningアプリケーションビルダーを使用して, ユーザーページとダッシュボードページを直接作成したり, カスタマイズすることはできない.
Lightnignアプリケーションビルダーを使用して特定のオブジェクトのレコードをカスタマイズすることができる. これにより, 管理者は特定のオブジェクトのレイアウトをカスタマイズしてユーザーのニーズに合わせたページを作成できる.
また, アプリケーションページを作成することもでき, これによって管理者は特定のアプリケーションを含むカスタマイズされたページを作成し, ユーザーがアクセスする際のエクスペリエンスを向上させることができる.

※初心者の僕にとって「レコードをカスタマイズする」という行為のイメージが, この文言だけではイメージできなかった. 「フィールドの追加」や「編集」のことをカスタマイズするというらしく, 言われてみたら,　まあ, そうだよな...と納得.

# Q5. プロファイルを編集するには, どの管理権限が必要か？
A: セットアップと構成の表示, ユーザーの管理とアプリケーションのカスタマイズ
### 解説
プロファイルを編集するには, セットアップと構成にアクセスする権限, ユーザーを管理する権限およびアプリケーションのカスタマイズを行う権限が必要. これらの権限を持つことで管理者はプロファイルの詳細を編集でき, ユーザーへのアクセス権を調整することができる.

# Q6. 共有のキーワードを検索すると, 2人の異なるユーザーが同じ検索結果を取得しますか？
A: いいえ（というか, そうならない可能性がある）
### 解説
Salseforceでの検索結果は, ユーザーのプロファイル, 役割, アクセス権およびセキュリティ設定に基づいてフィルタリングされている. なので, それぞれのユーザーのアクセス権によって得られる検索結果が同じとはならない可能性がある.

# Q7. Salesforceでの新しい営業プロセスの導入に際して, 管理者が設定するべき重要な機能は?
A: 新しい営業プロセスに基づいて商談ステージをカスタマイズする.
### 解説
新しい営業プロセスを導入する際には, そのプロセスを反映するように商談ステージをカスタマイズすることが最も重要である.

# Q8. カスタムアプリを作成するプロセスはどのようなものですか？
A: 新しいアプリケーションを作成し, ロゴを選択肢し, プロファイルを割り当てる
### 解説
カステムアプリを作成するプロセスには, まず新しいアプリケーションを作成する. その過程でアプリケーションの識別とブランディングのためにロゴを選択し, アプリケーションへのアクセス権を持つユーザーを管理するために特定のプロファイルを割り当てることができる.

# Q9. Selaeforce Lightning Experienceにおいて, ユーザーエクスペリエンスとデータの整合性を向上させるために管理者が利用することが推奨される機能はどれ？
A: バリデーションルールを設定して, データ入力時の誤りを最小限に抑える.
### 解説
バリデーションルールの設定によって, ユーザーによるデータの入力や更新の際の基準を設定できる. これにより, 不正値の入力を防ぎ, データの整合性を保つことができる.

# Q10.レポートと同じレポートに基づくダッシュボードで, ユーザーが異なるデータセットを表示することは可能ですか？
A: 可能
### 解説
「実行ユーザー」の設定をすることで, 異なるユーザーの視点や役割に合わせたデータをダッシュボードで表示することができる.
三項演算子について

## はじめに
　個人的に「三項演算子」について苦手意識があったので、今回はあえてそれに触れてみます。
## 環境
ruby 3.14

rails 7.0.3.1

## 三項演算子って？
 **条件式をif, elseを使わないで書いてしまえるもの。**

複数に渡ってかかなればならないコードも、これを使えば短いコードで済むのですっきりします。

コードにすると次のようになリます。
```
条件式 ? 正しいとき : 正しくないとき
```
これをif,elseで書くとすると次のようになります。

```ruby
  if 条件式
    正しいとき
  else
    正しくないとき
  end
```
以上のように短いコードで済むことが分かります。

ではこれはどのような時に使えば良いのでしょうか？

## 例
　作っているもの→　"ブログを作成するサイト"
　コードを書く場所→ Articleモデル

 また
”記事(Article)を『下書き(draft)・公開(published)・公開待ち(publish_wait)』としてstateカラムに分類している状態”

加えて、

publishde?メソッドとして
```ruby
def publishable?
    Time.current >= published_at
  end
```
と用意してあるとします。

ここに、“公開可能か判断させるメソッド"を作りたいとします。

これをif文で書くとすると、

```ruby
def adjust_state
  self.state = if publishable?
                   :published       #公開
                 else
                   :publish_wait    #公開待ち
                 end
  end
```

これを三項演算子で書くとしましょう。

```ruby
def adjust_state
    self.state = publishable? ? :published : :publish_wait
  end
```

だいぶすっきりしました。

## 補足
　複雑なロジックなど、if文のままの方が良い場合もあるようです。
例えば、

```ruby
def adjust_state
  return if draft?
  self.state = if publishable?
                   :published       #公開
                 else
                   :publish_wait    #公開待ち
                 end
  end
```
このように **return if draft? (stateがdraftの場合はadjust_stateから抜け出させる)**
という条件が盛り込まれている場合は、三項演算子でそのまま表現する事は難しいようです。
 
 しかし、シンプルに**AでないならB**という事を表現したい場合には、三項演算子を使いこなせればコードの短縮化に貢献出来て便利そうです。

## 参考にさせていただいた記事

https://pikawaka.com/ruby/ternary-operator

https://qiita.com/lasershow/items/160c854e4256ba596ec5

https://osamudaira.com/353/
Vertex AI Pipelineのimporterについて

## はじめに
以前Vertex AI Pipelineを構築して、それぞれのコンポーネントの詳細は今後の課題にしていたので、今回はImporterを掘り下げたいと思います。パイプライン自体は[サンプルコード](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/official/pipelines/lightweight_functions_component_io_kfp.ipynb)をColabで動かして構築しています。


![VertexAI_Pipeline.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/e72e9b84-359f-24a3-7301-464db3b611d4.png)

前回の記事

https://qiita.com/Pretzelisa/items/83df93d9028a4c15d448


## Importerとは

importerでは受け取った情報をアーティファクトとしてパッケージ化します。
アーティファクトはコンポーネントの入出力になるエンティティまたはデータです。アーティファクトとなり得るものは幅広く、モデル、入力ファイルなどがあります。

(参考)Vertex AI用語集

https://cloud.google.com/vertex-ai/docs/glossary?hl=ja

パイプライン構築のコード内でimporterを定義しており、今回は`artifact_uri=gs://hoge/shakespeare.1txt`、`artifact_class=Dataset`となっています。
Cloud Storageにあるshakespeare1.txtの場所を指定して、アーティファクト化しています。

GUIでimporterのノード情報を見てもshakespeare1.txtが入力パラメータとなっています。
(ちなみにshakespeare1.txtの中身はシェイクスピアの「ヘンリー六世」の一節です)

![Importer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/c761de5a-6347-f20d-d475-0dbcae0b4f82.png)

下図でimporterと繋がっている四角がアーティファクトで、コード内で定義されている通りDataset型です。

![Artifact_VertexAI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/c36dac46-0a7b-8a6a-a5ce-034725ead66c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/d95e9d9f-a666-a695-d2ce-75066427c593.png)

Cloud Storageのファイルをアーティファクトせずにそのままトレーニングに突っ込んだりできないのかしらと思いましたが、「Google Cloud パイプライン コンポーネントの概要」に、「入出力に標準のアーティファクト タイプを使用する一貫したインターフェースが提供されます。これらの標準アーティファクトは Vertex ML Metadata で追跡されるため、パイプラインのアーティファクトのリネージを簡単に分析できます。」

…とあるので各コンポーネントにはアーティファクトを入出力とするのがセオリーのようです。.txtをそのままトレーニングに突っ込めるか確かめてはいないですが、パフォーマンスを比較するにもメタデータが重要なので、アーティファクト化して後から追いかけられる形にしておくのが無難ですね。

https://cloud.google.com/vertex-ai/docs/pipelines/components-introduction?hl=ja

## おわりに
Colabで最初から最後まで全て実行、とやるとimporterの定義のところはあっという間に終わってしまうので、最初に構築したときは何を定義しているのか全く分からずでした。

importerについての解説があまり見つからず、パイプライン構築用のコードのコメントやVertex AIのドキュメントのちょっとした記述を集めて整理してみましたが、Vertex AI PipelineでデータをCloud Storageから持ってくるステップを具体的にイメージできるようになりました。
せんせー、触覚フィードバック技術ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、触覚フィードバック技術ってなに？

# 触覚フィードバック技術とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

触覚フィードバック技術は、コンピューターゲームやバーチャルリアリティ（VR）の世界で、リアルな感覚を体験できるようにする技術だよ。

例えば、ゲームの中で岩を持ち上げようとすると、コントローラーが重たくなって、まるで本当に岩を持ち上げているような感覚が得られるんだ。

これは、コントローラーの中に振動を起こす部品が入っていて、その振動の強さや長さを変えることで、様々な触感を再現しているんだよ。

また、VRの世界で物に触れたときに、指先に圧力を感じさせる技術もあるんだ。これは、指にはめる特別な手袋を使って、空気圧や電気刺激で圧力を与えているんだよ。

将来は、触覚フィードバック技術を使って、遠く離れた人と握手をしたり、ネットショッピングで商品の手触りを確かめたりできるようになるかもしれないんだ。

でも、本物そっくりの触感を再現するには、まだまだ研究が必要なんだ。

触覚フィードバック技術は、バーチャルの世界により没入感を与えてくれる、面白い技術だね。
Jetpack composeでうまいことエラーハンドリングをしたい

# はじめに
今回はJetpack composeで実装するときに複数種類のエラーをハンドリングするときのアイデアを出していこうと思います
### 本文
今主流となっている`seald class`でUIの状態を分岐させてそれによって出すCompose部品を出しわけるのが今の主流化と思いますが、そこにネスとしてエラー用の`seald class`をはやすというものです。

そうすることで読み込みのエラーや状態更新のエラーなどを分岐させることが可能になりそれにより表示を分岐させることもできます。

ただし、ここで懸念すべきところは分岐処理が増える分Compose関数内のコードが多少なりとも増えてしまうという点です
### 最後に
今回はアイデアの提案のみですが、何か改善点などがあればコメントいただけると参考になります
Salesforceで日付から曜日を取得しよう～WEEKDAY関数

こんにちは
本橋孝昭です

今回はSalesforceの数式項目「WEEKDAY」関数について解説します


# WEEKDAY関数とは

WEEKDAY関数を使えば特定の日付項目の曜日を確認し[1]から「7」を表示させます
1は月曜日、7は日曜日を表します

※参考ヘルプ
https://help.salesforce.com/s/articleView?id=000384282&type=1

しかしながら、通常のWEEKDAY関数だと数字のみが表示されます
なので例えば

>WEEKDAY(test01__c)
※test01__cは日付項目のAPI参照名とする

のような数式の場合、返す値は1や2となり、通常であればわかりにくいので
「1は月曜日と表示させたい」という話も多く出てきます


# WEEKDAY関数　応用例


そこで、WEEKDAY関数を使い月曜日から日曜日と返す数式は以下となります

>IF(ISBLANK(test01__c),"空欄です",
CASE(WEEKDAY(test01__c),1, "日曜日",
2, "月曜日",
3, "火曜日",
4, "水曜日",
5, "木曜日",
6, "金曜日",
"土曜日"))
※test01__cは日付項目のAPI参照名とする

このような数式項目（テキスト型）を使えば、
日付項目の日付が何曜日であるか　を返すことが出来るのでとても便利です
クラスの作成とクラスの継承

クラスの作成とクラスの継承を使ってプログラムを作りました。

```Ruby
class User
  attr_accessor :name
  @@count = 0
  VERSION = 1.1
  def initialize(name)
    @@count += 1
    @name = name
  end

  def sayHi
    # puts "私は#{@name}です"
    puts "私は#{self.name}です"
    # puts "私は#{name}です"
  end

  def self.info
    puts "User Class #{@@count} Instance Count"
    puts "#{VERSION}"
  end
end

class AdminUser < User
  def sayAdminUser
    puts "Hi! AdminUser #{name}"
  end
end

mai1 = User.new("白石麻衣")
mai1.sayHi
mai2 = AdminUser.new("白石麻衣")
mai2.sayAdminUser
AdminUser.info

```
resolvingAgainstBaseURL 解説: Swiftで絶対URLと相対URL

# 記事を書くに至った動機
URLのパラメーターを取得する際に
URLComponentsとinitializer内の第二引数のresolvingAgainstBaseURLは何だろうと気になった為、記事にしました。

```swift
init?(
    url: URL,
    resolvingAgainstBaseURL resolve: Bool
)
```


# URLComponentとは
カスタムURLをスキームを利用した際に、
```swift
struct URLComponents
```
URLComponents を使用することで、URLを安全に組み立てたり分解したりすることが可能になります。

下記のように
```swift
init?(string URLString: String)
```
Stringから初期化してもいいのですが、
URLであることが保証されるresolvingAgainstBaseURL付きのイニシャライザを利用した方が安全かと思います。

# resolvingAgainstBaseURLについて
本題ですが、
resolvingAgainstBaseURLをtrueにすると相対URLを絶対URLに変換する試みが行われます。
具体的にtrueの場合とfalseの場合の違いを見ていきます。

#### trueの場合
相対URLであれば、それをベースURLに対して解決し絶対URLを生成します。
```swift
if let baseURL = URL(string: "https://example.com/directory/"),
   let relativeURL = URL(string: "subdirectory/file", relativeTo: baseURL),
   let urlComponents = URLComponents(url: relativeURL, resolvingAgainstBaseURL: true) {
    print(urlComponents.url?.absoluteString ?? "Invalid URL")
}
// 出力: https://example.com/directory/subdirectory/file
```

#### falseの場合
falseにするとURLはそのまま使用され、ベースURLに対して相対URLを解決しません。
```swift
if let baseURL = URL(string: "https://example.com/directory/"),
   let relativeURL = URL(string: "subdirectory/file", relativeTo: baseURL),
   let urlComponents = URLComponents(url: relativeURL, resolvingAgainstBaseURL: false) {
    print(urlComponents.url?.absoluteString ?? "Invalid URL")
}
// 出力: subdirectory/file
```

# 実際のアプリでの使い方
実用的な使い方としてurlからパラメーターを取得するコードを載せます。
```swift
let urlString = "https://example.com/path?param1=value1&param2=value2"

// パラメーター名だけ取得したい場合
if let url = URL(string: urlString), let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) {
    let queryItemNames = urlComponents.queryItems?.map { $0.name } ?? []
    print(queryItemNames)
} else {
    print("Invalid URL")
}

// パラメーター名と値両方をreduceして取得したい場合
if let url = URL(string: urlString), let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false) {
    let queryItems = urlComponents.queryItems ?? []
    let parameters = queryItems.reduce(into: [String: String]()) { (result, item) in
        result[item.name] = item.value
    }
    print(parameters)
} else {
    print("Invalid URL")
}
```

# 参照
https://developer.apple.com/documentation/foundation/nsurlcomponents/1416476-init

https://developer.apple.com/documentation/foundation/nsurlcomponents/1410784-init
せんせー、人口RNAってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、人口RNAってなに？

# 人口RNAとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

人工RNAは、生物の体内にあるRNAを人工的に作る技術のことだよ。

RNAは、DNAの情報を使って、タンパク質を作るための設計図みたいな役割をしている物質なんだ。

人工RNAを作ることができれば、病気の治療に役立てることができるんだよ。例えば、ガンの原因になる悪い遺伝子の働きを抑えるRNAを人工的に作って、体内に入れてあげれば、ガンを治療できる可能性があるんだ。

また、ウイルスに感染した細胞を攻撃するRNAを人工的に作ることで、ウイルスを退治することもできるかもしれないんだよ。

さらに、人工RNAを使って、体内で不足しているタンパク質を作らせることもできるんだ。これは、遺伝子の異常が原因の病気の治療に役立つと期待されているんだよ。

でも、人工RNAがうまく働くかどうかは、まだわからないことも多いから、安全性には十分気をつける必要があるんだ。

人工RNAは、病気の治療に革命を起こすかもしれない、とってもワクワクする技術なんだよ。
せんせー、知的財産自動生成ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、知的財産自動生成ってなに？

# 知的財産自動生成とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)
AndroidStudio プラグインを入れる方法

プラグイン入れることは頻度が高くはないですが、たまに使用することがあると思います。

右上の方にある
``Settings > plagins``
![スクリーンショット 2024-03-10 19.24.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/c46fdda7-141b-cf5d-caac-3b26a8ecdf51.png)

![スクリーンショット 2024-03-10 19.24.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/350a4948-bd34-691b-3a3d-39e4f5071381.png)

``Type / to see options`` に入れたいプラグインの名前を入力

 ``Install``をクリック、そしてApplyをクリックします。

 以上です。

 再起動を求められた場合は再起動します。
apache-beamで使ったpython標準メソッドまとめ

# はじめに
- apache-beamを触ることになったがそもそもpythonを触ったことがあまりなかった。また似ている名前のメソッドもあり混同しそうだったため、備忘録としてまとめる。

# pythonにおける変数のデータ型の確認`type`
```python
str_data = 'hoge'
# <class 'str'>
print(type(str_data))

bytes_data = b'hoge'
# <class 'bytes'>
print(type(bytes_data))

int_data = 123
# <class 'int'>
print(type(int_data))

float_data = 123.456
# <class 'float'>
print(type(float_data))

dict_data = { "human": "hoge", "age": 23, "address": "shinjuku" }
# <class 'dict'>
print(type(dict_data))
```

# 文字列とバイト
## str型からbytes型へ`encode` 
```python
data = 'hoge'
encoded_data = data.encode()
# b'hoge'
print(encoded_data)
```

## bytes型からstr型へ`decode` 
```python
data = b'hoge'
decoded_data = data.decode()
# hoge
print(decoded_data)
```


# JSONとdict
## そもそものjsonとdictの違い
- JSONは「データフォーマット」であり、dictは「python」におけるデータ型
- JSONを扱えるようにする(`json[key_name]`のようにアクセスするためなど)にはそれぞれのプログラミング言語ごと変換が必要
  - pythonにおいては`dict`型に変換しなければならない
  - jsだったらparseしてオブジェクト型へ

## str型からdict型へ変換`loads` 
```python
import json

data = '{ "name": "hoge", "age": 23, "address": "shinjuku" }'

dicted_data = json.loads(data)
# dict型に変換されているためkeyで抽出できる
# 23
print(dicted_data['age'])

# 以下の場合はエラーになる
# Traceback (most recent call last):
#   File "/app/src/loads.py", line 7, in <module>
#     print(data['age'])
# TypeError: string indices must be integers
print(data['age'])
```

## dictをJSON(str)へ変換`dumps` 
```python
import json

data = { "human": "hoge", "age": 23, "address": "shinjuku" }

formatted_data = json.dumps(data)

# {"human": "hoge", "age": 23, "address": "shinjuku"}
print(formatted_data)
# <class 'str'>
print(type(formatted_data))
```


## dictをJSONとしてファイルへ保存`dump`
```python
import json

data = { "name": "hoge", "age": 23, "address": "shinjuku" }

with open('../result/index.json', 'w') as f:
    json.dump(data, f, indent=2)
```
出力結果
```json
{
  "name": "hoge",
  "age": 23,
  "address": "shinjuku"
}
```

# 文字列の連結
## イテレータの文字列を連結`join`
- イテレータ...for文で回せるもの
 - list
 - tuple
 - str
 - dict
 - etc...

```python
# list
list_data = ["f", "u", "g", "a"]
joined_list_data = "".join(list_data)
# fuga
print(joined_list_data)

# tuple
tuple_data = ("a","b","c","d")
joined_tuple_data = "".join(tuple_data)
# abcd
print(joined_tuple_data)

# str
str_data = ("hoge")
joined_str_data = "/".join(str_data)
# h/o/g/e
print(joined_str_data)

# dict
dict_data =  { "name": "hige", "age": 23, "address": "shinjuku" }
joined_dict_data = "/".join(dict_data)
# keyのみ結合される
# name/age/address
print(joined_dict_data)

# valueを結合したい場合
dict_data2 =  { "name": "higa", "age": 24, "address": "shibuya" }
joined_dict2_data = "/".join(str(value) for value in dict_data2.values())
# higa/24/shibuya
print(joined_dict2_data)
```

# 参考
https://qiita.com/masakielastic/items/2a04aee632c62536f82c

https://zenn.dev/collabostyle/articles/657cc495e69a9d

https://note.nkmk.me/python-json-load-dump/

https://qiita.com/conf8o/items/d57f74b4bcb67882be37
せんせー、フォトニック結合ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、フォトニック結合ってなに？

# フォトニック結合とは

「フォトニック結合」というのは、「光の粒子（フォトン）」を使って、物質と物質をつなぐ技術のことだよ。

例えば、2つのレゴブロックを組み立てるとき、ブロックの突起とくぼみを使ってパチッとはめ合わせるでしょ？それと同じように、光の粒子を使って、物質と物質をくっつけることができるんだ。

光の粒子は、とても小さくて速いから、物質をつなぐときに、とても正確で効率的なの。それに、光の粒子は電気を使わないから、電気を使う方法よりも、エネルギーを節約できるんだ。

この技術は、将来、とてもすごいコンピューターを作ったり、体の中の病気を見つける機械を作ったりするのに役立つと期待されているんだよ。

光の粒子を使って物質をつなぐ「フォトニック結合」は、まるで未来の技術みたいでワクワクするね！
【Docker】docker composeの立ち上げでmakefileを作成して長いコマンドを省略してみた。

## はじめに
何回もdocker compose up -d --buildを打つのが面倒になってきたので省力して打つことができないかと調べたらmakefileに出会ったので自分用の備忘録として残しておく。

## makefileとは
プログラムのビルドや実行などのタスクを自動化するためによく使用されているらしい。
コマンドも省略できたりする。

## 書き方
```:makefile
build:
	docker compose up -d --build

up:
	docker compose up -d

down:
	docker compose down
```

## 終わりに
色々環境とかを作成していると同じ長めのコマンドをいちいち打ったりすることもあるから使いこなせたら便利そうだなと感じた。
【Java、kotlin】UTC（文字列）からJST（文字列）に変換

世界中どこでも一定なunix時間（UTCの1970/1/1からの経過時間）を噛ませて変換する。
``` Test.kt
/**
 * UTC（オフセット付）の文字列から、日本時間に変換する
 */
val utcStr = "2022-06-01T06:00:30Z"

val utcWithOffset = OffsetDateTime.parse(utcStr)
val unixtime = utcWithOffset.toEpochSecond()

// オフセット（+09:00 とか）も出したい場合
val jstWithOffset = OffsetDateTime.ofInstant(
    Instant.ofEpochSecond(unixtime),
    ZoneId.of("Asia/Tokyo")
).toString()
println(jstWithOffset) // 2022-06-01T15:00+09:00

// オフセットはいらない場合
val jst = LocalDateTime.ofInstant(
    Instant.ofEpochSecond(unixtime),
    ZoneId.of("Asia/Tokyo")
).toString()
println(jst) // 2022-06-01T15:00:30

// タイムゾーン表記も出したい場合
val jstWithTimeZone = ZonedDateTime.ofInstant(
    Instant.ofEpochSecond(unixtime),
    ZoneId.of("Asia/Tokyo")
).toString()
println(jstWithTimeZone) // 2022-06-01T15:00:30+09:00[Asia/Tokyo]
```
ジムに着いたらNotionのDBに自動で記録する

# 1. なぜ作ったのか
水泳に行った記録を自動でNotionに付けたかったため。
これを作るまでは、紙のカレンダーに丸シールを貼る、という古風なやり方をしていた。
月何回行ったのか、どの時間帯に行ったのかを知りたくなったので作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463767/9b7f386d-5356-f9d6-7866-3c9c7ad1a454.png)

# 2. 何を作ったのか
iPhoneのショートカットアプリのオートメーションで、ジムの場所に着いたら、Notionのデータベースに記録するようにした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463767/ab70d506-034b-f411-1215-d37fa4c670ac.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463767/fbee0c8a-6936-2e49-542e-b14a3f316653.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463767/fe7c5205-7fab-09a5-cb1d-0eb0821f6842.png)


# 3. どうやって作ったのか
## 手順1. Notion API を叩くための Secret Key を取得
[Notion Integration](https://www.notion.so/my-integrations) でAPI Keyを作成して、記録を控える。（※手順3で使用する）
なお、私は名前を`for_iPhone_shortcut`としたが、任意の名前でOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463767/6b303134-a588-e16c-32fc-90e3cd5811f6.png)

## 手順2. Notion DBのデータベースidを確認、接続先を設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463767/2a3a8a5d-8699-cfa3-25f5-a50c252d9b7f.png)
リンクをコピーしたら、どこか適当なテキストエディタに貼り付けて、database_id を確認する。
**https://www.notion.so/{workspace_name}/{database_id}?v={view_id}** の形式です。

また、データベースの接続先も併せて設定しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463767/2a719494-2801-2a93-0251-6db4d0cb7184.png)

## 手順3. ショートカットアプリでショートカット作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463767/07f1f039-67ec-f13a-31f7-55170568e1cf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463767/b30c732e-3a04-89f3-d994-f479b1440725.png)
database_idの値は手順1で確認したデータベースidをコピペしてください。

APIを叩くのに使ったコンポーネントは以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463767/a3135b00-7a09-b4b0-4826-666390a246ad.png)


## 手順4. iPhone からショートカットアプリを開き、オートメーションを組む
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463767/f372a3ce-f907-7421-c03c-cd607d2d86b7.png)


# 4. ハマったポイント、大変だったところ
- 日付を時差を考慮してフォーマットしないと、実際にAPIを叩いた時間と異なる時刻が記録されてしまう
- ショートカットアプリではPOSTするJSONは手書きしないといけない。（テキストを読み込ませることができない。）

# ５. おわりに
これ、今回は水泳に行ったら記録するようにしているが、ショートカットアプリを複数作成して、場所ごとに記録をつけても面白そう。
（おわり）
【Next.js】getStaticPropsとは

# getStaticPropsとは
Next.jsの`getStaticProps`は、静的生成（Static Generation）を行うページで使用される関数です。この関数は、ページのビルド時にデータを取得し、ページのHTMLを生成する際にそのデータを使用します。具体的には、サーバーサイドでのデータのフェッチや処理を行い、その結果をページコンポーネントに渡します。

# 特徴
`getStaticProps`関数は次のような特徴を持ちます：

1\. **静的生成とデータのフェッチ** : `getStaticProps`を使用すると、ページのビルド時にデータをフェッチすることができます。このデータは、ページのHTML生成時に使用され、静的なコンテンツとして提供されます。

2\. **非同期処理のサポート** : `getStaticProps`は非同期関数として実装されます。つまり、データの取得に時間がかかる場合や外部APIからデータを取得する場合など、非同期処理を行うことができます。

3\. **ページの再ビルド** : データが更新されるたびに、ページを再ビルドする必要があります。これにより、常に最新のデータが提供される静的なページを維持することができます。

# 使用方法
`getStaticProps`関数は、次のように実装されます：
```js
export async function getStaticProps(context) {
  // データの取得や処理を行う
  const data = await fetchData();

  // 取得したデータをpropsとして返す
  return {
    props: {
      data
    }
  };
}
```

`getStaticProps`関数は、ページコンポーネントの外で実装されます。これにより、ページのビルド時にデータを取得し、そのデータをページコンポーネントにpropsとして渡すことができます。
【Next.js】クライアントサイドレンダリングとは

# クライアントサイドレンダリングとは
Next.jsのクライアントサイドレンダリング（CSR）は、ページのHTMLをクライアント側で動的に生成する方法です。サーバーは初回のリクエスト時に基本的なHTMLとJavaScriptを提供し、クライアントはその後にページの内容を取得し、レンダリングします。この方法では、ページの表示がクライアントのブラウザで行われ、サーバーへの負荷が低減します。

# 特徴
CSRの特徴は以下の通りです：

1\. **クライアント側で動的なレンダリング** : ページの内容がクライアントのブラウザ上で動的に生成されるため、ユーザーがページを閲覧する際に、最新のデータが表示されます。

2\. **初期読み込みが高速** : 初回のページ読み込みでは、基本的なHTMLとJavaScriptが提供され、ページのコンテンツはクライアントが動的に取得します。これにより、初期読み込みが高速化されます。

3\. **柔軟性** : クライアント側でのレンダリングにより、動的なコンテンツの更新や操作が容易になります。ユーザーの操作に応じて、ページの一部だけを更新することができます。

# まとめ
CSRは、ユーザーがページを閲覧する際に、最新のデータを取得したい場合や、動的な操作や更新が必要な場合に適しています。一方で、初回の読み込み時に基本的なHTMLとJavaScriptが提供されるため、初期読み込み速度は高速化されますが、動的なコンテンツの取得には追加のネットワークリクエストが必要となる点に留意する必要があります。
Docker+Laravelの環境構築でcould not find driverとなってしまった際の拡張機能の入れ方

Laravelで開発をしていて、MySQLに接続させる際には拡張機能を入れないといけません。

```
docker-php-ext-install pdo_mysql
```
のコマンドを実行して拡張機能を入れないといけません。
※上記はMySQLの場合です。PostgresQL等の場合は適宜入れ替えてください。

その拡張機能をいれる際に、自分が間違ってしまっていたことをシェアしていきたいと思います。


# 結論
- apt-get installで入れないこと
- 初期のapt-get installで入れている箇所に一緒に入れずに独立した処理としてDockerfileに記述すること
です。
自分がやってしまった過ちを詳しく解説していきます。

# apt-get installで入れないことについて

```
FROM php:8.2.6

# 必要なパッケージのインストール
RUN apt-get update && apt-get install -y \
    libzip-dev \
    unzip \
    libicu-dev \
    && docker-php-ext-install zip bcmath intl \
    && apt-get install redis -y \
    && apt-get install nodejs npm -y
    && apt-get install nodejs npm -y
    && apt-get install docker-php-ext-install pdo_mysql
//下記省略
```

と記述してしまい、そもそもコンテナをビルドすることができませんでした。

# 初期のapt-get installで入れている箇所に一緒に入れずに独立した処理としてDockerfileに記述すること

どういうことかというと、``apt-get install``でインストールしているのが悪く、`そもそもdocker-php-ext-install`
がパッケージインストールツールとして機能するものだから、apt-get installは不要7日もしれない。
であれば`docker-php-ext-install pdo_mysql`をそのまま実行させればよいのではないかと思いました。

ただその際に

```
FROM php:8.2.6

# 必要なパッケージのインストール
RUN apt-get update && apt-get install -y \
    libzip-dev \
    unzip \
    libicu-dev \
    && docker-php-ext-install zip bcmath intl \
    && apt-get install redis -y \
    && apt-get install nodejs npm -y
    && apt-get install nodejs npm -y
    && docker-php-ext-install pdo_mysql
//下記省略
```

のように、`apt-get update`の処理と同じところで実行させればよいと思っていました。
実際は
`RUN docker-php-ext-install pdo_mysql`
として実行させなければならないと今回の件で学びました。
ありがとうございました。
Renesas TSIP②：Security Key Management ToolによるUFPK/KUK作成

## はじめに
Renesas TSIPで利用するUFPKとKUKの平文鍵は、Renesasが提供しているSecurity Key Management Toolにより作成することができます。

## Security Key Management Tool
UFPKやKUKを作成するためには、Security Key Management ToolでMCUファミリを選択したのち、それぞれの鍵を生成します。
### MCUファミリの選択
Security Key Management Toolの「概要」タブで「MCU/MPUと暗号エンジン」を選択します。
筆者の手元にはRX65Nがあるので、「RX Family, TSIP」を選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3738861/765b9200-c29a-252f-0878-7a535b487b13.png)

### UFPKの作成
Security Key Management Toolの「UFPK生成」タブを選択します。
生成するファイル名（例：ufpk.key）を決めたのち「UFPKファイルを生成する」ボタンにより生成できます。

### KUKの作成
Security Key Management Toolの「KUK生成」タブを選択します。
生成するファイル名（例：kuk.key）を決めたのち「KUKファイルを生成する」ボタンにより生成できます。

## UFPK/KUKの使い方
MCUは鍵を平文で入力することを許容していません。MCUへの注入のためには、UFPK/KUKの平文鍵を暗号化してEncrypted Keyを生成する必要があります。
* UFPKは、HRKにより暗号化してUFPKのEncrypted Keyを生成し、MCUに注入する必要があります。HRKによる暗号化は、Renesas DLM Serverで行う必要があります。
* KUKは、UFPKにより暗号化してKUKのEncrypted Keyを生成し、MCUに注入する必要があります。これは、Security Key Management Toolで行うことができ「鍵のラッピング」タブを利用します。
【Next.js】増文静的生成とは

# 増文静的生成とは
Next.jsのインクリメンタル静的生成（Incremental Static Regeneration、ISR）は、静的生成（Static Generation、SG）の一種であり、ビルド時に事前にHTMLを生成するのではなく、初回のリクエスト時にHTMLを生成し、その後にバックグラウンドで再生成することができる機能です。

ISRでは、最初のリクエスト時に静的に生成されたHTMLがクライアントに提供されます。同時に、最新のデータを取得してページの内容を更新し、次のリクエスト時に新しいデータを含んだHTMLが生成されます。その後、新しいHTMLが生成されるまでの間、以前のHTMLがキャッシュされ、次のリクエストに返されます。

# 利点
ISRの利点は次のとおりです：

1\. **リアルタイムのデータ更新** : ISRを使用すると、ページの内容がリアルタイムで更新され、ユーザーに最新の情報が提供されます。データが更新されるたびにページ全体を再生成する必要はなく、部分的な更新が可能です。

2\. **高速なパフォーマンス** : ISRは静的生成と同様に静的なHTMLを提供するため、高速なページ読み込みを実現します。また、再生成がバックグラウンドで行われるため、ユーザーには即座に最新のコンテンツが表示されます。

3\. **柔軟性とスケーラビリティ** : ISRは静的生成と動的なレンダリングのハイブリッドであり、静的なコンテンツと動的なデータの組み合わせを実現します。これにより、柔軟性が向上し、異なるページに異なる更新頻度を適用できます。

# まとめ
ISRは、リアルタイムのデータが必要なページや、頻繁に更新されるコンテンツが含まれるページに最適です。例えば、ブログのコメントセクションや商品の在庫情報などが該当します。ISRを使用することで、静的生成と動的なデータのベストな組み合わせを実現し、ユーザーエクスペリエンスを向上させることができます。
【Next.js】サーバーサイドレンダリングとは

# サーバーサイドレンダリングとは
Next.jsのサーバーサイドレンダリング（SSR）は、クライアントのリクエストごとにサーバーでページのHTMLを動的に生成する方法です。サーバーがリクエストを受け取ると、ページのデータを取得し、データとコンポーネントを組み合わせてHTMLを生成し、クライアントに返します。これにより、クライアントがページをリクエストするたびに、常に最新のコンテンツが表示されます。

# 特徴
Next.jsのサーバーサイドレンダリングには、次のような特徴があります：

1\. **動的なコンテンツ** : クライアントのリクエストごとにページのHTMLを生成するため、常に最新のデータが表示されます。データが頻繁に変更されるページや、クライアントごとに異なるコンテンツが必要な場合に適しています。

2\. **データの取得** : `getServerSideProps` というメソッドを使用して、サーバーでページに必要なデータを取得します。このメソッドは、クライアントのリクエストごとに実行され、データがHTMLに組み込まれます。

3\. **SEO対応** : サーバーサイドでページのHTMLを生成するため、検索エンジンがページのコンテンツをクロールしやすく、SEO（検索エンジン最適化）に適しています。

4\. **パフォーマンス** : サーバーサイドレンダリングは、クライアントサイドでページをレンダリングする場合よりも負荷が高くなる場合がありますが、ページがリクエストごとに動的に生成されるため、常に最新のコンテンツが提供されるという利点があります。

# まとめ
サーバーサイドレンダリングは、データが動的に変化するページや、クライアントごとに異なるコンテンツが必要な場合に適しています。また、SEOを重視する場合や、クライアントサイドでのパフォーマンスよりも最新のデータの表示を優先する場合にも有用です。
【Next.js】静的生成とは

# 静的生成とは
Next.jsの静的生成（Static Generation、SG）は、サーバーサイドでページのHTMLを事前に生成し、ビルド時に生成されたHTMLファイルをクライアントに提供する方法です。これにより、サーバーがリクエストごとにページを動的に生成する必要がなくなり、高速でパフォーマンスの高いアプリケーションを構築できます。

# 特徴
Next.jsの静的生成には、次のような特徴があります：

1\. **事前ビルドされたHTMLファイル** : ビルド時に各ページのHTMLが生成され、サーバーにデプロイされます。クライアントからのリクエストがあるたびに、生成されたHTMLファイルが返されます。

2\. **データの事前取得** : `getStaticProps` というメソッドを使用して、ビルド時にページに必要なデータを取得します。このデータはHTML生成時にページに組み込まれます。これにより、ページがリクエストされたときに最新のデータを提供できます。

3\. **高速なパフォーマンス** : 事前に生成されたHTMLファイルを提供するため、サーバーの負荷が低くなり、ページの読み込み速度が向上します。また、CDN (Content Delivery Network) を使用することで、世界中のユーザーに高速にコンテンツを配信できます。

# まとめ
静的生成は、データが頻繁に変更されない静的なコンテンツに最適です。たとえば、ブログの記事、商品ページ、ランディングページなどが該当します。Next.jsの静的生成を使用することで、高速でパフォーマンスの高いウェブアプリケーションを構築することができます。
【Next.js】プリレンダリングとは

# プリレンダリングとは
Next.jsのプリレンダリングは、サーバーサイドでページのHTMLを生成し、クライアントに送信することを指します。これにより、クライアントがページをリクエストするたびに、サーバーが動的にHTMLを生成する必要がなくなり、ページの読み込み速度やパフォーマンスが向上します。

Next.jsには2つのプリレンダリングモードがあります：

1\. **Static Generation (静的生成)** : ページがビルド時にHTMLを生成し、それがキャッシュされ、クライアントに配信されます。これにより、リクエストごとにサーバーがページを再生成する必要がなくなり、高速なパフォーマンスが実現されます。ただし、データが更新される頻度が低い静的コンテンツに最適です。

2\. **Server-side Rendering (SSR、サーバーサイドレンダリング)** : ページがリクエストされるたびにサーバーでHTMLを動的に生成します。これにより、ページが常に最新のデータでプリレンダリングされ、動的なコンテンツやパーソナライズされたコンテンツに対応できます。データが頻繁に更新される場合や、クライアントごとに異なるコンテンツが必要な場合に適しています。

Next.jsでは、各ページコンポーネントに対してどのプリレンダリングモードを使用するかを選択できます。例えば、静的生成を使用する場合は `getStaticProps` を、サーバーサイドレンダリングを使用する場合は `getServerSideProps` をページコンポーネントで使用します。これらのメソッドは、ページのデータを取得し、それを使用してページのHTMLを生成するために使用されます。

プリレンダリングを使用することで、Next.jsアプリケーションのパフォーマンスとSEOの向上が期待できます。
【Next.js】CSSモジュールとは

# CSSモジュールとは
Next.jsのCSSモジュールは、コンポーネントごとにスコープが分離されたスタイルを適用するための方法です。CSSモジュールでは、各コンポーネントのスタイルが他のコンポーネントに影響を与えることなく、安全かつ予測可能な方法で定義されます。

CSSモジュールを使用すると、各コンポーネントのスタイルがローカルなスコープ内に閉じられます。各クラス名は自動的に一意の名前に変換され、グローバルな名前空間を汚染することなく、スタイルを適用できます。

#使用方法
Next.jsでCSSモジュールを使用するためには、次の手順に従います：

1\. コンポーネントごとにCSSファイルを作成します。ファイル名は `[name].module.css` の形式にする必要があります。たとえば、`Button.module.css` のような名前のファイルを作成します。

2\. CSSファイル内でスタイルを定義します。通常のCSSと同様に、スタイルを定義しますが、クラス名はローカルなスコープ内でのみ有効です。例えば、`Button.module.css` ファイル内で次のようにスタイルを定義します：
```css
/* Button.module.css */
.button {
  background-color: #007bff;
  color: #fff;
  border: none;
  padding: 10px 20px;
  border-radius: 5px;
}

.button:hover {
  background-color: #0056b3;
}
```

コンポーネントでCSSモジュールをインポートして、スタイルを適用します。例えば、`Button` コンポーネントで `Button.module.css` をインポートしてスタイルを適用します。
```jsx
// Button.js
import styles from './Button.module.css';

function Button() {
  return <button className={styles.button}>Click me</button>;
}

export default Button;
```

#まとめ
CSSモジュールを使用することで、コンポーネントごとにスタイルを管理し、予期せぬスタイルの競合を回避することができます。これは、Next.jsなどのコンポーネントベースのフレームワークで特に便利です。
Go言語におけるAtoiとItoa

# AtoiやItoaに使われるAはASCIIのこと
AtoiとItoaは文字列と整数間の変換を行う際の関数です。
Atoiは「ASCII to Integer」の略になります。ASCII（アスキー）以外の文字列にも対応しています。
strconvのパッケージに属しています。

# Atoi (ASCII to Integer)：文字列→整数

このコードでは、文字列 "123" を整数 123 に変換しています。変換に失敗した場合、エラーが返されます。

```golang
package main

import (
    "fmt"
    "strconv"
)

func main() {
    str := "123"
    num, err := strconv.Atoi(str)
    fmt.Println("変換結果:", num)
}
```

# Itoa (Integer to ASCII)：整数→文字列

```golang
package main

import (
    "fmt"
    "strconv"
)

func main() {
    num := 123
    str := strconv.Itoa(num)
    fmt.Println("変換結果:", str)
}
```
【Next.js】グローバルCSSとは

# グローバルCSSとは
Next.jsのグローバルCSSは、アプリケーション全体に適用されるスタイルシートのことを指します。通常、これらのスタイルは全てのページで共通のスタイリングを行うために使用されます。

# 使用方法
Next.jsでは、グローバルCSSを適用する方法がいくつかあります：

1\. **グローバルCSSファイルの作成** : `styles` ディレクトリや任意のディレクトリに、`.css` もしくは `.scss` ファイルを作成し、そこにグローバルなスタイルを定義します。例えば、`styles/global.css` というファイルを作成し、次のようにグローバルなスタイルを定義します：
```css
/* styles/global.css */
body {
  font-family: Arial, sans-serif;
  background-color: #f0f0f0;
}

/* その他のグローバルなスタイルを定義 */
```

2\. **_app.js ファイルでグローバルCSSをインポート** : Next.jsの _app.js ファイルを使用して、グローバルCSSファイルをインポートし、アプリケーション全体に適用します。次のように _app.js ファイルでグローバルCSSをインポートします：
```jsx
// pages/_app.js
import '../styles/global.css';

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

export default MyApp;
```

#まとめ
どちらの方法を選択するかは、アプリケーションの設定や好みによります。通常、大規模なアプリケーションでは、グローバルCSSファイルを作成して、それを _app.js でインポートする方法が一般的です。
【Next.js】メタデータとは

# メタデータとは
JavaScriptのメタデータは、データそのものではなく、データに関する情報を指します。JavaScriptのメタデータは、通常、オブジェクトや関数などのデータに関する追加情報を含むことがあります。

# 使用方法
JavaScriptのメタデータは、さまざまな目的で使用されます。例えば、以下のような場面でメタデータが利用されます：

1\. **コメントやドキュメント** : コード内のコメントや関数のドキュメントで、関数や変数の説明、使用方法、戻り値の型などの情報が含まれます。

2\. **クラスや関数のアノテーション** : TypeScriptやFlowなどの型システムを使用して、クラスや関数に型情報を付加することができます。

3\. **データの追加情報** : オブジェクトに関連する情報を追加するために、オブジェクトのプロパティにメタデータを含めることがあります。例えば、APIから取得したデータに対して、更新日時や作成者などの情報をプロパティに含めることができます。

#まとめ
JavaScriptのメタデータは、プログラム内のデータや機能に関する補足情報を提供し、データや機能の理解や使用を容易にします。また、静的解析やランタイム中の動的な処理で利用されることもあります。
【Next.js】プリフェッチとは

# プリフェッチとは
Next.jsのプリフェッチ（prefetch）は、ブラウザがリンク先のページを事前に取得してキャッシュに保存する機能です。これにより、ユーザーがリンクにマウスを重ねたり、リンクをクリックする前に、次のページのデータを先読みし、ページ遷移の速度やパフォーマンスを向上させることができます。

# 使用方法
Next.jsでは、Linkコンポーネントを使用して内部リンクを作成する際に、デフォルトでプリフェッチが有効になっています。例えば、次のようにLinkコンポーネントを使用してページ間のナビゲーションを実装した場合、プリフェッチが自動的に有効になります。
```jsx
import Link from 'next/link';

function Navigation() {
  return (
    <nav>
      <Link href="/about">
        <a>About</a>
      </Link>
      <Link href="/contact">
        <a>Contact</a>
      </Link>
    </nav>
  );
}

export default Navigation;
```

上記のコードでは、`<Link>` コンポーネントが使用されており、ユーザーがナビゲーションリンクに触れたりクリックすると、関連するページがプリフェッチされます。

プリフェッチを無効にする場合は、`<Link>` コンポーネントの `prefetch` 属性を `false` に設定します。

```jsx
<Link href="/about" prefetch={false}>
  <a>About</a>
</Link>
```

プリフェッチの有効化や無効化は、アプリケーションのパフォーマンスやユーザー体験に合わせて調整することができます。
Java8以降でBasic認証を復活させるオプション

# Eclipseオプション
Eclipseでプロキシの認証が通過しないと思っていたら、Java8以降ではデフォルトでBasic認証が無効になっているとのこと。
復活させるにはJavaのVM引数にオプションを追加する。
Eclipseでプロキシを有効にするには、eclipse.iniに追加する。
```properties:eclipse.ini
-Djdk.http.auth.tunneling.disabledSchemes=""

```

# JVMから削除
こういうのでもいいらしい。
$JAVA_HOME/jer1.8.0_XXX/lib/net.propertiesの以下をコメントアウトする。
```properties:net.properties
jdk.http.auth.tunneling.disabledSchemes=Basic
```

情報源はこちら。
https://yoneyore.hatenablog.com/entry/2018/04/22/220512

# マーケットプレースにつながらない
Basic認証が復活すれば、MavenとかSTSとかは使えるようになる。
しかし、Eclipseマーケットプレースには一向につながらない。
それは結局プロキシの設定が効いていない部分があるから。
[こちら](https://qiita.com/gogonosmarty/items/d406892f7bc2bf3f2d28)の情報によると、「SOCKS」にプロキシの設定を入れてしまうと、httpとhttpsの設定が効かなくなってしまうとのこと。
なので、「SOCKS」のプロキシ設定をクリアすればつながるようになる。
※筆者はこれでつながるようになりました。

それでもつながらない場合は、設定を直接書き換えるという荒技があるらしい。
```properties:\eclipse\configuration.settings\org.eclipse.core.net.prefs
# こんな感じらしい
eclipse.preferences.version=1
nonProxiedHosts=
org.eclipse.core.net.hasMigrated=true
proxiesEnabled=true
proxyData/HTTP/hasAuth=true
proxyData/HTTP/host=<PROXYSERVER>
proxyData/HTTP/port=<PORT>
proxyData/HTTPS/hasAuth=true
proxyData/HTTPS/host=<PROXYSERVER>
proxyData/HTTPS/port=<PORT>
systemProxiesEnabled=false
```
Elixir: Redis のデータを削除 (Delete)

## プロジェクトの作成

```bash
mix new redis_delete
cd redis_delete
```

```lib/redis_delete.ex
defmodule RedisDelete do
  @moduledoc """
  Documentation for `RedisDelete`.
  """

  @doc """
  Hello world.

  ## Examples

      iex> RedisDelete.hello()
      :world

  """
  def hello do
    :world
  end

  def main do
    IO.puts "*** 開始 ***"
    [id] = System.argv()
    IO.puts id
    {:ok, conn} = Redix.start_link(host: "localhost", port: 6379)
    Redix.command(conn, ["DEL", id])
    Redix.stop(conn)
    IO.puts "*** 終了 ***"
  end

end
```

```exs:mix.exs
（省略）
	{:redix, "~> 1.4"},
（省略）
```

```bash
mix deps.get
```

## 実行結果

```text
$ mix run -e RedisDelete.main t1856
*** 開始 ***
t1856
*** 終了 ***
```
Ubuntu aptでinstallできない問題

Ubuntu 17.04 (32bit版)の環境で、apt installでパッケージがインストールできない問題が発生しました。いつもであれば、WSL2 Ubuntu 20.04環境で作業してこのようなことが起こらず四苦八苦しましたので、備忘録的に記録を残します。


https://oyako-programming.com/ubuntu-apt-error
Spring BootとRabbitMQを使用してメッセージングシステムを構築してみた

## RabbitMQとは？

オープンソースのメッセージ指向ミドルウェア（MOM）で、メッセージングシステムを構築するために使用できる。

## Dockerを使用してRabbitMQをセットアップする

① DockerDesktopを開き、DockerImageのDockerContainerに移動する

② DockerHubからRabbitmq　DockerImageをプルする

[DockerHub](https://hub.docker.com/)

③teminalでインストールする
```
docker pull rabbitmq:3.10.5-management
```
④DockerのImage rabbitmqの『Run』をクリックし、Imageを起動する

```
docker run --rm -it -p 15672:15672 -p 5672:5672 rabbitmq:3.10.5-management
```
⑤lacalhost:15672を確認する


## 参考サイト
[Spring Boot RabbitMQ Tutorial | Consumer | Producer | Crash Course 2023](https://www.youtube.com/watch?v=0--Ll3WHMTQ&t=1138s)
[RabbitMQ徹底解説](https://qiita.com/haystacker/items/52e2fb7c5903c3f3bbf9)
【Android】Kotlinのテストコードを書いていてエラーになった時の話【Kotlin】



# エラー内容
```
Exception in thread "Test worker @coroutine#1" java.lang.IllegalStateException: Module with the Main dispatcher had failed to initialize. For tests Dispatchers.setMain from kotlinx-coroutines-test module can be used
```

# やったこと
上のエラーを翻訳をかけた感じ、ざっくりいうと
kotlinx-coroutines-test モジュールの Dispatchers.setMain が必要とのこと。


**kotlinx-coroutines-test** で検索をかけてみると

https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-test/

このライブラリが出てきたので追加してみた。

```php:build.gradle(Module :app)
dependencies {
    testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0'


    
    }
```

テストコード内では、以下をテストしたいコードよりも前に追加

```
    @Before
    fun setUp() {
        Dispatchers.setMain(Dispatchers.Unconfined)
    }

    @After
    fun tearDown() {
        Dispatchers.resetMain()
        mainThreadSurrogate.close()
    }
```
これで実行したところIllegalStateExceptionのエラーは出なくなり、テストが実行できた。

そもそもテストコードを実行するのに先ほど追加したライブラリーが必要みたいです。

# 参考

https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-test/


https://zenn.dev/maxfie1d/scraps/7c8d799d0eed67

https://qiita.com/HanaleiMoon/items/375e42a9fc5e635d02c9
【Next.js】リンクコンポーネントとは

# リンクコンポーネントとは
リンクコンポーネントは、Reactアプリケーション内でのページ間のナビゲーションを容易にするための特別なコンポーネントです。通常、Reactアプリケーションでは、`<a>`要素を使用してリンクを作成しますが、これは通常のブラウザのナビゲーションをトリガーし、ページ全体を再読み込みしてしまいます。

Next.jsの`<Link>`コンポーネントは、クライアントサイドのルーティングを実現するためにNext.jsが提供するものであり、通常の`<a>`要素とは異なります。これにより、ページ間のナビゲーションがよりスムーズになり、ページの再読み込みが行われることなく、Reactアプリケーション内での移動が可能になります。

# 記述方法
`<Link>`コンポーネントを使用すると、次のように記述します：
```jsx
import Link from 'next/link';

const MyComponent = () => (
  <Link href="/about">
    <a>About Page</a>
  </Link>
);
```
これにより、/aboutへのリンクが作成され、クリックした際にページが再読み込みされずに、クライアントサイドのナビゲーションがトリガーされます。これにより、ユーザーエクスペリエンスが向上し、アプリケーションのパフォーマンスが向上します。
【JavaScript】readdirSyncメソッドとは

# readdirSyncメソッドとは
`readdirSync` メソッドは、Node.js の `fs` モジュールに含まれる同期的なファイルシステム操作メソッドの一つです。このメソッドは、指定されたディレクトリ内のファイルおよびサブディレクトリのリストを同期的に取得します。

# 使用方法
以下は `readdirSync` メソッドの基本的な使用法です：
```js
const fs = require('fs');

try {
  // 指定されたディレクトリ内のファイルおよびサブディレクトリのリストを取得
  const files = fs.readdirSync('/path/to/directory');
  console.log(files); // ファイルおよびディレクトリのリストを出力
} catch (err) {
  console.error('Error reading directory:', err);
}
```
`readdirSync` メソッドは指定されたディレクトリ内のエントリの名前を配列として返します。ディレクトリ内のエントリがサブディレクトリやファイルである場合、その名前が配列の要素として含まれます。

# まとめ
このメソッドは同期的に実行されるため、ファイルシステムの操作が完了するまで次の処理はブロックされます。大規模なファイルシステムや大量のファイルがある場合、同期的なメソッドの使用には注意が必要です。非同期的なメソッドを選択するか、同期的なメソッドを非同期的な方法で使用することが推奨されます。
KARTEの計測タグをGTMで作成してみた

**前提として、サイト計測にGA4、GTMタグを利用されている方が対象です。**
その他のタグ設置を考えている方は、読み飛ばしてください。

["公式説明はこちら"](https://support.karte.io/post/1gfetGfZWpPqYATqgviBg0)

まあ公式にも書いてあるのですが、HOWに至るまでの説明が長いのでこちらに簡易に記述します。

<br>
<br>
<br>
要は、
<br>①タグ作成
<br>②ページビューのトリガーで作成


上の2点で、KARTEの計測タグはGTMで作成できます。

サイト条件によって（SPAなど）、KARTE側の設定を編集しなければいけないケースもあるのですが、そういったサイトごとの対応は割愛します。






<br>

### ・KARTEの計測タグをGTMで作成しよう

①まずはタグ作成　カスタムHTMLを指定


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745684/226d1b75-7b8b-9f31-46f3-dbcea525fea8.png)

<br>
<br>


②赤枠　KARTE計測タグをコピペ
・タグは、KARTEホーム>すべてのメニュー>Tag Manager > タグ設定 にあります


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745684/982ec025-ade9-4fe4-976d-d7441f036228.png)


<br>
<br>

③「詳細設定」をクリックし、「タグ配信の優先度」に「10」を設定
・値は任意ですが,その他に設定するタグよりも高い優先度を設定


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745684/e5659468-ae9d-9c59-cd46-f8083110ca2b.png)




<br>
<br>
④トリガーの作成<br>
・トリガーでページビューを作成して、設定<br>
・すべてのページのPVを取得するためのトリガーがすでに存在する場合は、流用しても問題ない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745684/36b5a157-4d99-a06d-853b-a2799bc9ff2b.png)

<br>
<br>
以上4点で、計測タグの作成工程です。
公開後、正しく計測ができているかの検証をして、作業完了です。


詳しいことは[公式に記載されています](https://support.karte.io/post/1gfetGfZWpPqYATqgviBg0)ので、設定の流れのご参考になりましたら。
chatgptを使って、GTMの変数を作ってみた

今回はchatgptでGTMのある変数を取得したので、その備忘録になります。





<br>

### ・GTMのJavaScript変数にコードを記載して、特定の値を取得してみた



目的：ページのセッションストレージから、特定の数値を抜き出してGTMの変数に格納する

意図：セッション流入を識別するため

手段：chatgptにkeyとvalueに格納されている情報を指定して、質問

chatgptにした質問：
GTMでsession storageのvalueを取得したい。
どのようなJavaScript変数を設定すればよいでしょうか。

key　xxxxxx
value　yyyyy:数値
が格納されている。
上記の数値だけを抽出したい。
どのようなコードを書けば良いか。




```
function) {
//セッションストレージから指定されたkeyの値を取得
 var sessionValue =
  sessionStorage.getltem('xxxxx');

//値が存在する場合
 if (sessionValue) {
//yyyyy":"数値"の形式から数値だけを取得
   var match = session Value.match(/"yyyyy":"(\d+)"/);
//マッチした場合、数字の部分を返す
   if (match && match[1]) {
    return match[1].trim);
//スペースを取り除く
  }
 }

//何も見つからなかった場合はデフォルト値を返すが、適切な処理を行う
 return 'デフォルト値；
}

```


上記のコードを記述すると、yyyyyの数値をGTMの変数を格納することができました。
修正のやりとりはしたのですが、二往復くらいのやりとりです。
コード生成、壁打ちがこのクオリティでできてしまうとは。。。
私はSQLがメイン、pythonとjavascriptがざっくり読めるレベルだったのですが、
本当に助かりました。

## 所感

・作業が大幅に時短になる
・学習コストを減らしてくれる
・他者から時間を奪って、聞き続けるというストレスから解放される
【自作パッケージ】ノードベースのスクリプトエンジンConversationGraph-v2の紹介【Unity】

# 自己紹介
以前作ったパッケージのコードが汚すぎて作り直した大学生。

# ConversationGraphとは
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3083521/1f953b35-e95b-f554-8d57-25a5c44fea75.png)

ノードベースのスクリプトエンジン（会話を構築できるヤツ）のUnityパッケージです。
OSSとして公開しています。

https://github.com/PrashaltGames/Unity-ConversationGraph

なお、本記事はv2.0.0-pre.1がリリースされた際の記念記事です。
正式リリースまでにサンプルプロジェクトとドキュメントの整備を行う予定です。
がんばる…

## コンセプト
**実用に耐えうる自由度とパフォーマンス**

# 本題
この記事では、READMEには書けないこだわりや苦労した点、v1との比較を記します。

## ConversationGraph-v1（旧バージョン）の問題点
### １．ランタイムでリフレクションを使用していること。
ランタイムで速度的に問題となるリフレクションを使用していることは問題視していました。

### ２．拡張性のなさ
v1も拡張性を意識して開発したつもりでしたが、最終的にはあまり拡張性を持たせることが出来ませんでした。

### ３．UIの限界
v1ではノードツールのUIは全てGraphViewの上に乗っかっていました。
これによってUI構築の自由度が低下し、UXの向上が難しい状態でした。

### ４．ConversationGraphAssetの無駄
v1ではRuntime上でもNodeの座標などをもつConversationGraphAssetを読み込み使用していました。
これでは無駄なメモリが確保されることになります。

### ５．無駄なプロパティシステム
v1では全ての型に対応した属性ベースのプロパティを採用していました。
しかし、これでは大規模なゲームになってくるとプロパティだけでメモリの消費が無視できない量になることが想定されました。

### ６．UniRxの依存
当時、UniRxに入門したばかりだったため、使いたい・練習したいだけでUniRxに依存しているパッケージでした。
これは単になくしています。

## ConversationGraph-v2の改善点
### １．拡張性
これは**スクリプトノード**の導入によって、改善しました。
スクリプトノードは、独自のインタフェースを継承したクラスをパッケージ使用者が制作することで独自の処理を会話中に挟むことができます。
これによって、高い拡張性を担保しています。

### ２．UIの大幅な変更
UIの中心をAppUIベースのConversationGraohInspectorという独自のEditorWindowに移行しました。
これによって、高いUXを実現できるだけでなく、GraphViewからの依存も軽減しています。

また、ノードエディターがよりすっきりした見た目になりました。
### ３．RuntimeとEditorのScriptableObjectの切り分け
Editorで使うノードの情報を取り除いたScriptableObjectを生成することで、無駄なメモリ確保をなくしています。

### ４．Dictionaryを使用した一般的なプロパティシステム
ConversationGraphではstring型のみに対応すればよいという観点から、内部的にはDictionaryを使った一般的なプロパティシステムに移行しました。また、動的にプロパティをいじることが少ないと考え、プロパティ用のScriptableObjectを用意してこれを参考にプロパティが反映されることにしました。
メモリ管理もv1のstaticなフィールドを使用したものより容易だと考えられます。

また、bool型のプロパティは廃止され、スクリプトノードに移行する予定です。（`ScriptableBranch`）

## 今後の課題
Runtime側のコードが満足いってないので、その修正を行いたいと思っています。
特にユーザー側が独自のFacilitatorを作る必要のないぐらい洗練したいですねぇ（もともと独自にFacilitatorを作れるようにしようという設計だったが、それが不要なぐらいScriptableNodeが仕事してくれそうなので、色々変更したい。）

ほかにもやりたいこといっぱいあります！！

# さいごに
少しの間、自主開発のUnityを触れないかもしれないため少しやり残し感はありますが、previewとしてリリースしました。
また更新して、いい感じにREADMEまで書きたいですね。
Pythonで「isinstance関数の使い方(オブジェクトのデータ型を判定する)」の動作を確認してみた

# 概要

Pythonで「isinstance関数の使い方(オブジェクトのデータ型を判定する)」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/python/function/index8.html

# 実装

以下のファイルを作成しました。
```sample.py
mylist = [2, "ab", 3.5, True, 4]
total = 0

for val in mylist:
    if isinstance(val, (int, float)):
        print("val:" + str(val))
        total += val

print("total:" + str(total))
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
val:2
val:3.5
val:True
val:4
total:10.5
```

# まとめ

何かの役に立てばと。