OmniAICreator/Qiita-1.07M huggingface dataset:
python maya opionVar

Set an optionVar
```python
import maya.cmds as cmds

option_var_name = "myOptionVar"
option_var_value = 42

# Set the optionVar
cmds.optionVar(iv=(option_var_name, option_var_value))
```

Get the value of an optionVar:
```python
import maya.cmds as cmds

option_var_name = "myOptionVar"

# Get the optionVar value
option_var_value = cmds.optionVar(q=option_var_name)
print(option_var_value)  # Output: 42
```

Check if an optionVar exists:
```python
import maya.cmds as cmds

option_var_name = "myOptionVar"

# Check if the optionVar exists
if cmds.optionVar(exists=option_var_name):
    option_var_value = cmds.optionVar(q=option_var_name)
    print(option_var_value)
else:
    print("OptionVar does not exist.")
```

Delete an optionVar:
```python
import maya.cmds as cmds

option_var_name = "myOptionVar"

# Delete the optionVar
if cmds.optionVar(exists=option_var_name):
    cmds.optionVar(remove=option_var_name)
    print("OptionVar deleted.")
else:
    print("OptionVar does not exist.")
```

# String Array
```python
import maya.cmds as cmds

def SetOptionVarStringArr(option_var_name, option_var_value):
    option_var_string = ",".join(option_var_value)
    cmds.optionVar(sv=(option_var_name, option_var_string))

def GetOptionVarStringArr(option_var_name):
    option_var_string = cmds.optionVar(q=option_var_name)
    option_var_value = option_var_string.split(",")
    return option_var_value
```
trpcでFormData(画像等)を送信する

trpcは基本json形式のみしか送受信は対応していませんが、
experimentalでFormDataが2023/04頃に対応されているため、やってみた。
※主な用途としては画像のアップロードなどで必要になると思います。

### 公式のサンプル

https://github.com/trpc/trpc/tree/main/examples/.experimental/next-formdata

基本はサンプル通りだが`zod-form-data`が結構やっかい
https://www.npmjs.com/package/zod-form-data

以下の例のようなシンプルなものならいいが、挙げられていない型の例を書いてみる
```ts
 import { zfd } from 'zod-form-data'; 
  
 if (typeof window === 'undefined') { 
   const undici = require('undici'); 
   globalThis.File = undici.File as any; 
 } 
  
 export const uploadFileSchema = zfd.formData({ 
   name: zfd.text(), 
   image: zfd.file(), 
 }); 
```

booleanはundefinedの場合にfalse、trueは任意の文字列に変更できる
https://www.npmjs.com/package/zod-form-data#checkbox
objectの場合はzodを使いつつzfdで中身を定義していく

```ts
const TestSchema = zfd.formData({
  optionalText: zfd.text().optional(),
  booleanData: zfd.checkbox({ trueValue: 'true' }),
  stringArray: zfd.repeatable(z.array(zfd.text())),
  objectArray: zfd.repeatable(z.array(XXXSchema)),
});

const XXXSchema = z.object({
  text: zfd.text(),
  file: zfd.file(z.instanceof(File).optional()),
});
```

React側での送信イメージ
```tsx
 const formMutate = trpc.testForm.useMutation();
  
 const submit = () => {
    const formData = new FormData();
    formData.append('name', name);
    if (optionalText) {
      formData.append('optionalText', optionalText);
    }
    if (image.file) {
      formData.append('file', image.file, image.file.name);
    }
    formMutate.mutate(formData);
 };
```
KMM（Kotlin Multiplatform Mobile）は廃止され KMP（Kotlin Multiplatform）に統一されたよ

長らくKotlin界隈でたびたび混乱していた **KMM（Kotlin Multiplatform Mobile）** と **KMP（Kotlin Multiplatform）** がついに終止符が打たれましたね

<font color="red">KMM（Kotlin Multiplatform Mobile）廃止</font>です👋

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">📣 Update on the name of Kotlin Multiplatform<br><br>From now on, “Kotlin Multiplatform” (KMP) is the preferred term when referring to the Kotlin technology for sharing code, regardless of the combination of platforms being discussed.<br><br>We are deprecating the “Kotlin Multiplatform…</p>&mdash; Kotlin by JetBrains (@kotlin) <a href="https://twitter.com/kotlin/status/1686018987304292352?ref_src=twsrc%5Etfw">July 31, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

しかし「KMM廃止」と言うと誤解を招きすぎるので、正しくいうと「<font color="red">KMMという名称をやめ、ターゲットの組み合わせに関係なく、Kotlin テクノロジーを指すものを KMP に統一しましょうね</font>」ということ。

しかしそもそもKMPとKMM、何が違うのよ？


## KMP（Kotlin Multiplatform） と KMM（Kotlin Multiplatform Mobile） の違い

KMP と KMM の違いを説明する前に、それぞれについてまとめました。

### KMP（Kotlin Multiplatform） とは

そもそも KMP とは、JetBrains社で開発されているプログラミング言語 Kotlin を利用して、クロスプラットフォームの開発を簡素化するように設計された技術やそのエコシステム全体のことを指します。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33505/cbc9268f-1c74-368a-475d-54050f869198.png">

※ 出典 https://kotlinlang.org/docs/multiplatform.html

この KMP を利用して開発されるプロジェクトのことを **Kotlin MPP(Kotlin Multiplatform Project)** と呼びます。

では KMM（Kotlin Multiplatform Mobile） とはなにか？

### KMM（Kotlin Multiplatform Mobile） とは

<font color="red">KMM とはiOSやAndroidなど、モバイルアプリケーション開発に特化した機能や技術を KMP を使って実現させたもの</font>になります。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33505/5a431a63-65a0-73ef-c7a3-4a83fa0179da.png">

※ 出典 [It's Time for Kotlin Multiplatform Mobile by Ekaterina Petrova](https://www.youtube.com/watch?v=PW-jkOLucjM&t=340s)

## じゃあなぜ混乱したの？

答えは Kotlin Blog: [Update on the Name of Kotlin Multiplatform](https://blog.jetbrains.com/kotlin/2023/07/update-on-the-name-of-kotlin-multiplatform/) に書いてあります。

そもそも KMP（Kotlin Multiplatform） は、 [KotlinConf 2017で発表](https://blog.jetbrains.com/kotlin/2017/11/kotlinconf-keynote-recap/)され、当初は JVM、ネイティブ、および JS をターゲットにサポートしていました。しかし2020年 iOS と Android の間のコード共有に焦点を移したことをきっかけに、多くのモバイル開発者を惹きつけました。

その際、多くのモバイル開発者のフィードバックやサポートの向上、さらに将来の改善に備えることを目的に iOS と Android の間のコード共有に関連する Kotlin Multiplatform のすべてを KMM（Kotlin Multiplatform Mobile） と総評したことでその結果 Kotlin Multiplatform と Kotlin Multiplatform Mobile という複数の名前と、略語 KMP、KMM、MPP を持つエコシステムが誕生しました。

名前や略語が複数検出されることで複雑になっただけでなく、 <font color="red">**KMP（Kotlin Multiplatform） そのものが、モバイル開発のためのものであるという誤解**</font>につながりました。

## さいごに

実際名称が複数あることで KMM = KPM と誤解することは少なからずあったと思います。iOS や Android で利用されることが多い KMP ですが、Webも含めて利用を検討していくことで KMP（Kotlin Multiplatform） が求めた理想的な活用に繋がっていくんじゃないかと期待します。
TypeScriptのパワフルなツール: Null合体演算子 (`??`) をマスターしよう！


## 目次
1. [はじめに](#intro)
2. [Null合体演算子とは？](#null-coalescing)
3. [Null合体演算子の使用例](#examples)
4. [Null合体演算子 vs OR 演算子](#comparison)
5. [まとめ](#conclusion)

---

<a name="intro"></a>
## 1. はじめに

JavaScripttは、日々の開発作業を容易にし、コードをより簡潔に書くための多くのツールを提供しています。その一つが**Null合体演算子**（`??`）です。この記事では、Null合体演算子の使い方とその強力さを解説します。

---

<a name="null-coalescing"></a>
## 2. Null合体演算子とは？

Null合体演算子（`??`）は、左辺の値が`null`または`undefined`の場合に、右辺の値を返します。それ以外の場合、つまり左辺の値が`null`または`undefined`でない場合には、左辺の値がそのまま返されます。

---

<a name="examples"></a>
## 3. Null合体演算子の使用例

以下に、JavaScript/TypeScriptにおけるNull合体演算子の使用例を示します：

```javascript
let x = null;
let y = x ?? "default";
console.log(y);  // "default"
```

この例では、`x`は`null`なので、`y`は`"default"`となります。

もう一つの例：

```javascript
let x = "Hello, world!";
let y = x ?? "default";
console.log(y);  // "Hello, world!"
```

この例では、`x`は`null`または`undefined`でないので、`y`は`x`の値である`"Hello, world!"`となります。

---

<a name="comparison"></a>
## 4. Null合体演算子 vs OR 演算子

JavaScriptのOR演算子（`||`）も似たような動作をしますが、`falsy`（`false`, `0`, `""`, `null`, `undefined`, `NaN`）の場合に右辺のオペランドを返します。これはNull合体演算子との重要な違いです。以下の例で見てみましょう：

```javascript
let x = "";
let y = x || "default";
console.log(y);  // "default"
```

この例では、`x`は`""`（falsy）なので、`y`は`"default"`となります。

しかし、Null合体演算子を使うと：

```javascript
let x = "";
let y = x ?? "default";
console.log(y);  // ""
```

この例では、`x`は`null`または`undefined`ではないので、`y`は`x`の値である`""`となります。

つまり、Null合体演算子は`null`または`undefined`のチェックに特化しているため、`0`や`""`（空文字列）などの有効な値をデフォルト値に置き換えてしまうOR演算子の問題を避けることができます。

---

<a name="conclusion"></a>
## 5. まとめ

Null合体演算子（`??`）は、JavaScriptやTypeScriptでの開発において強力なツールです。存在しない可能性のある値に対してデフォルト値を設定する際などに、この演算子を使ってコードを簡潔に保つことができます。また、OR演算子（`||`）との違いを理解することで、より適切な場面でNull合体演算子を使用することができます。

---

以上、JavaScript/TypeScriptのNull合体演算子の使い方についての解説でした。この記事があなたの開発に少しでも役立つことを願っています。いいねやシェアをいただけると幸いです。
UTMで仮想化を行う際、choose type of install で選択できない

今回は、m1 mac でlinux開発をするためにUTMで仮想化を行う際のtipsです。

UTMのインストール
新規バーチャルマシンの作成

までは終えていると仮定します。本記事はUbuntuのインストールに関連します。

Keyboard Configurationまで進めると、次にChoose type of installが出てくると思います。

ここではUbuntu Server か Ubuntu Server(minimized)のいずれかを選ぶのですが、
いかんせんUIがわかりにくいですよね。

選べと言われてもどこを押せばよいのかわからない。
少なくとも私は勘が鈍いので足止めを喰らいました。

結論を言うと、「Xが入っていれば選択できている」ということです。
たとえば下の画像では、Ubuntu Serverが選択されていることになります。

もしUbuntu Server(minimized)に変更したい場合は、カーソルを合わせてEnterキーを押せばUbuntu Server(minimized)にXが入り選択完了です。

あとはキーボードの十字キーでDONEにカーソルを合わせてEnterキーを押せば次のステップに進めます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631758/b3073eb4-e8b7-4300-d8d2-89af17500985.png)
cisco packet tracer ネットワーク勉強

ルーターを使ったデーターのやり取りの方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/3637abf5-9825-23fd-3d48-aaed910d469b.png)

ルーター　pcを接続

cross overケーブルで接続

port statusをonに設定する

pc0 
ip 192.168.1.1 
subnet musk 255.255.255.0
gateway 192.168.1.10

pc1
ip 192.168.2.1 
subnet musk 255.255.255.0
gateway 192.168.2.10

router0 
ethernet0/0
ip 192.168.1.10
subnet musk 255.255.255.0

ethernet1/0
ip 192.168.2.10
subnet musk 255.255.255.0

ethernet6/0
ip 192.168.10.10
subnet musk 255.255.255.0

ここまででpc0とpc1のやり取りの確認をする（最初の一回はtimeoutになることがある）

router1
ethernet0/0
ip 192.168.10.20
subnet musk 255.255.255.0
ethernet1/0
ip 192.168.20.20
subnet musk 255.255.255.0

pc2
ip 192.168.20.3
subnet musk 255.255.255.0
gateway 192.168.20.20

別のネットワークと接続するためにルーター側で設定をする

router0ではpc0,pc1がpc2と通信できるようにrouter0のstatic routesにpc2のネットワークアドレスを設定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/d3a5d54c-1d3a-827f-54ef-e79fdec919ec.png)


Networkに接続したい通信先のネットワークアドレス
NextHopにrouter1のipアドレスを入力する

router1側でも同様に設定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/541c74c3-4b97-9bca-f621-15ccf5c8a0e1.png)

pc0のcommand promptでping 192.168.20.3
を入力し通信できるか確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519817/222696b4-4160-5f32-2746-9d70bc832215.png)


通信できました
Redshift Serverless トランザクションによりRPUが使用されたままになってしまうことを防ぐ

Redshift Serverlessを使って気づいたことを書きます。
今回はトランザクションを実行した際に、RPUが消費され続けるという挙動を検知し、防ぐために実行した事例です。  


# 対策 その1
Redshift ServerlessでRPUが消費されたままになることを検知したいできるようなモニタがしたい。

使うのはAWS上であれば、まずはCloudWatch Alarmと考えるべきである。
Redshift ServerlessのComputeCapacityに対するアラームを条件「0より大きい」で、「アラームを実行するデータポイント」をつかって設定する。
データポイントが5分単位なので、データポイントが「100/100」なら「500分間0より大きい状態が続く」となる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245869/6866e5c6-8a7c-2ef5-1e3c-0b7d49a5eb07.png)

あとはSNSトピックをつくってアラームと連携すれば通知が可能になる。

# 対策 その2  
長時間トランザクションを強制的に切断することを検討する。
Redshift上で実行されているトランザクションを
・Queryし
・実行時間を確認し
・実行時間が長いものを切る。
というステップの処理を、Stepfunctions、Redshift DataAPIで実装する。

1.Stepfunctionsで以下3つの処理をつくる
-長時間トランザクションのPIDを取得する検索SQLを実行する　
テーブルSVV_TRANSACTIONSからtxn_startの時刻を取得し、現在時刻とdatadiffを取得してトランザクションの実行時間を出し、それが閾値より大きいセッションのPIDをとる
　実行するSQLは「"select pid from SVV_TRANSACTIONS where datediff(minute,txn_start,getdate()) > 閾値となる時間(分)"
-GetStatementResultでSQLの結果を取得(Dataapiは非同期なのでWaitしてから取得する必要がある)
-結果に含まれるPID(複数あるかもしれないので、Mapを使って処理を分岐する)について、それぞれ「 pg_terminate_backend」を実行する

↓イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245869/9a6d8406-91d3-a97c-561d-9b2a9e5b120b.png)


2.Stepfunctionsを実行するIAMがRedshift上で使用するユーザ("IAMR:(IAMロール名称)"というユーザになる)をRedshiftにCreate Userして、"GRANT ROLE sys:superuser to (ユーザ名)"でスーパーユーザー権限を与える。(他のユーザのセッションを切るのでスーパーユーザ権限が必要)

3.1で作ったStepfunctionsをEventbridgeのスケジューラから定期実行する。(実行タイミングはどのくらいの時間の処理を切りたいか次第で調整する必要がある)


# 結果
上記によって、実現したい機能を実装し、実際に期待した通りに動くことを確認することができた。

が、そもそもなぜトランザクションがタイムアウトしなかったのか、という疑問は残ったままである。
ゼロからの挑戦！Professional Cloud Architectに一発合格した方法とは？

## 結論: <font color="#e5732a">過去問がいっっっちばん大事だった</font>
これから経緯や参加したプログラムの話もしますが、この記事で一番伝えたいことはこれです。
解いた過去問: [【最短攻略】Google Cloud 認定 Professional Cloud Architect 模擬問題集](https://www.udemy.com/course/google-cloud-professional-cloud-architect-i/)
![スクリーンショット 2023-08-01 18.42.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/c2562492-20d6-f9f3-e5ae-1c0459b4d15a.png)


## 取得した資格について
取得したのは「Professional Cloud Architect」

![スクリーンショット 2023-08-01 18.13.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/3fbbc130-1172-11e7-b258-7ff731bee05b.png)
どやぁ


> Professional Cloud Architects は、組織が Google Cloud 技術を利用できるように支援します。クラウドアーキテクチャと Google Cloud に関する専門的な知識を活かして、ビジネス目標を実現するために、スケーラブルで高可用性を備え、堅牢かつ安全な動的ソリューションを設計、開発、管理します。
(引用元: https://cloud.google.com/certification/cloud-architect?hl=ja)

めちゃくちゃざっくり要約「**広くGCPのことを理解している証**」

## 自分のスペック
自分のスペックは下記の通り
- webアプリケーションエンジニア
- フロントエンド/バックエンド/アプリまで色々やる
    - いわゆる「ふるすたっくえんじにあ」(あんまり声を大にしていうほど自信は無い)
- インフラまわりの知識はほぼゼロ
  - awsはちょっと触ったことがある(ちょっと)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/8646b7ad-440c-3ab8-cde0-e1ae3594254f.png)
「インフラのことわからん...」
「なんか動いているいつもありがとう...」

## 参加したG.I.G.プログラムについて
今回資格を取得するきっかけにはこのプログラムがきっかけとなっています。

### G.I.G.とは？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/bffa337a-426d-c4d7-2b64-acebb6fb6c2c.png)

GoogleCloudの技術を習得してもらい、活用推進してもらうためにGoogleが企画しているプログラム
参加は無料

Googleさん太っ腹っす...


### スケジュール
- セッションは全3回(4/13、5/18、6/15)
- 修了式は8/3

### 修了条件
- Courseraの受講（関連するコースを最低5つ）
- 7/21までに合格報告


## 資格取得のための勉強
自分は下記のようなものを使ったりして勉強をしました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/b741dbfa-a13e-8e47-3bce-f923ba873c57.png)


- Coursera
    - **今回のG.I.G.プログラムに参加することでGCP関連が期間限定で勉強し放題**(太っ腹っす...)
    - 基礎知識の体得できる
    - 実際にGCPの画面を触りながら学べる
- ChatGPT
    - わからない単語が出てきたときに活用
    - 必殺技は **「OOについて小学生でもわかるように教えて！」** です
- 先駆者の記事閲覧
    - 先駆者も先駆者の記事を読んでいたので自分も読みました。
    - どんな勉強をしたら良いかとか結構書いてあります。
    - **ここで過去問が大事だということを知りました**
- 過去問
    - **ほんとにこれが一番大事だった**
    - **なんというか教科書読んで理解した気になっても実際問題解くときにはコツが居るじゃないですか**
    - **そんな感じです**
    - 自分は[【最短攻略】Google Cloud 認定 Professional Cloud Architect 模擬問題集](https://www.udemy.com/course/google-cloud-professional-cloud-architect-i/)こちらをやりました

過去問をこれを買うか悩んでいる人へ
**他で色々無料で勉強の環境整えてもらってるのでこれくらは払ってもバチは当たらないと思います！**
別にUdemyの回し者とかではありません！が、ほんとにこれのお陰で合格できたので！！！

## 実際の試験について

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/4cf9d662-f46d-e8ac-f5ce-f95284fc3df0.png)

実際の試験は自宅で受けました。
理由として、試験に申し込んだのがギリギリだと言うこともあり試験会場は**土日埋まっていた**ので自宅で受けました。


## 感想

社会人になってエンジニアとして技術のキャッチアップなどはしてきたが、「勉強」というものは久しぶりでとても新鮮だった。
最初分からなかったことがわかるようになるのはシンプルに楽しい！！
合格できてめちゃハッピー🎉🎉🎉🎉🎉

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/b40c43be-92b2-7208-1b30-05875aa11d15.png" width="500px">
Cloud Functionsを実行時、The request was not authenticatedエラーの対策法

Cloud Functionsを検証するときに起きた問題。

専用サービスアカウントを指定し、Pub/Sub トリガーのCloud Functions（第2世代）
トピックにメッセージをパブリッシュすると、Cloud Functionsのログにこういうエラーが出ました。

```
"The request was not authenticated. Either allow unauthenticated invocations or set the proper Authorization header. Read more at https://cloud.google.com/run/docs/securing/authenticating Additional troubleshooting documentation can be found at: https://cloud.google.com/run/docs/troubleshooting#unauthorized-client"
```


解決策として、Cloud Functionsのサービスアカウントに関数の実行権限を付与する
```
gcloud functions add-invoker-policy-binding FUNCTION_NAME \
      --region=REGIN \
      --member=SERVICE_ACCOUNT
```
【入門編】Web技術の用語を解説してみる

## はじめに

本記事は、エンジニア初学者の方やこれからwebのお仕事に携わる方や<br>ITパスポートや基本情報技術者の勉強をされている方向けに作成いたしました。

なんとなく目にしたことはあるけどどういう意味なんだろう？とか<br>これ勉強で出てきたけどなんだっけな？など拝見された方の学習や再復習の手助けになれば幸いです。

初学者向けの学習本はたくさんありますが<br>今回は「[プロになるためのWeb技術入門](https://www.amazon.co.jp/%E3%80%8E%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEWeb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80%E3%80%8F%E2%80%95%E2%80%95%E3%81%AA%E3%81%9C%EF%BC%8C%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AFWeb%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B-%E5%B0%8F%E6%A3%AE-%E8%A3%95%E4%BB%8B-ebook/dp/B09MVGM99L/ref=sr_1_1?crid=2RUFI5FRBVD4D&keywords=web%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80&qid=1645489804&sprefix=web%E6%8A%80%E8%A1%93%2Caps%2C205&sr=8-1)」から重要な用語をピックアップして解説していきます。

たくさんのエンジニアの方が初学者向けにオススメしている本で<br>文章だけではなく図も記載されているので読みやすい良本です。

それでは、用語の解説をしていきます。

## リクエスト・レスポンス・HTTPプロトコル

簡易的に表すとこうなります。

**クライアント(自分のPCやスマホなど)←HTTP通信→Webサーバ**

クライアント側(自分のパソコンやスマホ)からサーバ側へ「〇〇の画面表示したい！」と**リクエスト**を送ります。
サーバ側は、リクエストに応じて「はい！これ依頼されてた〇〇の画面の表示のやつね！」と**レスポンス**を返します。

クライアントとWebサーバの間にある、HTTP通信は**通信プロトコル**のことを指します。<br>正式名称はHyperText Transfer Protocol（ハイパーテキスト・トランスファー・プロトコル）

通信をする時には、足並みを揃えてからお互いにやりとりしましょうねと約束事を決めています。
現実世界で例えるならば、片方は日本語、もう片方は英語を喋ってやりとりしてしまうとコミュニケーションが成立しませんよね？通信の世界でも同じです。

なので「○○通信をするときは××なお約束事に従ってやり取りしようね」と事前に決まっています。



## クッキー(Cookie)
ネットを閲覧したときに一度は見たことがあるであろう、Cookieを有効化しますか？と出てくるあのCookieです。あのCookieとても大事な役割を果たしています。

Cookieとは、WebサーバからWebブラウザへHTTPレスポンスのヘッダを利用して送る**小さなデータ**のことです。

WebサーバからCookieを受け取ったWebブラウザは、次回と同じWebサーバにアクセスするときに、リクエストと共にCookieを一緒に送信します。

Webアプリケーション側は、リクエストと共に送られてきたCookieを調べることでアクセスしてきた相手が誰なのかが分かるようになっています。

また、意図しない情報が他のWebサーバに送られない仕組みとして、Cookieを受け取ったサーバとは異なるWebサーバに対してはCookieは送りません。


## IPアドレスとポート番号

**IPアドレス**とは、コンピュータに割り当てられる住所のことです。
**ポート番号**とは、ネットワークとパソコンの間にあるポート（データの通り道）に割り振られている**識別用の番号**です。

インターネットで情報をやりとりする場合は<br>現実世界の手紙と同様に送信先（宛先）を指定しなければ正しく届きません。

**IPアドレス**を指定して送信先を特定することは出来るのですが<br>どのプロトコルを使うかまでは特定できません。<br>そこで、**ポート番号**で指定することで、どのプロトコルを指定するのかを特定しています。

例を挙げるなら、80番ポートはHTTP(Webブラウジング)ですよといった具合です。



代表的なプロトコルにはあらかじめ**ポート番号**が振られています。
これを**ウェルノウンポート(well-known ports)**といいます。

#### 代表的なウェルノウンポート
|ポート番号|プロトコル|
|:---:|:---:|
|20, 21|FTP(ファイル転送)|
|22|SSH(暗号化されたリモートコンピュータとの汎用通信)|
|23|Telnet(リモートコンピュータとの汎用通信)|
|25|SMTP(メール送信)|
|53|DNS(ホスト名解決)|
|80|HTTP(Webブラウジング)|
|110|POP3(メール受信)|
|443|HTTPS(暗号化されたHTTP)|
 


## ステートフル(Stateful Protocol)とステートレス(Stateless Protocol)

あんまり馴染みのない言葉ではありますが説明を見たら「あ〜そんなことなのね〜」ぐらいの感覚で見てもらえると思います。

**ステートフル**とは、**状態を持つプロトコル**のことです。

例を挙げると、ネットショッピングでお買い物をする時に必ず欲しい商品をカートに入れてから購入すると思います。
このカートに入れて購入リストに保存している状態こそステートフル(状態を持つ)というわけです。

意外と身近なところで、お世話になっているプロトコルです。

反対に、**ステートレス**とは、**状態を持たないプロトコル**のことです。

どちらかというと、インターネットではステートレスの方が一般的です。
序盤で紹介したHTTP通信がまさにステートレス(状態を持たない)なのです。

Googleで「りんご」と検索したときに、「りんご」の検索結果が表示されるわけですが、それ以前や以後に検索していた内容が反映されることはないですよね？<br>つまり、1回のリクエストに対してレスポンスを返しているのが**ステートレス**なのです。


## おわりに
意外と身近な部分で触れているWebの仕組みや用語を出来るだけ簡潔に解説してみました。
学び始めてみると、筆者自身も「そういう仕組みなんだ！」とか「この用語そういう意味だったのか〜」など今後のタメになることばかりでした。
記事を拝見された方の学習や再復習の手助けになれば幸いです。
「Reactの新機能！Concurrent ModeとuseDeferredValueを詳しく解説」



## 目次
1. [はじめに](#intro)
2. [Concurrent Modeとは](#concurrent)
3. [useDeferredValueとは](#use-deferred-value)
4. [Concurrent ModeとuseDeferredValueを使ったコードサンプル](#example)
5. [まとめ](#conclusion)

<a id="intro"></a>
## 1. はじめに
Reactの新機能、Concurrent ModeとuseDeferredValueが話題になっていますね。しかし、これらの新機能はどのように使用するのでしょうか？ 今回は、これらの新機能を詳しく解説し、実際のコードサンプルを通じてその活用方法を探ります。

<a id="concurrent"></a>
## 2. Concurrent Modeとは
Concurrent ModeはReactの新機能で、アプリケーションのレンダリングをより効率的に制御することができます。

従来のReactでは、一度に一つの更新タスクを処理します。このモードでは、一度に処理される更新が1つだけなので、新しい更新が発生すると、それが完了するまで他の更新は待たされます。これは、アプリケーションが応答性を失い、ユーザー体験が悪化する可能性があります。

しかし、Concurrent Modeを有効にすると、Reactは複数の更新タスクを同時に処理することができます。これにより、Reactは更新の優先順位をより柔軟に制御し、ユーザーインタラクション（例えば、入力やクリックなど）に対する応答性を改善することができます。

<a id="use-deferred-value"></a>
## 3. useDeferredValueとは
useDeferredValueはReactの新しいフックで、Concurrent Modeでのレンダリングを制御するためのものです。

このフックは、ある値が遅延して利用可能になる可能性があることをReactに伝えます。Reactは、その値が利用可能になるまで待つ代わりに、代わりの値（通常は以前の値）を表示し続けます。

以下に基本的な使用例を示します：

```jsx
const deferredData = useDeferredValue(someData, { timeoutMs: 2000 });

const isStale = deferredData !== someData;

return (
  <>
    <LoadingSpinner show={isStale} />
    <SomeComponent data={deferredData} />
  </>
);
```

<a id="example"></a>
## 4. Concurrent ModeとuseDeferredValueを使ったコードサンプル
以下に、Concurrent ModeとuseDeferredValueを組み合わせたサンプルコードを示します。

まず、Concurrent Modeを有効にするには、`ReactDOM.createRoot`を使用してルートを作成します。

```jsx
const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(<App />);
```

次に、非同期にデータを取得するコンポーネントを作成します。このコンポーネントは`useDeferredValue`フックを使用して、データが遅延して利用可能になる可能性があることをReactに伝えます。

```jsx
function AsyncComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetchData().then(setData);
  }, []);

  const deferredData = useDeferredValue(data, { timeoutMs: 2000 });

  const isStale = deferredData !== data;

  return (
    <>
      <LoadingSpinner show={isStale} />
      <SomeComponent data={deferredData} />
    </>
  );
}
```

<a id="conclusion"></a>
## 5. まとめ
以上がReactの新機能、Concurrent ModeとuseDeferredValueの詳細な説明とその使用方法でした。これらの新機能を使用することで、Reactアプリケーションのパフォーマンスとユーザー体験を大幅に向上させることができます。さあ、あなたも新機能を試してみましょう！

---

以上がQiitaのテックブログ記事の例です。この記事は、Reactの新機能についての基本的な説明と使用例を提供します。読者はこの記事を通じて、Concurrent ModeとuseDeferredValueの活用方法を理解することができます。
Apache Arrow 覚え書き

以下は、Apache Arrow公式サイトの以下のオーバービューページの翻訳をベースに、自分の理解のための、自由な翻案・省略・追記を含みます。

https://arrow.apache.org/overview/

画像は全て、上記からの引用です。

# Apache Arrow の概要
Apache Arrow は、大規模なデータ セットを処理および転送する高性能アプリケーションを構築するためのソフトウェア開発プラットフォームです。

Apache Arrowの設計目標は、**分析アルゴリズムのパフォーマンス**と、**あるシステムまたはプログラミング言語から別のシステムまたはプログラミング言語へのデータ移動の効率**の両方の向上です。

Apache Arrow の重要なコンポーネントは、**メモリ内の列形式**です。

Apache Arrowは、メモリ内で構造化されたテーブルのようなデータセットを表現するための、**言語に依存しない標準化された仕様**を設計・実装します。
このデータ形式には、分析データベース システムやデータ フレーム ライブラリなどのニーズをサポートするように設計された豊富なデータ型システム (ネストされたデータ型やユーザー定義のデータ型を含む) が含まれています。

## 実行効率向上のためのカラムナーデータ型の選択
Apache Arrow 形式を使用すると、計算ルーチンと実行エンジンが、大きなデータ チャンクをスキャンして反復するときに効率を最大化できます。特に、連続した縦列レイアウトにより、最新のプロセッサに含まれる最新の SIMD (単一命令、複数データ) 操作を使用したベクトル化が可能になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/246c9cc9-b513-9d8b-f19e-19b64793800a.png)

## 標準化による保存
標準の列指向データ形式がなければ、すべてのデータベースと言語は独自の内部データ形式を実装する必要があります。これにより、大量の廃棄物が発生します。あるシステムから別のシステムにデータを移動するには、コストのかかるシリアル化と逆シリアル化が必要になります。さらに、一般的なアルゴリズムはデータ形式ごとに書き直さなければならないことがよくあります。

Arrow のメモリ内列指向データ形式は、これらの問題に対するすぐに使用できるソリューションです。Arrow を使用またはサポートするシステムは、ほとんどコストをかけずにシステム間でデータを転送できます。さらに、他のすべてのシステムにカスタム コネクタを実装する必要もありません。これらの節約に加えて、標準化されたメモリ形式により、言語を超えてもアルゴリズムのライブラリの再利用が容易になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/7bd29ea4-253a-a74b-01f3-71f7bec217ad.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/33d65cbc-0e7c-531d-4a39-d4d13ff67ebe.png)


## アローライブラリ
Arrow プロジェクトには、多くの言語で Arrow 列形式のデータを操作できるライブラリが含まれています。C ++、C#、Go、Java、JavaScript、Julia、およびRustライブラリには、Arrow 形式の個別の実装が含まれています。さらに、C (Glib)、MATLAB、Python、R、およびRuby用の Arrow ライブラリが C++ ライブラリ上に構築されています。
LoRaモジュールのE220-900T22Sを使ってみた！

今回お客様から「安価なカメラモジュールでAI画像解析を行って、LoRaで長距離伝送をしたい」と
ご要望頂きましたので、今安価に販売されているLoRaモジュールの「E220-900T22S」を使ってみました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/b8576c08-7cd0-de7f-39a0-15f5a1f221aa.png)

今回は送信側をESP32で制御。
受信側は、PCで行いたいと思います。
安価なカメラモジュールでのAI画像解析は後ほど投稿しますね！


## ハードウェア
1、E220-900T22S　2セット
https://www.switch-science.com/products/8672
2、ESP32-S3-DevKitC-1-N8　1個
https://akizukidenshi.com/catalog/g/gM-17073/
3、USBシリアル変換モジュール　1個
https://akizukidenshi.com/catalog/g/gM-11007/

## 配線
受信側
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/b32b542a-f49a-37b5-4bf3-a9c005c43266.png)

送信側
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/7e654bd4-4284-422c-c2cf-ba1be6a45fa1.png)

## プログラム
【受信側】
受信はPC上で起動するフリーソフトの「SerialDebug2」を使用して、モニタリングをした。


【送信側】
```c
const int ledPin = 48;

void setup() {
  Serial.begin(9600);       // シリアル通信を9600bpsで開始
  pinMode(ledPin, OUTPUT);  // LEDピンを出力モードに設定
}

void loop() {
  delay(900); // 900ms待機

  digitalWrite(ledPin, HIGH);
  
  // 16進数「0xFF, 0xFF, 0x01, 0xFF」をシリアル通信で送信
  Serial.write(0xFF);   //ブロードキャスト上位
  Serial.write(0xFF);   //ブロードキャスト下位
  Serial.write(0x01);   //チャンネル番号
  Serial.write(0xFF);   //DATA

  Serial.print("\r\n"); // CRLF（改行）をシリアル通信で送信

  delay(100);

  digitalWrite(ledPin, LOW);
}
```
送信する側は、送信するたびにボードに内蔵されてあるLEDを点灯させています。

## テスト
それでは送信機を離れたところまで持っていき、
無事データを受信するか試してみましょう！！

送信端末は、こんな感じで手作りしました！
少々見た目は悪いですが、試作機なのでOK！
電源はモバイルバッテリーを使用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/442045c6-e4d2-0354-e315-97d1db94bfbe.png)

受信端末は、こんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/27bb3edc-9da7-b96b-aec9-726854273bff.png)

それでは会社の端っこまで送信端末を持って、移動してみましょう！！
今回のプログラムは1秒間隔で「0xFF」を送信するプログラムですが、
無事PCで受信することが出来ました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/189e83a2-04e4-490c-2cc7-548e7123ef8d.png)
（画像が見にくくてすみません。）

## まとめ
今回は安価なLoRaモジュール「E220-900T22S」を使用しました。会社の中は全て正常に通信できました。
また送信速度も早いです。
LoRaには、「ADR」「SF」「BW」など本来は色々設定が必要で、
距離や送信したいデータ量、通信速度によって可変することが重要です。

長距離でデータを送信したい方！
開発依頼お待ちしております！
まずはお気軽にご相談ください！
GASでQiita投稿があったらスラックに通知を流す

## はじめに
GASを触り始めたのでスラックを使ったものにも挑戦してみたお話しです。
APIも触り慣れていないので凡ミスなども目立ちました。

## 準備
- Qiitaアカウントと記事を投稿しておく
- Qiita APIを使うにあたってトークンを発行しておく　※
- スラック投稿できるようにAppなどを用意しておく

※参考記事

https://qiita.com/miyuki_samitani/items/bfe89abb039a07e652e6


## 参考記事
このスクリプトを作るにあたって以下の記事を参考にしました。

https://qiita.com/Futo_Horio/items/6eff81da9d85acbcaecf

https://zenn.dev/kenghaya/articles/6ff68c70235d49


## やったこと
1. JSONデータでQiita記事の情報を取得
1. 上のデータからタイトルと日付、URLを取得する
1. 1時間以内に投稿された記事があればスラックにテキストなどのデータを渡す
1. スラックAPIを使って指定したチャンネルにメッセージを飛ばす

### ソース（記事取得の部分のみ）
```Qiita.gs
const url = "Qiita個人ページのフィードURL";
const apiKey = "Qiita APIのトークン";

const qiitaPost = () => {
    //Qiita API
    const apiUrl = "https://qiita.com/api/v2/authenticated_user/items";
    
    //自分の投稿記事の情報を取得
    const response = UrlFetchApp.fetch(apiUrl, {
        headers: {
          Authorization: `Bearer ${apiKey}`,
        },
    }

    // レスポンスからJSONデータを取得
    const data = response.getContentText();
    const jsonData = JSON.parse(data);

    // 取得したデータから記事のURLを抽出してSlackに投稿
    for (let i = 0; i < jsonData.length; i++) {
        const postUrl = jsonData[i].url;
        const title = jsonData[i].title;
        const createdAt = jsonData[i].created_at;
        
        // 投稿日時をDateオブジェクトに変換
        const postDate = new Date(createdAt);

        // 現在の日時を取得
        const nowTime = new Date();

        // 1時間以内に投稿された記事のURLをSlackに投稿
        if (nowTime - postDate <= 3600000) {
          const user = "ユーザー名";
          const text = `@${user} さんが【${title}】を投稿しました。\n${postUrl}`;
          postSlackbot(text);
        }
    }
};

// あとはスラックの投稿APIの設定を追加する
```


## 壁だったところ
### XMLでは記事URLは取得できない
参考にした記事ではXMLデータから記事の投稿日時やタイトルを取得していましたが、記事のURLはXMLでは取得できないのでJSON取得しました。

### APIの使い方をはじめに確認しておく
```
Exception: Request failed for http://qiita.com returned code 403. Truncated server response: <html> <head><title>403 Forbidden</title></head> <body> <center><h1>403 Forbidden</h1></center> </body> </html> (use muteHttpExceptions option to examine full response)
```
トークン発行し忘れていた為、ずっとスクリプト実行すると跳ね返されており、原因に気づくのが遅れました.......APIのトークン発行は最初にやっておくべきでした。

### QiitaAPIのURLによっては取得するURLの範囲が広がる
最初、apiUrlに設定していたURLを`https://qiita.com/api/v2/items`にしていたのですが、この状態だと、自分のみではなく1時間以内に投稿された記事が全部取れてしまったため

`https://qiita.com/api/v2/authenticated_user/items`に変更して認証中のユーザーの記事のみにしています。

▼参考

https://qiita.com/api/v2/docs#get-apiv2authenticated_useritems
【Go】POSTのAPI作成

# 作るもの
- NameとEmailをPOSTで送り、それに基づくレスポンスを返すようなAPI（Go言語）。
- POST以外のメソッドは受け付けないようにする。

![スクリーンショット 2023-08-01 16.51.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1850625/7892ba22-966a-0c1f-dfe3-39b947535344.png)

![スクリーンショット 2023-08-01 16.51.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1850625/989eedeb-d34e-366a-61d3-b035247d2b1f.png)

# 実装
```go:main.go
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
)

// RequestBody はPOSTリクエストのJSONデータを格納する構造体。
type RequestBody struct {
	Name  string `json:"name"`
	Email string `json:"email"`
}

// ResponseBody はレスポンスのJSONデータを格納する構造体。
type ResponseBody struct {
	Message string `json:"message"`
}

func main() {
	// ルーティング設定
	http.HandleFunc("/api", handleAPI)

	// サーバーを起動し、ポート8080でリクエストを待ち受ける
	port := ":8080"
	fmt.Printf("サーバーをポート%sで起動中...\n", port)
	err := http.ListenAndServe(port, nil)
	if err != nil {
		log.Fatalf("サーバーの起動に失敗しました: %s", err)
	}
}

func handleAPI(w http.ResponseWriter, r *http.Request) {
	// POSTメソッド以外のリクエストを受け付けないようにする
	if r.Method != http.MethodPost {
		http.Error(w, "POSTメソッドのみ受け付けています", http.StatusMethodNotAllowed)
		return
	}

	// リクエストボディの読み取り
	var requestBody RequestBody
	err := json.NewDecoder(r.Body).Decode(&requestBody)
	if err != nil {
		http.Error(w, "リクエストの解析に失敗しました", http.StatusBadRequest)
		return
	}

	// データ検証
	if requestBody.Name == "" || requestBody.Email == "" {
		http.Error(w, "nameとemailの両方のフィールドが必須です", http.StatusBadRequest)
		return
	}

	// 受け取ったデータを使って何らかの処理を行う（ここでは簡単な例としてそのままレスポンスを作成）
	responseMessage := fmt.Sprintf("Hello, %s! Your email is %s.", requestBody.Name, requestBody.Email)

	// レスポンスの作成
	responseBody := ResponseBody{
		Message: responseMessage,
	}

	// レスポンスをJSON形式で返す
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK) // 200 OK
	err = json.NewEncoder(w).Encode(responseBody)
	if err != nil {
		http.Error(w, "レスポンスの作成に失敗しました", http.StatusInternalServerError)
		return
	}
}
```

# Postmanで確認
- 以下の画像の通り設定を行って、レスポンスが返ってこれば成功。
![スクリーンショット 2023-08-01 16.51.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1850625/ac71f11f-0fea-ca00-72c2-78cdf4d816c2.png)

- POST以外のメソッドも受け付けないようになっているか確認。
![スクリーンショット 2023-08-01 16.51.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1850625/be727981-d4fe-d3a4-28f4-b18504d5e5a0.png)
romeを使ってみた

rome公式
https://rome.tools/

## 特徴
romeはlinter,formatterの統合ツールであり、高速に動作するのが特徴です。

## 使ってみた感想
早いです。早いは正義
細かいルールがESlintなどと異なるためそこさえ問題なければ十分使えそう。

## サンプル
eslint,prettierが重いなと思い利用してみたサンプルの設定ファイルです。

```json:rome.json
{
  "$schema": "https://docs.rome.tools/schemas/12.1.3/schema.json",
  "organizeImports": {
    "enabled": true
  },
  "vcs": {
    "enabled": true,
    "clientKind": "git",
    "useIgnoreFile": false
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "correctness": {
        "noUnusedVariables": "warn"
      },
      "nursery": {
        "useCamelCase": "warn",
        "useExhaustiveDependencies": "warn",
        "useHookAtTopLevel": "error"
      }
    },
    "ignore": ["node_modules"]
  },
  "formatter": {
    "enabled": true,
    "formatWithErrors": true,
    "indentStyle": "space",
    "indentSize": 2,
    "lineWidth": 100,
    "ignore": ["node_modules"]
  },
  "javascript": {
    "formatter": {
      "quoteProperties": "asNeeded",
      "quoteStyle": "single",
      "trailingComma": "es5",
      "semicolons": "always"
    }
  }
}

```
【Rails】リンクで言語を切り替える方法

オリジナルアプリ製作中にこの機能の実装をしたかったので、調べて実装してみました。
（間違いありましたらご指摘いただけますと幸いです。）

# 1.デフォルトの言語などの設定

```application.rb
    config.i18n.available_locales = %i(ja ko)
    #（）の中にjaやko等、使用可能な言語の記載を行う
    config.i18n.enforce_available_locales = true
    #enforce_available_localesをtrueにすることで上記以外の言語の際はエラーを発生させることができる
    config.i18n.default_locale = :ja
    #デフォルトの言語を設定する
    config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] 
    #ymlファイルを読み込む設定をする
```

# 2.コントローラー

```application.controller.rb
class ApplicationController < ActionController::Base
before_action :set_locale

  def change_locale
    locale = params[:locale].to_sym
    #リクエストのパラメーターで渡された言語を取得し、シンボルに変換(params[:locale]は言語切り替えリンクから送られてくるパラメータ
    locale = I18n.default_locale unless I18n.available_locales.include?(locale)
    #取得した言語が使用可能な言語ではない場合、デフォルトの言語を使用する
    session[:locale] = locale
    #選択した言語をセッションに保存する
    redirect_back(fallback_location: root_path)
    #現在のページにリダイレクトする（これによって言語の切り替えのみが行える）
  end

private

  def set_locale
    I18n.locale = session[:locale] || I18n.default_locale
  end
end
```

# 3.ルーティング

```route.rb
get 'change_locale/:locale', to: 'application#change_locale', as: :change_locale
#change_locale/:localeの:localeの部分にjaやkoが入る
#ApplicationControllerのchange_localeアクションが実行されるように指示
```

# 4.リンクとymlファイルの作成

```application.html.erb
<%= link_to "한국어", change_locale_path(:ko) %>
<%= link_to "日本語", change_locale_path(:ja) %>
```

```ja.yml
ja:
  button_topic_create: 'トピックを作成する'
  view topic: 'トピックを見る'
  edit: '編集'
  delete: '削除'
```

```ko.yml
ko:
  button_topic_create: '토픽 만들기'
  view topic: '토픽 보기'
  edit: '편집'
  delete: '삭제'
```

ボタンや、リンクの文字を翻訳する場合は下記のようにViewを編集する
```view
<%= link_to t('view topic'), topic_path(topic.id)%>
<%= link_to t('edit'), edit_topic_path(topic.id)%>
```

他にもいろいろ方法はあると思うので、ここの部分こうした方がいいよとか楽だよとかあればご共有ください。
よろしくお願いします！！
スッキリわかるJava入門 第３版を読んでみて- part２ -式と演算式

# はじめに
こんにちは・ω・）ﾉ
前回に引き続いてスッキリわかるJava入門のまとめを書いていこうと思います（＾ω＾）
今回は式や型変換について学びました！

## 第２章　式と演算式
### 1.計算の文
`b= a + 5`のようなもの __式__　という
・「b」「a」「5」を __オペランド__
・「=」「+」を __演算子__

__すべての式はこの２つの要素でできている__
### 2.オペランド
__リテラル__...ソースコードに記述されている具体的な値,リテラルはデータ型を持っている

__エスケープシーケンス__...¥記号と後に続く文字
何に使うのか？
　⇨ ” や ’ を文字として取得する
### 3.評価のしくみ
__評価__...式に従って計算処理をすること

#### 評価の３つの原則
1.評価結果への置換の原則
　演算子はオペランドを巻き込んで結果に置き換わる
2.優先順位の原則
　Javaで決められた優先順位の高い演算子から順に評価される
　↑基本的に数学と変わらない？
3.結果規則の原則
　同じ優先順位グループに属する演算子が複数ある場合
　⇨演算子ごとに決められた「方向」から順に評価される
### 4.演算子
__算術演算子__
　基本の５つ
　　＋（足し算）
　　ー（引き算）
　　＊（掛け算）
　　／（割り算）
　　％（割り算の余り）
__文字列結合演算子__
　文字列オペランドを結合して１つの文字列にする
　　＋（文字列の連結）
__代入演算子__
　右オペランドの内容を左オペランドの変数に代入する
　　＝　（右辺を左辺に代入）
　　＋＝（左辺と右辺を加算して左辺に代入）
　　etc...
__インクリメント/デクリメント演算子__
　＋＋　（値を１増やす）
　ーー　（値を１減らす）
※++と--は他の演算子と使わない
### 5.型の変換
原則：演算子の多くは左右のオペランドが同じ型であること
⇨文法エラーにならないのはなぜ？
　⇨Javaが指揮を評価する過程で自動的に型を変換しているから

Javaを変換する３つのしくみ
1.代入時の自動型変換
2.強制的な型変換
3.演算時の自動型変換

__1.代入時の自動型変換__
ある型で宣言された変数には、その値しか代入できない
　小さな値　⇨　大きな値　のみ自動変換できる
※逆はできない...入りきらない可能性

__2.強制的な型変換__
元のデータの一部を失ってもデータを強制的に変換する
__キャスト演算子__
　（変換先の型名）式
__:warning:よほどの理由がない限り使わない__

__3.演算時の自動型変換__
「意味的に大きな型」に統一されてから演算

### 6.命令実行の文
命令実行の文
　`呼び出す命令の名前　(引数);`
　⇨Javaが準備してくれている様々な命令を呼び出すための文

-その他の命令-
画面に文字を表示する命令
　`System.out.println(①);`

文字列を数値に変換する命令
　`int n = Integer.parseInt(①);`

キーボードから一行の文字列の入力を受け付ける
　`String s = new java.util.Scanner(System.in).nextLine();`

## まとめ
この章では型の変換、特に代入時の自動型変換について知れたのが大きいと感じました。
小さい値⇨大きい値のみ自動変換できるのは知らなかったです Σ( ˙꒳˙ ;)
計算の式や評価のしくみの基本を知ることができてよかったです。
インクリメント/デクリメントを他の演算子と使えないことは知らなかったので気をつけたいです。

今回もありがとうございました！
ではまた〜　＊˙︶˙＊)ﾉ"
Oracle Analytics Cloud：数値書式を整数表示にする。ワークブック側で設定する。

はじめに					
---					
数値項目の数値書式を整数表示に変更してみます					
数値書式を変更する際、２つ方法があります。１つめはデータセットの列に対して変更する、２つめは、レポート側、つまり表やピボット、グラフなどのビジュアライゼーションで変更する方法があります					
今回は、レポート側、つまり表やピボット、グラフなどのビジュアライゼーションで変更する手順を試してみます。					

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/2238e400-66b8-0af4-3ffb-815eb9f7db1b.png)

ビジュアライゼーションで小数のデータを整数表示します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/2032dce9-41e1-57b5-926f-a2e03da169dd.png)

データセットの作成	
---	
以下のExcelファイルをアップロードしてデータセットを作成します。	
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/8aebf47b-46e8-47fa-906c-3290d1b1a033.png)

作成されたデータセットは以下です。データセットは数値書式を設定せずに利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/4bc54e89-f38b-7437-ca6b-9fde2a37400e.png)

ビジュアライゼーションで数値書式を設定する
---
データセットを開き、右上部、ワークブックの作成をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/6e04d947-cde6-fe58-bd7f-3691d1b7709a.png)

列をクリックします。Ctrlキーを押しながら複数の列を選択し、右クリックします。
右クリックメニューが表示されたら、ビジュアライゼーションの選択をクリックします
表をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/b988c178-8b56-3bab-0f79-5681d7f1bc59.png)

真ん中のプロパティタブをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/5c12681c-863b-eb68-7b72-ed162d97691e.png)

プロパティペインで、「＃」（値）タブをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/59f7e460-b65c-f8c6-2316-29d1c2dd2c65.png)

「＃」タブの整数表示する列で、数値書式の「自動」のところをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/d36ddfce-8664-ece9-1b2d-7cf5f5870625.png)

「数値」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/355b0573-9337-8e6a-15b8-42b4745edae1.png)

小数点の「2」をクリックします。整数表示は「0」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/11e307e9-9631-44d7-9d56-8f2c6f691242.png)

整数表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/2ed7ef6c-653a-0769-4786-05035eefbb13.png)

ビジュアライゼーションで設定することで、特定のビジュアライゼーションに対して数値書式を設定できます。数値書式はデフォルトでは、データセットでの書式が引き継がれますので、個別で設定したい場合は、ビジュアライゼーションで設定することで対応できます

データセット側では汎用的な書式をセットする。ビジュアライゼーションでは個別に書式をセットする。という使い分けが考えられます。

以上
JavaでPowerPointをXPSに変換する

## はじめに
PowerPointのプレゼンテーションをXML Paper Specification（XPS）に変換することで、ユーザーはPPTファイルを異なるプラットフォームで印刷や共有が可能な形式に変換することができます。XPS形式は、元のプレゼンテーションのレイアウト、グラフィック、フォーマットを保持し、高品質な印刷出力効果を提供します。PPTをXPSに変換することで、ユーザーは特定の要求や使用シナリオに応じて、PPTファイルを静的に閲覧および配布可能なXPSファイルに簡単に変換することができます。以下に変換方法をご紹介します。

## ツール
IntelliJ IDEA 2018 (jdk 1.8.0)
[Free Spire.Presentation for Java](https://www.e-iceblue.com/Introduce/free-presentation-for-java.html)
ご注意ください。この無料版には、スライド枚数が3枚までの制限があります。さらに多くのスライドを変換したい場合は、[商用版](https://www.e-iceblue.com/Introduce/presentation-for-java.html)をご利用いただけます。使用する前に、[一時的な許可](https://www.e-iceblue.com/TemLicense.html)を申請してください。

## Jarファイルの導入
* [Free Spire.Presentation for Java](https://www.e-iceblue.com/Download/presentation-for-java-free.html)をダウンロードして解凍します。
* IDEAで新しいプロジェクトを作成します。
* 「File」>「Project Structure」>「Modules」>「Dependencies」をクリックします。
* 「+」の「JARs or Directories」を選択します。
* 「Spire.presentation.jar」を見つけてプロジェクトにインポートします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/2a963bfb-29ff-71f9-2a6c-bf1ccb3c228d.png)

## コード：
```java
import com.spire.presentation.*;

public class PowerPointtoXPS {
    public static void main(String[] args) throws Exception{

        //Presentationクラスのインスタンスを作成する
        Presentation ppt = new Presentation();

        //PowerPointファイルを読み込む
        ppt.loadFromFile("sample.pptx");

        //XPSファイルに保存
        ppt.saveToFile("toXPS.xps", FileFormat.XPS);
        ppt.dispose();
    }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/d131bbba-7b02-6432-639c-7ac056c0673a.png)
BashでTerraformのoutputからmapの値を取り出して利用する方法

# はじめに
BashでTerraformのoutputからmapの値を取り出して使うことがあったので備忘録的に書いていきます。

# 方法について

```tf:Terraformのoutputの例
output "<output名>" {
  value = {
    for k, v in <リソース>.<リソース名> : k => v.<引数>
  }
}
```

- output名
  - `terraform output`で取り出すときの名前
- リソース
  - クラウドのリソースの名前
- リソース名
  - Terraform内のリソースの名前
- k
  - mapのキー名
- v.<引数名> 
  - mapの値, 取り出したい引数名

```bash:mapのキーを全て取り出したい場合
outputs=( $(terraform output -json <output名> | jq -r 'keys[]') )
```

```bash:mapの値を全て取り出したい場合
outputs=( $(terraform output -json <output名> | jq -r '.[]') )
```

```bash:ループで回したいなら
for output in "${outputs[@]}"; do
    echo "$output"
done
```

何をしているのか簡単に説明すると、
`terraform`コマンドでoutputの値をjson形式で出力、
`jq`コマンドでjson形式の値をbashで利用可能な配列に変換しています。

このスクリプトを実行するには`jq`が必要なので、別途インストールしてください。

```bash:mac
brew install jq
```

#### 番外編

```bash:特定の値を取り出したい場合
output=$(terraform output -json <output名> | jq -r '.<mapのキー>')
```

以上です。

# 最後に
誰かのお役に立てれば幸いです。
SQLAlchemyで取得した値を辞書型で取得したい

# 【前置き】
・案件で作業中、「SQLAlchemy」を使ってDBのVIEWの値を辞書型（dict）で取得し扱いたかったときに良い記事があまりなかったから備忘録として残すことにした。
※また基本的に「SQLAlchemy」はORMを使って値を取得するのが主流だが今回はSQLを直接実行して辞書型で取得する

# 【やること】
SQLAlchemyライブラリで取得したVIEWの値を辞書型として扱うようにする

# 【必要なもの】
#### 〇環境
* Python 3.11
* SQLAlchemy 2.0.13
* 使用DB：「SQL Server 2017 Standard」

# 【ソース】

* 通常は`session.excute().all()`で取得すると実行結果の値(全件)のみを取得してくる
``` diff_python
import sqlalchemy
from sqlalchemy import Engine, Row, create_engine
from sqlalchemy.orm import sessionmaker

def __init__(self, connection_str: str) -> None:
        self.engine = create_engine(connection_str, echo=False)

        self.session_maker = sessionmaker(autoflush=True, bind=self.engine)

#stmt:VIEWのSELECT文
def get_view_data(self,stmt)-> set[Row]:
    with self.session_maker.begin() as session:
        return session.execute(stmt).all()
        #[{'Taro',20},{'Hanako',19},{'Yukiko',17}]
 ```

* しかし`session.excute().mapping().all()`で取得すると...
→[key：value]の辞書型で取得することが出来る！！
``` diff_python
def get_view_data(self,stmt)-> set[Row]:
    with self.session_maker.begin() as session:
        return session.execute(stmt).mapping().all()
        #[{'name':'Taro','age':20},{'name':'Hanako','age':19},{'name':'Yukiko','age':17}]
```

* また普通に辞書型と同じように扱うこともできる！
``` diff_python
for p in person:
    print("【name】")
    print(p["name"])

    print("【age】")
    print(p["age"])

#【name】
# Taro
# Hanako
# Yukiko

#【age】
# 20
# 19
# 17
```

# 【あとがき】
簡単に記載しましたがこれで辞書型で取得が可能となりました。
正直ORMを使えた方がSQLAlchemyを有効活用できるのですがそもそもORMについての土台を理解出来てなかったので今回は直接SQL文を実行しての形となりました。
方法については海外の記事はありましたが日本語での記事が全くないので是非参考にしていただけたら幸いです。

# 【参考ドキュメント】
* SQLAlchemy2.0ドキュメント

https://docs.sqlalchemy.org/en/20/core/connections.html#sqlalchemy.engine.MappingResult.columns

* Qiitaの別記事

https://qiita.com/syuuu/items/07bf3b3180d4b1267f55#%E4%BF%AE%E6%AD%A3%E5%BE%8C-2
Reactで音声認識してChatGPTに質問する

# 目次
[成果物](#成果物)
[フロントエンド(Next.js)の実装](#フロントエンドの実装)
[エラーが出る場合](#エラーが出る場合)
[ローカル開発でマイクがONにできない場合](#ローカル開発でマイクオンにできない場合)

# 成果物
無音なのでわかりづらいが、自分の声がしっかり音声認識されている。
![speechAI.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526938/bfd4217b-ce73-2a98-f9ba-99d8c1b3ce6a.gif)

# フロントエンドの実装
音声認識には[こちらのライブラリ](https://github.com/JamesBrill/react-speech-recognition)を使う。
```tsx
import SpeechRecognition, {
    useSpeechRecognition,
} from "react-speech-recognition";

export const SpeechButton = () => {
    const [inputText, setInputText] = useState("");
    const { transcript, listening } = useSpeechRecognition();

    useEffect(() => {
        if (listening) setInputText(transcript);
    }, [transcript]);

    return (
        <>
            <button
                type="button"
                onClick={() => SpeechRecognition.startListening()}
            >
                {listening ? "認識中" : "音声入力"}
            </button>
            <button
                type="button"
                onClick={() => setInputText("")}
            >
                リセット
            </button>
            <p>{inputText}</p>
        </>
    );
}
```
上記コードを実装し、音声認識で入力された inputText をOpenAIのAPIに渡してあげればChatGPTに質問できる。
バックエンド側は[こちらの記事](https://qiita.com/gwanryong/items/b1b012e90df4878ca9b9)参照。

# エラーが出る場合
アプリを起動してReferenceエラーが出る場合は、、

1. `npm install regenerator-runtime`を実行する
2. `import "regenerator-runtime";`を上記Reactコードの一番上に書いてあげる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526938/8684002b-f385-e8de-f840-d336df9c4cbb.png)

# ローカル開発でマイクオンにできない場合
ローカル開発だとhttps対応していないので、ブラウザのマイクがブロックされている場合がある。
[こちらの記事](https://qiita.com/dmiya/items/77eadd8abdfd7282d917)を参考に以下を実行するとマイクオンできた。
1. Chromeのアドレスバーに`chrome://flags/#unsafely-treat-insecure-origin-as-secure`を入力して検索
2. `Insecure origins treated as secure`という欄にローカル開発で起動しているURLを入力してEnabledを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526938/2592ca62-1a9b-f062-ae1b-519c52ce4ca1.png)
Windowsのコマンドプロンプト（bat）で特定ファイルを特定フォルダーへ移動

# やり方（基本）

```bat:move.bat
rem このbatと同じフォルダー内にある『ほげえ.txt』をbatと同じフォルダー内にある『to』という名前のフォルダーへ移動
move ほげえ.txt to
```

bat実行前が下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/13f613aa-1bfb-4ceb-6407-95e0bd9c99df.png)

bat実行後は下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/833f636c-b37e-7c7f-908c-e2de4b4af1bb.png)

txtファイルは下記に移動された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0e86306c-f1e2-4e54-99e5-023cafe6e354.png)

# 移動先フォルダーパスの末尾に『\』は？

付けても付けなくてもどちらでもよいです。

下記のように書いても、前述のサンプルと同じ動作になります。

```bat:
move ほげえ.txt to\
```

動作は同じですが『移動先フォルダーが存在しない場合』の挙動が違います。
詳細は後述。

想定外の事故を防ぐ為に移動先フォルダーパスの末尾に『\』は付けておくのがおススメです。

# やり方（リネーム移動）

```bat:
rem このbatと同じフォルダー内にある『ほげえ.txt』に対する操作。
rem batと同じフォルダー内にある『to』という名前のフォルダーへ移動。
rem ただし、移動時にリネームも行う。
move ほげえ.txt to\ふがあ.txt
```

# 特定の拡張子ファイルをまとめて移動

```bat:
rem このbatと同じフォルダー内にあるtxt拡張子に対する操作。
rem batと同じフォルダー内にある『to』という名前のフォルダーへ移動。
move *.txt to\
```

# 移動先フォルダーの存在有無に注意

下記状態で…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ec915ef1-0ed2-0cf1-2102-9e9bc808a426.png)

下記batを実行すると…

```bat:move.bat
rem 『ふにゃー』という名前のフォルダーが存在しない時どうなるか。
move ほげえ.txt ふにゃー
```

移動対象のtxtがリネームされてしまいました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/bd587260-e4b0-f5c1-0b43-463a7246ea96.png)

フォルダーパスの末尾に『\』を付けておくと…

```bat:move.bat
rem 『ふにゃー』という名前のフォルダーが存在しない時どうなるか。
move ほげえ.txt ふにゃー\
```

bat実行後にtxtはリネームされません。
（何も起きない）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/f69f5ed5-c999-1c40-c525-bfffd3db6cba.png)

# 移動先に同名ファイルがある場合（ファイル上書き）

下記のように移動先に同名ファイルが存在する場合…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/2e294f26-c2dc-b258-e4b5-610f083b0bfd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/5c84c3ac-2036-42c9-69d9-9f558667da51.png)

```bat:move.bat
rem 移動先に同名ファイルがあることによるファイル上書き発生。
move ほげえ.txt to\
```

実行後は下記のようにファイル上書きされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/1fceb0c1-9629-d908-76c2-9376381b5e1b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ad29211b-60fa-40d3-6215-42f9a342b8c5.png)
実際はtxtの中身を変えるなどして本当に上書きされたか確認しましたが、そのあたりは割愛。

# 参考サイトさん

https://www.javadrive.jp/command/file/index7.html

# バージョン

Microsoft Windows [Version 10.0.19045.3208]

TODO:moveはフォルダー名変更にも使えるでそのやり方まとめる。
TODO:フォルダー内の全ファイルを別フォルダーに移動するやり方まとめる。
コールヒエラルキーを使うといい場面と避けたほうがいい場面

# コールヒエラルキー

:::note
**メソッドや関数がどのように呼び出されているか**に関する階層構造
:::



## コールヒエラルキーを使うといい場面の例

### 影響範囲の把握
- 特定のメソッドが他にどのメソッドから呼び出されているかを知る
→**変更を加える予定のメソッドが他のメソッドに影響を与えるかどうかを特定**するのに使える

### テスト対象の特定
- 変更される可能性のあるメソッドがどのテストケースに関連しているかを特定
→影響を受ける可能性のあるテストケースを重点的に検証可能

### リファクタリングのサポート
- リファクタリングを行う際に、変更したいメソッドが他の部分にどのように影響を及ぼすかわかる
→リファクタリングが正確で安全に行える

### デバッグとトラブルシューティング
- 特定のメソッドがどのように呼び出され、データや処理がどのように伝播しているかわかる
→問題の原因を特定しやすくなる

### パフォーマンス最適化
- コールヒエラルキーを分析することで、パフォーマンスボトルネックを特定できる

<details><summary>パフォーマンス最適化の例
</summary>

- ウェブアプリケーションのリクエスト処理が多数のコントローラーから共通のサービスメソッドを呼び出す場合
→**サービスメソッドのパフォーマンスを最適化することで全体の処理速度を向上できる**

</details>




## コールヒエラルキーを避けた方が良い場面の例

### 過度な依存

- 過度な依存を持つコードは保守性が弱く、バグの発生リスクが高まる

<details><summary>過度な依存の例
</summary>


- 以下のような循環的な依存関係がある場合

クラスAがクラスBを呼び出す
↓
クラスBがクラスCを呼び出す
↓
クラスCがクラスAを呼び出す


</details>

### 依存の逆転の原則(Dependency Inversion Principle, DIP)違反

- 高レベルのモジュールが低レベルのモジュールに直接依存している場合
→高レベルのモジュールが低レベルの実装の詳細に依存してしまうということ

:::note
高レベルのモジュールが低レベルのモジュールを直接呼び出すのではなく、**抽象化されたインターフェースに依存すべき**
:::

</details>

<details><summary>依存の逆転の原則違反の例（データベースにアクセスするシステムの場合）
</summary>

### 依存の逆転の原則に違反する設計

```Java
class DatabaseAccess {
    // データベースにアクセスするコード
    public void query() {
        // データベースにクエリを送信する処理
    }
}

class Service {
    private DatabaseAccess databaseAccess;

    public Service() {
        this.databaseAccess = new DatabaseAccess();
    }

    public void doSomething() {
        // データベースへのアクセスを使った処理
        databaseAccess.query();
    }
}
```

Serviceクラスが直接DatabaseAccessクラスをインスタンス化して使用している
→**高レベルのServiceクラスは低レベルのDatabaseAccessクラスに依存している**

### DIPに従う設計

```Java
interface DataAccess {
    void query();
}

// DataAccessはデータベースへのアクセスを抽象化するインターフェース
// queryメソッドが定義されているが、具体的な実装は以下のDatabaseAccessへ

class DatabaseAccess implements DataAccess {
    // データベースにアクセスするコード
    public void query() {
        // データベースにクエリを送信する処理
    }
}

class Service {
    private DataAccess dataAccess;

    public Service(DataAccess dataAccess) {
        this.dataAccess = dataAccess;
    }

    public void doSomething() {
        // データベースへのアクセスを使った処理
        dataAccess.query();
    }
}

// Serviceクラスはデータベースアクセスを行うクラス
// DatabaseAccessクラスに直接依存はしていないが、その代わりにDataAccessインターフェースに依存している

```
ServiceクラスのコンストラクタでDataAccessインターフェースの実装を受け取る
↓
doSomethingメソッド内では、具体的な実装を意識することなくDataAccessのqueryメソッドを呼び出すことができる

</details>
公開リンクボタンを非表示にする

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめN～Z](https://qiita.com/Keiji_otsubo/items/92f92bb9f668ca9688be)


# Salesforceの場合

プロファイル --> システム設定 --> 公開リンクの作成をチェックをfalseにする

公開リンクボタンはないですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/c1bef0e4-c73a-d71c-25d6-7381389f8897.png)

この画面からも消せました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/0d66a5ed-f997-8a7d-5f2e-d437153228ee.png)


# SharePoint 

[サイトの共有設定を変更する](https://learn.microsoft.com/ja-jp/sharepoint/change-external-sharing-site)


# 表示できない

+ [Why can't I create a public link for file?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A8t1mSAB)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/ca9d487a-74e8-975c-8305-9c618001b8de.png)

+ [Issues with trying to have a public link to a document in Salesforce](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007IdKuj)


Can't create  public link. you can try asking the file owner for access

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/1c3374d7-738f-9203-203d-5efbd00f3010.png)


 + [Option to Share Files on Library via Public Link Not Available](https://help.salesforce.com/s/articleView?id=000391143&type=1)