OmniAICreator/Qiita-1.07M huggingface dataset:
Pixel 8でソフトバンク回線(Nuroモバイル)を使用したときにネットワークを正常につかめなくなることがある話

Pixel 8でソフトバンク回線(Nuroモバイル)を使用したときにネットワークを正常につかめなくなることがある話

# Googl Pixel 8をソフトバンク回線で使う
Nuroモバイルが妙に安かったので、UQモバイルからこちらに移った。
ただ、SIM挿入後Nuroモバイルに記載がある設定どおり入力してもどうしても電波をつかまない。
何か設定足りないんだろうな、と思いいろいろ調べてみる

## APNタイプが怪しい？
つかまない理由がわからないけど、Nuroの設定資料には記載がないけどPixelのAPN設定画面でいろいろ情報が入っているものというとAPNタイプしかない。
こちらが怪しいよね、ということでいろいろ調べていると…

https://mobile.nuro.jp/support/device/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101039/56afde49-d589-3eb2-d35a-f6a26802d6b0.png)

こんな記載を発見した。au版GooglePixel8では、上記のような設定で動作検証をしていたっぽい。
  APNタイプ：default,supl,ia,dun 
これに従って入力をしてみるとうまくつながった。

もうちょっと調べてみる。
Pixelの仕様なのか、APNタイプを任意で指定しない場合「default,mms,supl,dun,hipri,fota,cbs,xcap」が指定されるっぽい。
動作検証のAPNタイプとPixelのデフォルトAPNタイプを比べてみると、iaの有無が差分となる。
PixelデフォルトのAPNタイプに「ia」を加えるとうまく電波をつかむことができた。
ということで、少なくともau版Pixel8では、APNタイプにiaを追加する必要がある、という結論。

ただ、原理的なところは全く理解で来ていないので経験則でしかない。

## いろいろ問題出ているようで。
同じくSoftbank回線を使っているmineoでも同様事象は発生しているようですが、機種によってデフォルト値が違うためか通信業者側の接続マニュアルでAPNタイプを明確に記載しているパターンがあまり見当たらなかった。
Nuroモバイルの動作検証リストも、画面キャプチャではなくて設定値自体も記載してくれていればGoogle検索に引っかかるんですけどね。
いろいろな人がTwitterやらマイネ王にも記載してくれていますが、いろんなところに解決の糸口は書いておいたほうがいいし自分の備忘録としても使いたいのでここに記録しておきます。
【GitHub Actions】secretsはそんなにsecretsじゃない

# はじめに

GitHub Actionsでは、リポジトリに登録された `secrets` をログに出すとき自動的にマスキングしてくれますが、どうやらsecretsとの完全一致の場合のみそれが発動するっぽいのでその実験結果です。

# 事前準備（リポジトリにsecrets追加）

以下のようにリポジトリに `secret` を登録します。

（リポジトリ > `Settings` > `Secrets and variables` > `Actions` > `New repository secret`）

![github_actions_secrets_registration.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3388832/e619d019-6885-0064-9a7a-3cb0efb71acf.png)



# 事前準備（コード）

リポジトリの `secrets` を利用するワークフローファイルを書いて動かします。

```yaml: 実験用.yml
name: jikken-workflow
on:
  workflow_dispatch:

jobs:
  check-secret:
    runs-on: [self-hosted, linux, x64]
    steps:
      - name: マスキングされる
        run: echo "SECRET >>> ${{ secrets.SECRET_CONTENT }}"

      - name: 1文字目の後にスペースを挿入
        run: echo "SECRET >> ${SECRET:0:1} ${SECRET:1}"
        env:
          SECRET: ${{ secrets.SECRET_CONTENT }}

      - name: 最後の文字の前にスペースを挿入
        run: echo "SECRET >> ${SECRET:0:len-1} ${SECRET:len-1}"
        env:
          SECRET: ${{ secrets.SECRET_CONTENT }}

      - name: 全ての文字の間にスペースを挿入
        run: echo "SECRET >> $(echo $SECRET | sed 's/./& /g' | sed 's/ $//')"
        env:
          SECRET: ${{ secrets.SECRET_CONTENT }}
```

# ログ出力してみた結果

ログから機密情報が洩れております...。

![github_actions_secrets_log.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3388832/e47213f4-cf60-7e6d-bb1c-927ad68d0b63.png)


# おわりに

リポジトリの管理者権限がなくても、割と簡単にsecretsは確認できてしまうので、`secrets` への登録はある程度リスクが伴うことを確認できました。

「マスキングされるし安全！」だなんて思わずに、登録しなくてよいものはしないようにするなど、適切に管理していきましょう。


# 参考

https://www.ssw.com.au/rules/mask-secrets-in-github-actions/
StateとPropsについて - React

# Stateとは
システム開発において、ユーザーの入力値など現在の状態を保持しておく必要が出てきます。こういったコンポーネントが固有でもつ状態やデータのことをstateと呼んでいます。
**stateが変化すると、そのコンポーネントは再レンダリングされ、UIが更新されます。**

## useStateを使ったstateの管理
useStateは、コンポーネント内のstate（状態）を管理するためのReactフックです。

### useStateの使い方
useStateは、コンポーネントのトップレベルで呼び出してstate変数を宣言します。
```react
import { useState } from 'react';

export default function App() {
  // トップレベルで呼び出す
  const [state, setState] = useState(initialState);
  
  return ()
}
```
- **引数**
`initialState` : stateの初期値を設定します。
初回レンダー後は無視されます。
- **返り値**
useStateの戻り値を配列の分割代入で取得します。
`state` : 現在の状態を指します。初回レンダー時は、引数で渡したinitialSateと同じ値になります。
`setState` : state（状態）を更新するための関数で、再レンダーをトリガーします。

### useStateの注意点
- useStateはフックであるため、コンポーネントのトップレベルで呼び出す必要があります。ループや条件文の中で呼び出すことはできません
※トップレベル・・・コンポーネントの関数本体の中で、他の関数やループの中ではなく、直接的に実行されるコード部分。
- 状態の変更によりレンダリングが発生するため、頻繁に変更がある状態や重い処理は慎重に扱う必要があります

## useStateを使ったカウントアップボタン
useStateフックでcountというstate変数を初期化し、ボタンをクリックするたびに、setCount関数を使ってcountの値を1増やし、再レンダリングすることでUIを更新します。
```react
import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>現在のカウント: {count}</p>
      <button onClick={() => setCount(count + 1)}>カウントアップ</button>
    </div>
  );
}
```


# Propsとは
propsは、親コンポーネントから子コンポーネントにデータを渡すための手段です。子コンポーネントはpropsを受け取って表示したり、動作に利用したりしますが、propsは子コンポーネント内で直接変更することはできません。

## propsを渡して名前を表示する
親コンポーネントで子コンポーネントを呼び出すときに、nameに値を渡し、子コンポーネントでnameというpropsを受け取り表示します。
```react
// 子コンポーネント
export default function Child(props) {
  return <div>こんにちは、{props.name}さん！</div>;
}
```
```react
// 親コンポーネント
import Child from "./Child";

export default function Parent() {
  return (
    <div className="App">
      <h1>Props</h1>
      <Child name="太郎" />
    </div>
  );
}
```

## 複数のpropsを設定する
propsはオブジェクトとして渡され、各プロパティには親コンポーネントから渡されたデータが含まれます。以下の例では、`name`と`age`、`hobby`の2つのプロパティが含まれるpropsを子コンポーネントで受け取り表示しています。
```react
// 子コンポーネント
export default function Child(props) {
  return <div>私は{props.name}です。{props.age}歳で、趣味は{props.hobby}です。</div>;
}
```
```react
// 親コンポーネント
import Child from "./Child";

export default function Parent() {
  return (
    <div className="App">
      <h1>Props</h1>
      <Child name="太郎" age={17} hobby="サッカー" />
    </div>
  );
}
```

## propsの注意点
- **オブジェクトとして渡される :** `props`はオブジェクト形式で渡され、各プロパティに親コンポーネントから指定された値が入ります。そのため、`props`を受け取るときはオブジェクトの構造を考慮して扱う必要があります
- **読み取り専用 :** 子コンポーネントで受け取った`props`は読み取り専用であり、子コンポーネント内で直接変更することはできません。`props`を変更したい場合は、親コンポーネントから新しい値を渡すようにします
【読書】linuxの作者の自伝を読んだ【それがぼくには楽しかったから】 


# Just for fun(それがぼくには楽しかったから)

こちらです。

https://www.amazon.co.jp/%E3%81%9D%E3%82%8C%E3%81%8C%E3%81%BC%E3%81%8F%E3%81%AB%E3%81%AF%E6%A5%BD%E3%81%97%E3%81%8B%E3%81%A3%E3%81%9F%E3%81%8B%E3%82%89-%E5%85%A8%E4%B8%96%E7%95%8C%E3%82%92%E5%B7%BB%E3%81%8D%E8%BE%BC%E3%82%93%E3%81%A0%E3%83%AA%E3%83%8A%E3%83%83%E3%82%AF%E3%82%B9%E9%9D%A9%E5%91%BD%E3%81%AE%E7%9C%9F%E5%AE%9F-%E5%B0%8F%E3%83%97%E3%83%AD%E3%83%BB%E3%83%96%E3%83%83%E3%82%AF%E3%82%B9-%E3%83%AA%E3%83%BC%E3%83%8A%E3%82%B9-%E3%83%88%E3%83%BC%E3%83%90%E3%83%AB%E3%82%BA/dp/4796880011

日本語版の表紙良いです。
![IMG_4861.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780693/086015da-676b-683e-29d3-fd9e557c063c.jpeg)

日本語版は絶版で、中古市場で3000円以上します。

表紙を外すと。

![IMG_4862.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780693/f80656a2-900c-873b-7ff7-ba4c2b0208fb.png)

装丁も良く、買う価値ありですね。

英語版であれば以下のgithubレポジトリから読めます。

https://github.com/limkokholefork/just-for-fun-linus-torvalds/blob/master/just-for-fun.pdf


# とにかく楽しいことをする

>あの子が大人になるに連れて、心配でたまらなくなりました。あんな調子で、好きな女の子にちゃんと巡り会えるのかしらって。

単に楽しいからやったことが、その楽しさを原動力にしてコンピューターの世界を席巻していくのが描かれます。



# 金のために頑張るというのではなく、楽しいからよりやりこむ、ということの示唆

どう頑張ったらいいかわからない時もあると思います。
直近で給料が増えるわけではない。
少なくとも今日頑張ったから明日給料が増えるということは、あまり無いでしょう。

>リナックスがいいものになっていったのは、また、やりたい気持ちを掻き立ててくれたのは、みんなからの感想だった。感想があるってことこそ、リナックスがそこそこのものであり、僕がその社会的グループの一員だってことを示す証しだったんだ。



# computer scienceの歴史がわかる

>とにかく、ぼくはリナックスを売り物にしたくなかった。リナックスを制しきれ無くなるのも嫌だった。つまり、他人にLinuxを売らせたくないということである。それについては、九月にアップした最初のバージョンのファイルの中で、著作権に関する考え方を明記しておいた。
p.152

・そもそもりーナスはフィンランド出身らしい。アメリカで生まれたとざっくり思っていた。そこからアメリカに行くのは、linux 1.0が出た後のようだった。

・ミニックスっていうのが元々あったらしい。

・unixが元々あって、後発としてlinuxができた、というくらいの知識しかなかったが、周辺の歴史を楽しく読めたので、知識を色々と肉付けできた。


# その他の引用

>リナックスや他のオープンソースプロジェクトに参加しているハッカーは、いや、プログラマーは、睡眠も、ステアマスターでの運動も、子供のリトルリーグの試合も、そして、たまにはセックスも後回しにしている。プログラミングを愛しているのだ。
彼らはまた、望みさえすれば、誰でも手にいれることができる、もとも美しく最高のテクノロジーを作り上げる全地球規模の今日どう作業の一翼をになっていることも愛している。それだけのことだ。それが楽しいのだ。
p.191

すごい

>既存の商業プロジェクトをオープンソース化する可能性について初めて耳にした時は、みんな同じ質問をする傾向があるようだ。そんな質問の一つは、外部の者が社内の者よりいい製品を生み出し、それが世間に公開されてしまう可能性について、社内の人はどう感じるだろう？というものだ。
それは素晴らしいことだと、ほとんど仕事をしないで給料をもらえるとはすごいじゃないかと感じるべきだと、ぼくは思う。この点に関しては、オープンソースは、その他、オープンになるどんなものでも、容赦はない。仕事ができるのは誰か、有能なのは誰か、それが一目瞭然なのだ。経営陣の後ろに隠れることはできない。
p.343

オープンソース化するということ。

# 最後に

楽しく仕事したいですね
just for fun
Ubuntuサーバでユーザを追加

<!-- Ubuntuサーバでユーザを追加 -->

Ubuntuのサーバ上でユーザを追加する方法などの覚え書きです。

## ユーザの確認

ユーザ名は一意である必要があると思うので、新しく追加したいユーザ名が既存のものと被ってないかどうかを確認する必要があります。

一番手軽な方法は、```home```ディレクトリにある各ユーザのディレクトリを確認することです。

```bash
$ ls /home
```

## ユーザの追加

確認できたら、新しいユーザを追加します。

```bash
$ sudo adduser <ユーザ名>
```

これを入力すると、パスワードの入力が求められます。8文字より短いと警告が出ます。

```bash
BAD PASSWORD: The password is shorter than 8 characters
```

その後、ユーザの情報を入力するように求められます。特に必要がなければ、そのままEnterを押してください。

```bash
Enter the new value, or press ENTER for the default
        Full Name []: 
        Room Number []: 
        Work Phone []: 
        Home Phone []: 
        Other []: 
Is the information correct? [Y/n] Y
```

これでユーザの追加は完了です。

## sudo権限の付与

個人用サーバなどであれば、新しいユーザにsudo権限を付与しておくと便利です。

以下の二つのコマンドのうち、どちらかを実行してください。

```bash
$ sudo usermod -aG sudo <ユーザ名>
```

```bash
$ sudo gpasswd -a <ユーザ名> sudo
```

一般的には、```gpasswd```を使うと良いとされています。```usermod```を用いると、オプションに```-G```だけを用いた場合、グループが新しいメンバーのみになってしまう危険があるらしいです。

[usermodでグループを追加するのは危険 #Linux - Qiita](https://qiita.com/tk1024/items/16e98031b84a31df469b)

追加後、以下のコマンドを用いてしっかりsudoグループに追加されているかを確認します。

```bash
$ groups <ユーザ名>
```

## 参考文献

[Ubuntuでユーザーの確認・追加・削除・sudoに追加 #Ubuntu - Qiita](https://qiita.com/RYOSKATE/items/81b564b2ab281ec7f27d)
欧州CRA解説 第1回：制定の背景と日本企業への影響

# 欧州CRA制定の背景
近年、サプライチェーンを狙ったサイバー攻撃が急増しており、独立行政法人情報処理推進機構（IPA）が毎年発表している「情報セキュリティ10大脅威」でも第2位にランクインするほど、その脅威は深刻です。これらの攻撃は、セキュリティ対策が不十分な関連企業や取引先を足がかりにして、ターゲット企業へ不正侵入を図るという厄介な手法を取ります。

このようなサプライチェーン攻撃に対応するためには、サプライチェーン全体のセキュリティ対策を強化することが不可欠です。EUにおいては、国境を越えたサプライチェーンを構築している企業が多数存在するため、欧州ネットワーク・情報セキュリティ機関（ENISA）が中心となり、欧州サイバーレジリエンス法案（EU Cyber Resilience Act、CRA）が制定されました。

# 日本企業への影響
「欧州の法律だから日本企業には関係ない」と考えがちですが、実際にはこの法律の影響を受ける日本企業は少なくありません。対象範囲は広く、施行までの期間も限られており、罰金規定もあるため、影響を受ける企業は自社への影響を早急に調査し、対応策を検討する必要があります。
対象となるのは、自動車、航空、医療分野などの明確にCRAの対象外と定義されたデジタル製品以外の「EU圏内で販売されるデジタル要素を持つ製品」です。これに該当するEU向け製品を製造・輸出・販売している企業は、CRAの規制対象となる可能性があります。

CRAは2024年中に成立予定であり、施行後は法案で要求される各種要件の履行が義務付けられます。違反した場合、罰金が課される可能性があり、その規制は非常に厳しいものとなるでしょう。

# 欧州CRAで義務化される主要ポイント
欧州CRAは、主に製造業者に対して以下の要件を義務付ける予定です。
1.	**適合性評価の実施**
デジタル要素を含む製品を市場に投入する際、必須要件に従って設計・開発・製造されていることを保証する。
2.	**セキュリティ特性要件への適合義務**
サイバーセキュリティリスクのアセスメントを実施し、技術文書を作成、適合性評価手続きを実施する。
3.	**当局への報告義務**
脆弱性が発見された場合やインシデントが発生した場合には、定められた期間内に報告することが義務付けられる。
___

今回の投稿では、欧州CRAの概要とその制定背景について簡潔に解説いたしました。Regrit Partnersのサイバーセキュリティサービスチームは、今後、欧州CRAが日本企業に与える影響や、対応すべき事項について解説をシリーズ化して解説してまいります。

:::note warn
※本内容は記事作成時点での最新の欧州CRA法を参照していますが、今後法案が修正され内容が変更、もしくは新たな記載が追加される可能性があります。また、法律の専門家ではないため、法の解釈が誤っている可能性もあります。本法の内容について参照する際は必ずご自身で内容をご確認ください。
:::
ページ読み込みプロセスの動画化ツールを公開

# loadshow

URLを指定すると、そのページの読み込みプロセスをこんな感じの動画にするNode.js製のCLIツール `loadshow` (ロードショー)をオープンソースとして公開しました。

![ページ読み込み動画](https://notes.ideamans.com/assets/apple.com.DwytDGWA.webp)

動画を並べて、読み込みスピードの比較もできます。

![比較動画](https://notes.ideamans.com/assets/compare.Cs2PEaUn.webp)

# 簡単な使い方

GitHubプロジェクトはこちら。Apache 2.0ライセンスです。

https://github.com/ideamans/loadshow/

Node.js(>=20)、Chrome、ffmpegがインストールされていれば、

```bash
npm i -g loadshow
loadshow record https://apple.com/ ./apple.com.mp4
```

でお試しになれます。

NPMはこちら。

https://www.npmjs.com/package/loadshow

# なぜ開発したか？

弊社では主にフロントエンドのスピード改善をお手伝いしています。

改善結果はLighthouseで計測した指標をエビデンスにしますが、専門家以外の人は数値を示されてもなかなかピンときません。

そこでこのような動画でも違いを示し、わかりやすいと好評いただいています。

社内ツールとして数年前から作り込んできたのですが、だいぶ中身がごちゃごちゃしてきたのでリメイクがてらオープンソース化しました。

動画のカスタマイズもできるようになっています。ぜひ[README](https://github.com/ideamans/loadshow/)を読んで試してみてください。

サイトスピードの改善機運に貢献できたら望外の喜びです。

# どんな作り？

Chrome DevTools Protocolにはそのものずばり画面の録画機能があります。

https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-startScreencast

1. [puppeteer](https://www.npmjs.com/package/puppeteer)に縦長のビューポートを設定し、
1. `Page.startScreencast`でページの読み込み過程を録画して、
1. [sharp](https://www.npmjs.com/package/sharp)でフレームを構成し、
1. 最後にffmpegでmp4動画に合成します

:::note warn
ウィンドウとビューポートを縦長に設定する都合で、全画面背景など画面高さに合わせたCSSがあるページは苦手です。
:::

動画上部の情報バナー(タイトルやURLなど)は、[node-html-to-image](https://www.npmjs.com/package/node-html-to-image)によって生成しています。

社内ツール時代はLinuxで動作すればよかったんですが、MacOSやWindowsなど他のプラットフォームではpuppeteerの挙動に微妙な違いがあって、対応に苦労しました。

その他いろいろ発展途上なので、ぜひ改善にご協力ください！
003 皆で使おう　専門分野特化のＬＬＭ　の公開方法！！！

皆で使おう　専門分野特化のＬＬＭ　の公開方法！！！

追加学習済みのＬＬＭを安価に共有する方法です。

完成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/2b412d63-7ba8-46d6-4f81-83d0e04a0f13.png)


前回までの要約

https://qiita.com/bono0/items/bd0a01e50d5804bdacf3

https://qiita.com/bono0/items/4a992dc388527d3b99f4


ＬＬＭは、ほぼ出てきません。
事前に、仕様を定義すると

　１，自分専用
　２，皆≒小、特定少数、１日１００人　目安
　３，皆≒大、不特定多数、同時接続１００億人　目安

とした場合、今回は　２、特定少数　とします。
それぞれ、最適解や予算や期間や技術はご意見がおありだと思います。
が、生暖かい目で見てやってください。

ＬＬＭを公開する方法は、webapi、webアプリ等あります。
Python界隈なら
　flask、
　fastapi、
　Django、
　streimlit、
　他多数
あります。お好みで選んでください。
今回は、flaskでwebapiとします。


まずは、ローカルで動かしてみましょう。
作った特定分野特化のＬＬＭに質問したり
ググるといっぱい出てきます。
ミニマム構成で動いたら、引数と戻り値に前回のＬＬＭを繋ぎます。


https://flask.palletsprojects.com/en/3.0.x/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/d837f168-1bf4-cd7c-70cf-ebb636e8517d.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/eb32d5af-84f2-d26f-e32c-c61c5eb72d73.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/da1deefb-0fdf-6a8a-fdf1-635fe9f7e420.png)


無事にローカルでの動作確認ができました。
ここまで出来たら、
　同一ネットワーク内、
　社内、
　部内、
　学内、
　他などで
特定少数向けの　閉じた環境での運用は動きます。（LANの設定等要確認）

無事に
　皆で使おう　専門分野特化のＬＬＭ　の公開方法！！！
完成です。おめでとうございます。


しかし、まだ道半ばです。特定少数とは言え、世界に向けてインターネットへ公開するには少し注意が必要です。
念能力なしで天空闘技場へ行くようなものです。
心得のある方は、適宜お進みください。

最善手は所説あろうかと思いますが、ここはクラウドさんのサーバーレス一択です。
次回は
　皆で使おう　専門分野特化のＬＬＭ　インターネットで公開！！！
です。



次回予告

https://bono0-8o1lf4ep.an.gateway.dev/cat_llm002?name=hello

https://
bono0-8o1lf4ep.an.gateway.dev/cat_llm002?name=hello


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/5b99a637-8f06-bf32-5f62-b6686e672b53.png)



ー続くー
TextFieldに複数改行を入力させない

# はじめに

以前[こちら](https://qiita.com/zensehakittoneko/items/6af329855896240179b1)の記事を公開しました。
今回も「TENBIN」で実装した機能についての記事を書こうと思います。

もっとこうした方がいいとかあれば是非コメントをお願いします！
また、是非「TENBIN」で遊んでみてください！

https://apps.apple.com/jp/app/tenbin/id6670417709

# 本文
「TENBIN」では投稿内容の入力画面でTextFieldを使用しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3808248/2b7b6a4d-b609-6698-a6c7-ec56b2c026eb.png)

ここの実装をしていた時に「これ、140文字分の改行を入力されたらどうすればいいんだろう？」と思いました。
パッと思いついたのは3パターン
①： DBから取得した表示内容に複数改行がある場合、単一改行に変換してから表示する
②： 入力された投稿内容に複数改行がある場合、単一改行に変換してからデータ格納する
③： そもそも複数改行させない

①はFirestoreからデータを確認する時に見辛くなったりするのかな？あと、きっと無駄な容量を使うだろうなぁ〜

②はユーザーが折角改行したのに表示結果が単一改行だと無駄な時間と労力を掛けさせてしまうなぁ

あと、①と②の両方で言えるけど、意図して複数改行を入力したとしたら、開発者側がそれを操作すべきではないなぁ

という理由から、そもそも複数改行を許容しなければいいという③の選択肢を取りました。

そしてこちらがそのコード
``` Swift
struct CostomTextField: View {
    @State private var contents: String = ""

    var body: some View {
        VStack {
            HStack(alignment: .center) {
                Text("投稿内容")
                Text("任意")
                    .font(.caption)
                    .padding(.horizontal, 7)
                    .padding(.vertical, 2)
                    .background(.gray)
                    .foregroundColor(.white)
                    .cornerRadius(12)
            }
            .frame(maxWidth: .infinity, alignment: .leading)

            TextField("", text: $contents, axis: .vertical)
                .onChange(of: self.contents) { oldValue, newValue in
                    // ここで連続する改行を削除しています。
                    let sanitizedString = newValue.replacingOccurrences(of: "\n\n+", with: "\n", options: .regularExpression)
                    if sanitizedString != newValue {
                        self.contents = sanitizedString
                    }
                }
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding(.horizontal)
        }
    }
}
```

ポイントは、
``` Swift
let sanitizedString = newValue.replacingOccurrences(of: "\n\n+", with: "\n", options: .regularExpression)
```
の部分です。
```"\n\n+"``` は複数改行のことを表現しています。
```"\n"``` は単一改行のことを表現しています。
正規表現です。

```.onChange```はTextFieldに値が入力されたことを検知して実行されます。
なので、TextFieldに文字が入力された時に入力内容をチェックして、複数改行が入力されたら、単一改行に変換されるようになります！


# さいごに
今回はSwiftuiのTextFieldについてのコードを書きましたが、これはモバイルとwebで活用できる考え方だと思いますので、適宜複数改行非許容ロジックを実装してみてはいかがでしょうか！

あと、ここまで書いておいて何ですが、
``` Swift
TextEditor(text: $text)
    .frame(width: 250, height: 250)
```
を使えば表示サイズは固定で複数改行を入力・表示できることを記事作成中に知りました。
もっと早く知りたかった。。。
（参考：https://tokizuoh.hatenablog.com/entry/2022/02/26/140406）


おわり
004 皆で使おう　専門分野特化のＬＬＭ　インターネットで公開！！！


皆で使おう　専門分野特化のＬＬＭ　インターネットで公開！！！

追加学習済みのＬＬＭを安価に共有する方法です。



完成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/64cb13e8-fbb9-8538-d0b4-e059a7835d30.png)


前回までの要約

https://qiita.com/bono0/items/bd0a01e50d5804bdacf3

https://qiita.com/bono0/items/4a992dc388527d3b99f4

既に動作確認済みのflaskを　クラウドのサーバーレスに移植します。

　各種クラウド、
　各種サービス、
　各種操作方法、

色々あります。ご都合の良い方法でお試しください。
今回は、

　グーグルさんの
　クラウドラン関数の
　WebUI

旧姓　グーグル　クラウド　プラットフォームの　クラウド　ファンクションズ　です。
コーディングもデプロイもブラウザ上の
サンプルコードからベタ打ちで全部出来ます。
ローカルの真っ黒なターミナルに専用アプリを入れなくても
ブラウザのみで即使えて、コマンドと引数を覚えなくても、
ボタンポチポチで使えます。


まず初めに何もしないでデプロイです。

無事に動きましたか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/45b846cd-e505-92a5-783d-806e20b0abd3.png)



ここから、移植作業です。万が一動かない時には追加部分の問題の可能性が高いです。
頑張ってコピペでしのいでください、後「ライブラリの追加」と「未承認の呼出しを許可」も忘れずに。
そしてデプロイすれば　完成です。

クラウドのサーバーレスなので、遍く脅威から自動で守ってくれていますし、お値段も自分でマシンを買うよりよっぽど安いです。


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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/e710e117-6627-cbf7-1171-808fd32ff0da.png)



今回も無事に
　皆で使おう　専門分野特化のＬＬＭ　インターネットで公開！！！
完成です。おめでとうございます。


なぜか当初の意図からズレたお話が続きましたが、無事に読書感想文を作成してくれる専門分野特化のＬＬＭを開発できました。

が、インターネト公開のお作法は、多々あります。
予算があれば、プロに頼むのが吉です。

気軽に安価にあっという間に、
皆さんのお手元にも　専門分野特化のＬＬＭ　が届くことを祈念します。
ありがとうございました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/002dcd53-0fad-038b-ad65-3f9b87d89cc1.png)



完成イメージ　例：gateway化


https://bono0-8o1lf4ep.an.gateway.dev/cat_llm002?name=hello


https://
bono0-8o1lf4ep.an.gateway.dev/cat_llm002?name=hello






P.S.
なんとか、現時点のミニマム構成

　特定少数
　身内向けの
　データーサイエンティストさん御用達の

大規模言語モデル＋インターネット公開でしたが、
web屋さん目線とAI屋さん目線で　webアプリ　への前提が根本的にずれていると思われます。「全てが完璧に整うまで何もしない」よりは、「今すぐ出来る範囲で手を動かして」いじり倒しています。

専門分野特化のＬＬＭ自体、昨今出来る様になったばかりの最新技術です。
まだまだ混沌の只中ですが、最終的には大手の便利なSaaSが完成して大衆向けには終わりでしょうか。ならば、今のうちに先行者利益の確保ですね。

しかし、名前が変わるとか気を遣うわ。「ご結婚おめでてとう」と思ったら逆パターンもあるからね。怖いわ、地雷踏みそうで。

ー完ー
paizaラーニング問題集「点の幅」を解いてみた

▼感想：

クエリメニューの問題を最初から解いていたので、
その知識を踏まえて、本問を解くことができました。

▼コード：
   
    ########## 処理0(準備) インプット,リスト定義など ###########
    
    N,K = map(int,input().split())

    import math
    N_s = int(math.sqrt(N))

    # tmp,minmaxdata: 区間ごとの最低点および最高点格納用リスト,辞書
    S = []
    tmp = []
    minmaxdata = {}

    ########## 処理1 区間ごとの最低点および最高点格納 ##########
    
    for i in range(N):
    
        num = int(input())

        S.append(num)
        tmp.append(num)
    
        if len(tmp) == N_s:
            minmaxdata[i-len(tmp)+1] = (min(tmp),max(tmp))
            tmp.clear()

    ########## 処理2 最高点 - 最低点算出 ##########

    # mins,maxs: 最低点と最高点格納用リスト
    mins = []
    maxs = []

    for i in range(K):
    
        Al,Ar,Bl,Br = map(int,input().split())
    
        Al -= 1
        Ar -= 1
        Bl -= 1
        Br -= 1
    
    for i in range(2):
        
        if i == 0:
            l = Al
            r = Ar
        else:
            l = Bl
            r = Br

        # AlとAr(BlとBr)が同じまたは隣の区間に存在するならば
        if l//N_s*N_s == r//N_s*N_s or l//N_s*N_s+N_s == r//N_s*N_s:

            for j in range(l,r+1):
                mins.append(S[j])
                maxs.append(S[j])
            
            score = max(maxs) - min(mins)
        
        # AlとAr(BlとBr)が離れた区間に存在するならば
        else:

            # Al(Bl)が存在する区間の最低点と最高点格納
            for j in range(l,(l//N_s)*N_s+N_s):
                mins.append(S[j])
                maxs.append(S[j])

            # Al(Bl)左隣～Ar(Br)右隣の区間の最低点と最高点格納
            for j in range((l//N_s)*N_s+N_s,(r//N_s)*N_s,N_s):
                mins.append(minmaxdata[j][0])
                maxs.append(minmaxdata[j][1])

            # Ar(Br)が存在する区間の最低点と最高点格納
            for j in range((r//N_s)*N_s,r+1):
                mins.append(S[j])
                maxs.append(S[j])
            
            score = max(maxs) - min(mins)

        if i == 0:
            a = score
        
        else:
            b = score

            if a > b:
                print("A")
            elif a < b:
                print("B")
            else:
                print("DRAW")
            
        maxs.clear()
        mins.clear()
GA4のBigQueryエクスポート時間を比較


## 概要
GA4ではBigQueryへのエクスポート時間が一定ではなく、最近ではエクスポート先のテーブルを参照するスケジュールクエリが失敗するケースも増えてきています。

そこでこの記事では複数プロパティでエクスポートの時間を比較し、挙動の違いを考察してみます。

## 今回利用するSQL
以下のSQLを使用してデータを抽出しました：

```sql
WITH
  raw_data AS (
  SELECT
    PARSE_DATE("%Y%m%d", REGEXP_EXTRACT(table_id, r"events_([0-9]+)")) AS date,
    DATETIME(TIMESTAMP_MILLIS(creation_time), 'Asia/Tokyo') AS creation_time,
  FROM
    `projectName.analytics_xxxxx.__TABLES__`
  WHERE
    table_id LIKE 'events_%'
    AND table_id NOT LIKE 'events_intraday_%' )
SELECT
  *,
  DATETIME_DIFF(creation_time, date, HOUR) - 24 AS hour
FROM
  raw_data
WHERE
  date >= "2024-01-01"
```

このクエリ結果を用いて、日付ごとの「エクスポート時間の推移」を確認します。

## GA4プロパティA（無償版）

- 2024年5月21日以降
    - 数値が3時間後ろ倒し
    - 最小は8時台、最大は20時台


![スクリーンショット 2024-09-07 19.25.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147689/bd765f25-2f3a-d852-bd3c-3fb4f083fb50.png)
※エクスポート開始は2024年4月。

## GA4プロパティB（無償版）

- 最大で43時台
- 2024年5月21日以降
    - 数値が3時間後ろ倒し
    - 最小は24時台、最大は33時台


![スクリーンショット 2024-09-07 19.42.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147689/fdc9a660-f451-cb89-ee1c-c4b5891428ae.png)


## GA4プロパティC（無償版）

- 最大で42時台
- 2024年5月21日以降
    - 数値が3時間後ろ倒し
    - 最小は24時台、最大は33時台

![スクリーンショット 2024-09-07 19.40.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147689/b0651141-4324-ae2e-d282-39d3cf3769b7.png)


## GA4プロパティD（360）

- 2024年5月21日以降
    - 数値が3時間後ろ倒し
    - 最小は8時台、最大は15時台

![スクリーンショット 2024-09-07 19.24.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147689/86e267f9-6720-7fb9-0f0f-2e029f029c2b.png)

## GA4プロパティE（360）

- 2024年5月21日以降
    - 数値が3時間後ろ倒し
    - 最小は8時台、最大は15時台

![スクリーンショット 2024-09-07 19.28.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147689/8e4c01bc-fa14-e1e3-bf07-97ffa2100deb.png)


## GA4プロパティF（360）

- 2024年5月21日以降
    - 数値が3時間後ろ倒し
    - 最小は8時台、最大は16時台

![スクリーンショット 2024-09-07 19.30.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147689/4cc75014-7bd9-094d-29a6-c62af4f8da96.png)

## 考察

エクスポート時間を整理すると以下のようになります。（2024年5月21日以降）

| プロパティ | 種別 | 最小 | 最大 | 備考 |
|:-|:-|:-|:-|:-|
| A  | 無償  | 8時台  | 20時台|  |
| B  |  無償 | 24時台   | 34時台 | ほぼ利用していないデータセット |
| C  | 無償  | 24時台  | 33時台| ほぼ利用していないデータセット  |
|  D | 360  |  8時台 | 15時台|  |
| E  |  360 |   8時台  |15時台 |  |
|  F |  360 | 8時台 | 16時台|  |

### 2024年5月21日以降、遅延幅が増加

この日以降、エクスポート時間が3時間遅くなっており、午前中のデータを期待してスケジュールクエリを組む場合、処理の失敗が増加する可能性があります。

### 無償版では最大34時間かかることがある
無償版ではデータセットの利用頻度やエクスポート量によって、処理の優先度が下がり、遅延が大きくなるのかもしれません。

### 何時台を想定すべきか
360プロパティの場合、16時台までにエクスポートされる可能性が高いですが、無償版ではエクスポートが1日以上かかる場合もあるため、BQテーブルの利用は難しいかもしれません。

### 前日分の速報値が必要な場合
360プロパティでも最大で16時間近くかかるため、前日のデータを速報値として利用するにはストリーミングテーブルの使用が推奨されます。


## まとめ


2024年5月21日以降、すべてのプロパティでエクスポート時間が3時間遅れることが確認され、特に無償版では最大で34時間の遅延が発生することがありました。


リアルタイムや前日分のデータを迅速に活用するには、ストリーミングテーブルの利用が必要となりそうです。

### 追記

GA4の「データの更新頻度」のヘルプに「前日のデータ処理のタイムライン」の項目が追加されているようです。

https://support.google.com/analytics/answer/11198161?hl=ja
電話の音声データをOpenAIのTTS (text-to-speech) modelで作成する

# 背景
Whisperによる電話の音声データの文字起こしを試してみたかったのですが、自由に使えそうな電話のデータは見つかりませんでした。
そこで[OpenAIのTTS (text-to-speech) model](https://platform.openai.com/docs/guides/text-to-speech/overview)を活用して、電話の音声データを自分で作成することにしました。

# 手順
下記手順で音声データを作成しました。
1. ChatGPTで電話の応対のやりとりを生成
2. 生成したやりとりをOpenAIのTTS (text-to-speech) modelで音声化

# ChatGPTで電話の応対のやりとりを生成
下記プロンプトで会話の履歴を生成してもらいました
```
あなたは、Tokoroteenという文房具を販売しているECサイトのヘルプデスクで働いているオペレーターの佐藤さんです。
ヘルプデスクに着信する問い合わせの中で、「返品・交換」カテゴリに属する問い合わせの、電話の書き起こしスクリプトを[# 出力]に沿って教えて

# 出力
|role|script|
|--|--|
|operator|（コミュニケータの発話内容）|
|customer|（コミュニケータの発話内容）|
```
生成結果は下記のとおりです。これを`conversation.csv`として保存しました。
|role|script|
|--|--|
|operator|佐藤でございます。Tokoroteenカスタマーサポートにお電話いただき、ありがとうございます。本日はどのようなご用件でしょうか？|
|customer|こんにちは、先日購入した万年筆が壊れていたので、返品か交換をお願いしたいです。|
|operator|大変申し訳ございません。商品が壊れていたということで、ご不便をおかけしました。まずはご注文内容を確認させていただきますので、お名前とご注文時の生年月日をお伺いできますでしょうか？|
|customer|名前は山田太郎、1990年5月1日です。|
|operator|ありがとうございます。少々お待ちください…ご注文の確認が取れました。壊れていたとのことですが、具体的にどのような状態でしたでしょうか？|
|customer|到着したときにペン先が折れていて、インクも漏れていました。|
|operator|それは大変申し訳ございません。新品交換か、返品対応のどちらかをお選びいただけますが、どちらをご希望されますか？|
|customer|交換をお願いしたいです。|
|operator|承知いたしました。それでは、新品の万年筆と交換させていただきます。まず、壊れた商品をご返送いただき、その後交換品を発送いたします。返品用のラベルをメールでお送りいたしますので、商品を元の箱に戻し、ラベルを貼っていただき、最寄りの配送業者にお渡しください。|
|customer|わかりました。|
|operator|交換品は返品商品を確認後、3～5営業日以内に発送いたします。返品が確認され次第、追ってメールでご連絡いたしますのでご安心ください。その他ご不明な点はございますでしょうか？|
|customer|特にありません。ありがとうございました。|
|operator|こちらこそ、迅速に対応させていただきますので、ご迷惑をおかけして申し訳ございませんでした。何かございましたらいつでもご連絡くださいませ。失礼いたします。|

# 生成したやりとりをOpenAIのTTSで音声化
`conversation.csv`を読み込み、音声化します。声のオプションとして、`alloy, echo, fable, onyx, nova, shimmer`の6名を選ぶことができ、今回はオペレーターを`alloy`、顧客を`onyx`とすることにしました。
一行ずつ音源を生成し、最後にそれらを結合することで一つの音声ファイルとしました。

```python
import pandas as pd
from openai import OpenAI
from pydub import AudioSegment
from pathlib import Path

# OpenAIクライアントの初期化
client = OpenAI()

# CSVファイルを読み込む
csv_file_path = "conversation.csv"
df = pd.read_csv(csv_file_path)

# 音声ファイルの保存先
output_dir = Path("audio_files")
output_dir.mkdir(exist_ok=True)

# 各行ごとに音声を生成
audio_files = []
for index, row in df.iterrows():
    role = row["role"]
    text = row["text"]

    # 音声を選択
    if role == "operator":
        voice = "alloy"
    elif role == "customer":
        voice = "onyx"
    else:
        continue

    # 音声を生成
    response = client.audio.speech.create(
        model="tts-1",
        voice=voice,
        input=text,
    )

    # 音声ファイルを保存
    speech_file_path = output_dir / f"speech_{index}.mp3"
    response.stream_to_file(speech_file_path)
    audio_files.append(speech_file_path)

# 音声ファイルを結合
combined = AudioSegment.empty()
for audio_file in audio_files:
    segment = AudioSegment.from_mp3(audio_file)
    combined += segment

# 最終的なMP3ファイルとして保存
final_output_path = "conversation.mp3"
combined.export(final_output_path, format="mp3")
```

# 結果
想像以上に自然な会話を生成することができて大満足です。
適切な実データがなくとも、生成されたデータで問題なく検証できそうだと感じました。

# 参考資料
https://platform.openai.com/docs/guides/text-to-speech/quickstart
intersectionObserverについて調べていますー終

お疲れ様です。

昨晩投稿した内容の続きですが、今朝起きて現在のコードをちょっと書き換えてみたところ動きました:relaxed:
何が違ったのかについては以下の通りです。

昨日投稿したもの↓
```diff_javascript

// 監視設定
const history = new IntersectionObserver(History);

history.observe(document.querySelector('#history'));
```
<br>
改善したもの↓

```diff_javascript

// 監視設定
const history = new IntersectionObserver(History);

history.observe(document.querySelector('.work-main'));
```

ということで、単純に「どこを監視するのか」の範囲指定が間違っていました…笑

訂正前は、アニメーションさせたいタグを含む、親要素のIDを指定していましたが、それだと、アニメーションだけでなくその下に続いている文章も指定した秒数後に、パッと現れる動作になっていて、おかしーなー:thinking:と思っていたところでした。

そこで、IDじゃなくてクラスなのでは…と思い、試しに書き換えたところ動作しました！
親要素ではなく、アニメをつけたいh2タグのクラスでよかったようです。
また勉強になりました。

試しに、昨日の投稿で出てきた、**root** や **rootMargin** を使ってのアニメーションもやってみようと思います！
UUIDとは？GoでUUIDを生成する

## UUIDとは？
UUIDとはUniversally Unique Identifierの略で、**一意に情報を識別するための識別子**です。

フォーマットも定められています。
- 16進数形式: 32桁の16進数（数字とアルファベット）
- ハイフンで区切られた形式: 8桁-4桁-4桁-4桁-12桁、合計で36文字（32桁の16進数と4つのハイフン）

例）123e4567-e89b-12d3-a456-426614174000

以上を満たすような文字列をUUIDとし、**事実上世界中で重複しない**ためユニークなIDとして扱うことができます。

UUIDとUIDの違いは、**グローバルで一意であるのがUUID、特定のシステムで一意であるのがUID**です。

## バージョンとは？
UUIDには、**生成方法が異なる複数のバージョン**があり、**v1からv8**まで存在します。その中でも、おそらく一番多く使われているのはv4です。v4はランダムなUUIDを生成したい場合に一般的に利用されます。**用途に応じて適切なバージョンを選定することが望ましい**ですが、本記事では各バージョンの詳細には触れません。詳しく知りたい方はドキュメントなどを読んでいただきたいです。[参考](https://www.rfc-editor.org/rfc/rfc9562#name-introductio)



## golangでUUIDを生成する
goのuuidパッケージを使ってUUIDを生成する方法を紹介します。

```
func New() UUID
```
この関数は、ランダムなUUIDかパニックを返します。通常、v4のUUIDになります。

```
func NewRandom() (UUID, error)
```
この関数は、ランダムなv4のUUIDかエラーを返します。

```
uuid.Must(uuid.NewRandom())
```
という書き方で、uuid.New()と同義になります。
その他のバージョンの生成方法については以下のドキュメントを参考にしてください。

参考ドキュメント：
https://pkg.go.dev/github.com/google/uuid#section-readme

## UUID↔stringの変換
UUIDを文字列に変換したり、逆に文字列をUUIDに変換することができます。

### UUID→string
```
func (uuid UUID) String() string
```
StringはUUIDを文字列に変換できます。UUIDが無効の場合は空文字になります。

```
func NewString() string
```
ちなみにNewStringはランダムなUUIDを生成+文字列で受け取ることができます。

### string→UUID
```
func Parse(s string) (UUID, error)
```
Parseは文字列からUUIDに変換し、形式が適切でなかった場合はエラーを返します。
```
func MustParse(s string) UUID
```
MustParse は Parse に似ていますが、文字列を解析できない場合はパニックになります。

## 参考
https://www.rfc-editor.org/rfc/rfc9562#name-introductio
https://pkg.go.dev/github.com/google/uuid#section-readme
令和６年度　静岡中央高校　アプリ制作（オープンデータ）

目次
[１．はじめに](#１はじめに)
[２．環境について](#２環境について)
[３．オープンデータ](#３オープンデータ)
[４．AI活用について](#４ai活用について)
[５．令和６年度　ゼミでの作品](#５令和６年度　ゼミでの作品)
[６．その他](#６その他)

# １．はじめに

　静岡県立静岡中央高校では、アプリの考案から製作までの活動をAIの技術を活用しながらゼミの授業の中で実施をしています。また、そのアプリ製作の内容はオープンデータの活用について実施しており令和６年度より実施していきます。


# ２．環境について
<h3>Monaca - HTML5ハイブリッドアプリ開発プラットフォーム</h3>
令和6年度から静岡中央高校のアプリは Monaca Educationで作成しています。

<h3>Monaca とは？</h3>
Monaca Educationは、教育機関における情報教育を通じて中高生の未来を拓くプログラミング教育サービスです。 生徒たちはスマホアプリを作りながらプログラミングの基礎学習から作品作りまで取り組めます。

[Monaca Education公式サイト][link-2]

[link-2]:https://edu.monaca.io/


# ３．オープンデータ
　オープンデータとは、行政機関を中心に取り組んでいる、情報を誰でも自由に使えて再利用もでき、かつ誰でも再配布できるようにしたデータです。保有する情報を、第三者が従来にはなかった視点で活用することで、新たな価値が生まれ、市民生活をより豊かにするという考えのもと運営されています。
　静岡中央高校では、ゼミ授業の一環としてアプリケーションの作成をする中でオープンデータについて学習していますが、今回、地域に根ざした学校の取り組みのひとつとして実施をしています。　
皆さまが地域のお店のデータを有効に利用していただくことで地域貢献につなげることができればと思います。
　学校*1の取り組み（ゼミ授業の中での実施）としても全国初の試みであり、手探りの部分も多々ありますのでデータに関する改善意見や質問などをいただければありがたいと思います。この試みが地域の課題改善や地域活性化に向けた一助となるようオープンデータの学習・アプリケーションの開発に取り組んでいきます。

参考：[総務省HP][link-18]

[link-18]:http://www.soumu.go.jp/menu_seisaku/ictseisaku/ictriyou/opendata/index.html

# ４．AI活用について
・対話型AI ([chatgpt][link-40] / [Bard][link-41]) 対話型については生徒が自分でGoogleアプリを掲載するときに校正的な部分での活用。プログラミングを実施するときの補助的なものとして活用する。
（意外とコードが違っているので最初の部分などに活用しています）
・画像作成AI([BlueWillow][link-42] / [canva][link-43])画像生成などでアイコンやプレゼンの挿絵などの活用をしています。
・カラー配色AI([ColorMagic][link-44]) HP / アプリ / プレゼン資料などの配色展開を教えてくれるので参考程度に使っています。

<font color="red">授業での注意事項として（ねらい）</font>
・授業の中で活用した場合はこのAIで作成したというものをプレゼン資料などに記載させる。
・Webデザイナー、システムエンジニアなどだけではなく様々なAIを活用することで自分が将来就職してからAIではできないことのようなものを考えさせる。


[link-19]:https://www.mofa.go.jp/mofaj/gaiko/oda/sdgs/about/index.html
[link-40]:https://openai.com/blog/chatgpt
[link-41]:https://bard.google.com/
[link-42]:https://www.bluewillow.ai/
[link-43]:https://www.canva.com/ja_jp/
[link-44]:https://colormagic.app/

# ５．令和６年度　ゼミでの作品

　　<font color="red">地域からQiita・内容からgoogle sitesにリンクがあります。


| NO | 地域 | 内容 |
| :---: | :--- | :--- |
| 1 | [静岡市][link-4]|[いつでもどこでも美味しいパン！][link-5]|


[link-4]:https://qiita.com/shigeru-suzuki/private/56c918894c222fa06f4e
[link-5]:https://sites.google.com/view/shizuoka-cyuou/%E6%A6%82%E8%A6%81



# ６．その他

静岡県立静岡中央高校　こちら[クリック][link-33]

[link-33]:https://www.edu.pref.shizuoka.jp/shizuokachuo-h2/home.nsf/IndexFormView?OpenView
Call Summaries Powered by Einstein Generative AI



+ [Einstein Generative AI による通話要約機能を有効にするためには何が必要ですか](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007iflP5)

私はこのページを読んでいます:

Einstein Generative AI を活用した通話要約

https://help.salesforce.com/s/articleView?id=sf.eci_call_summaries.htm&type=5

「Einstein for Sales アドオンと Einstein Conversation Insights を備えたEnterprise Edition、Performance Edition、Unlimited Edition で利用できます。」

:::note
ECI はすでに UE に存在するため、販売には eisntien のみが必要になります。

EE をお持ちの場合は、Sales Cloud に ECI と Ensiten の両方が必要になると思います (ただし、EE には ECI に関するフリーミアムのものもあるため、それを調べる必要があります)
:::
AWS CloudFormation で環境構築を自動化しよう！～Part2～


### クロススタック参照クラウドフォーメーションのリソース依存関係と参照方法

AWS CloudFormation（クラウドフォーメーション）は、AWSのリソースを簡単に管理・デプロイできる強力なツールです。特に、リソース同士の依存関係や参照方法を理解することで、より効果的にテンプレートを構築できます。今回は、リソースの依存関係、組み込み関数、ネストされたスタック、クロススタック参照、そしてスタックセットについてわかりやすく解説します。

### クロススタック参照リソースの依存関係

CloudFormationを使用してリソースを作成する際、あるリソースが他のリソースに依存することがあります。たとえば、EC2インスタンスを作成する前に、セキュリティグループを先に作成しなければならない場合です。このような依存関係は、CloudFormationが自動的に処理します。

また、依存関係を明示的に定義するために `DependsOn` 属性を使用できます。例えば、S3バケットとSNSトピックを作成する場合、SNSトピックの作成がS3バケットに依存していると指定することで、S3バケットが先に作成されるようにします。

### クロススタック参照組み込み関数による依存関係

CloudFormationでは、組み込み関数を使ってリソース同士を参照することができます。例えば、`Ref` 関数を使用することで、リソースのIDやARNなどを取得できます。この仕組みを利用すると、SNSトピックが作成された後にSNSサブスクリプションを設定するなど、リソースの順序を自動的に調整できます。

`GetAtt` 関数も同様に、別のリソースの属性を取得できます。たとえば、EC2セキュリティグループのIDを取得し、それを他のリソースに利用することが可能です。

### クロススタック参照動的参照

動的参照を利用すると、AWS Systems ManagerやAWS Secrets Managerに保存されているデータをテンプレートで参照できます。たとえば、S3バケットのアクセス制御にSystems Managerに保存されたパラメーターを使用することができます。

### クロススタック参照ネストされたスタック

ネストされたスタックを使うと、大規模なテンプレートを再利用可能な小さなテンプレートに分割できます。これにより、テンプレートの複雑さを減らし、管理を容易にします。たとえば、VPC、IAM、EC2といったリソースを個別のテンプレートに分けて保存し、メインのテンプレートからそれらを参照することで、リソース数の制限を回避できます。

### クロススタック参照

クロススタック参照を使うと、あるスタックで作成したリソースを別のスタックから参照できます。例えば、セキュリティチームが管理するIAMスタックや、ネットワークチームが管理するVPCスタックを参照することで、スタック間の依存関係を適切に設定できます。

注意点として、参照された出力値は変更や削除ができないため、慎重に管理する必要があります。

### スタックセット

スタックセットを使用すると、1つのテンプレートで複数のAWSアカウントやリージョンにわたって同じスタックを作成、更新、削除できます。これにより、複数の環境に対して効率的に一貫したインフラストラクチャをデプロイすることが可能です。

---
CloudFormationの依存関係や参照方法、そしてスタックの管理方法について解説しました。これらの機能を理解し、うまく活用することで、AWS環境をより効率的に管理できるようになります。

### 参考資料
[AWS CloudFormation#2 基礎編【AWS Black Belt】](https://www.youtube.com/watch?v=RN9D09OVxVk)
[AWS CloudFormation#2 基礎編【AWS Black Belt】/PDF](https://www.youtube.com/redirect?event=video_description&redir_token=QUFFLUhqbVZTdUR0YWNjUXd5N1VuMjFaUDVMaUVBeWItd3xBQ3Jtc0ttQkd2UzdSUHhjQ3hBQThZRjVHTXc5OEtta2dUSnJRSFFqdWpFclFUYXBTRGlTVFYwMWVDd1o2RHRwQW9ZdXJSZnNUa2pvYnFzeVRJNVJHcndwdms2THZYQlU2dGhIdlQ5WHNmMEVkMG1VdzlOSXdnaw&q=https%3A%2F%2Fpages.awscloud.com%2Frs%2F112-TZM-766%2Fimages%2FAWS-Black-Belt_2023_CloudFormation-2_1231_v1.pdf&v=RN9D09OVxVk)
Doma1からDoma2への移行: IterationCallbackの書き換え

# 概要

本記事は、Doma1 から Doma2 へ移行した際の調査メモである。

Doma2 で IterationCallback を用いた検索が禁止された。`java.util.stream.Stream` を用いた検索に書き換えるよう公式ドキュメントで指示があり、最低限の変更で対応する方法を調査したので、具体例を示す。

本記事が対象とするのは、検索結果に対して単純なループ処理を行うものである。IterationContext に対して何か操作をしているようなコードではない。

# 書き換え前: Doma1 でのコード

Doma1 でのコードは https://doma.seasar.org/reference/query/select.html より引用。

## DAO インターフェース

```java
@Select(iterate = true)
Void selectByNameAndSalary(String name, BigDecimal salary, IterationCallback<Void, Employee> callback);
```

## 検索実行部分

```java
EmployeeDao dao = new EmployeeDao();
dao.selectByNameAndSalary(name, salary, new IterationCallback<Void, Employee>() {
  @Override
  public Void iterate(Employee target, IterationContext context) {
    ...
    return null;
  }
});
```

# 書き換え後: Doma2 でのコード

`java.util.stream.Stream` を用いた検索に書き換える。

## DAO インターフェース

* `@Select` アノテーションの引数に `strategy = SelectType.STREAM` を指定
* `IterationCallback<R, T>` 型の引数を `Function<T, R>` 型に変更
  * 型引数の順番が逆になるので注意 

```java
@Select(strategy = SelectType.STREAM)
Void selectByNameAndSalary(String name, BigDecimal salary, Function<Stream<Employee>, Void> callback);
```

## 検索実行部分

* IterationCallback<R, T> を Function<T, R> に変更
  * 型引数の順番が逆になるので注意 
* iterate メソッドの変更
  * メソッド名を `apply` に変更
  * 引数でエンティティ型のストリームを受け取る
  * メソッドの引数にあった IterationContext を除去
* メソッド内でストリームの `forEachOrdered` メソッドを呼び出す
  * `forEachOrdered` の処理に、元のメソッドの処理を移す (`return` 文以外)

```java
EmployeeDao dao = new EmployeeDao();
dao.selectByNameAndSalary(name, salary, new Function<Stream<Employee>, Void>() {
  @Override
  public Void apply(Stream<Employee> stream) {
    stream.forEachOrdered((target) -> {
      // ここに Doma1 での iterate メソッドの中身を移す
      // ただし return 文は除去する
      ...
    });
    return null;
  }
});
```
SMSのまとめ

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


+ [リードが作成されたときにケースを作成し、アクション「会話メッセージを送信」要素を使用してリードに SMS を送信するフローを作成しました。その後、新しく作成されたケース ID を使用して作成された、新しく作成されたメッセージング セッション レコードのケース参照フィールドをどのように設定すればよいでしょうか。同じフロー内で ID を取得する方法はありますか。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ifkxaSAA)

:::note
同じフローでメッセージ送信アクションの後にメッセージング ユーザー ID に基づいてメッセージング セッションを取得してみてはいかがでしょうか。
:::
データ分析プロジェクトの大まかな流れ　その2

　下記の記事で、分析プロジェクトの大まかな流れをシステム開発におけるウォーターフォールと比較しながら、見てきたのでもう少し全体像を細かく見ていく。

https://qiita.com/Life-tech/items/8d693388559e9d19a3ab

# 1. 課題設定
データ分析プロジェクトの第一ステップは、解決したい問題や目標を明確にする「課題設定」です。このフェーズでは、プロジェクトの方向性を定めるために、課題の整理と仮説の構築が重要になってきます。

### 課題整理
解決したいビジネスの問題や目的を明確にします。これにより、分析の方向性が決まります。
### 仮説構築
ビジネスの課題を解決するために、どのような仮説を立てるかを考えます。仮説が分析の基礎となり、必要なデータや手法を決定します。

# 2. 分析計画
　次に、課題を解決するための具体的な分析の計画を立てていきます。この段階では、どのデータを使用し、どのように分析を進めるかを決定し、プロジェクトの遂行に向けた土台を整える作業になります。

### プランニング
課題解決のために必要な分析手法やツール、データソースを計画します。どのデータを収集し、どのような分析を行うかを具体化します。
### ステークホルダーへの調整
プロジェクトの進行に必要なリソースやスケジュール、期待値をステークホルダーとすり合わせます。

# 3. データ収集
　分析計画が決定したら、次は必要なデータを収集します。この段階では、データの取得から初期的な解析（EDA）を行い、データの質と傾向を把握していきます。ヒストグラムや散布図を作成して、外れ値やシステム的なデータの局在値の傾向がないなどを確認していきます。
 
### データ収集
分析に必要なデータを外部または内部のデータソースから収集します。データの取得やクレンジング、加工などを行い、分析に使用できる状態に整えます。
### EDA（探索的データ解析）
データの可視化や簡単な集計を行い、データの質や傾向を確認します。このプロセスでは、仮説に基づく初期の検証も行います。

4. データ分析
　データが準備できたら、仮説を検証するための分析作業に入ります。このステップでは、統計的手法や機械学習モデルを活用し、仮説の妥当性を確認します。

### 実装/テスト
仮説検証のための分析モデルを実装し、データを使ってテストを行います。統計的手法や機械学習モデルなどを活用して、仮説の妥当性を検証します。
機械学習におけるアルゴリズムの種類などは、下記の記事を参照ください。

https://qiita.com/Life-tech/items/fb9c0accee35c2aa9add

### 効果検証
テストデータや実データを使い、分析モデルの精度や有効性を確認します。必要に応じてモデルのチューニングや再構築を行います。


# 5. レポーティング
　分析結果が得られたら、次はそれをレポートとしてまとめ、ステークホルダーに報告します。報告後も必要に応じて調整を行い、次のステップに進めます。

### レポーティング
分析結果を整理し、ステークホルダーに理解しやすい形で報告します。結果が課題解決にどう貢献するか、ビジネスインパクトがどれほどかを明確に伝えます。
### ステークホルダーへの調整
結果に基づき、次のアクションプランや改善点をステークホルダーと共有し、フィードバックを得て今後の戦略に反映させます。
AppiumのiOS実機テストでWebDriverAgentのインストールに失敗するとき

## 背景
AppiumをPythonで動かすにあたって、iOSの実機を接続して実行すると以下のようなエラーが発生した。（Tracebackから抜粋）

```
UnknownError: An unknown server-side error occurred while processing the command. 
Original error: Unable to launch WebDriverAgent because of xcodebuild failure: 
xcodebuild failed with code 65. This usually indicates an issue with the local Xcode
setup or WebDriverAgent project configuration or the driver-to-platform version 
mismatch. Consider checking the WebDriverAgent configuration guide for real iOS devices
at https://github.com/appium/appium-xcuitest-driver/blob/master/docs/real-device-
config.md.. Make sure you follow the tutorial at https://appium.github.io/appium-
xcuitest-driver/latest/preparation/real-device-config/. Try to remove the 
WebDriverAgentRunner application from the device if it is installed and reboot the device.
```

要約するとWebDriverAgent（AppiumからiOSを操作するためのアプリ）のインストールに失敗している状態。

## 試したこと
- Appiumの再インストール → 変化なし
- Appiumのダウングレード → 変化なし
- WebDriverAgentのprofileの再認証 → 解決

## 解決策の背景
WebDriverAgentはAppiumのプラグイン「xcuitest」内にXCodeのプロジェクトとして配置されている。

プロジェクトへのパスは以下の通り。（Mac環境）
`/User/XXX/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj`

補足：Appiumへのプラグインは`$HOME/.appium`に配置される。

## 解決

このxcodeprojを開き、Project:`WebDriverAgent`のTarget:`WebDriverAgentRunner`を選択し、Signing&Capabilitiesのタブを開くとTeamが未選択の状態になっていると思われるので、ここで自身のAppleIDを設定する。
これを行うとBundle Identifierを変更するよう促されるので、適当な文字列を設定する。

そしてテストを行いたいiPhoneをビルドターゲットに設定し、▶️ボタンを押してビルドを実施しておく。

---

ここまで完了したらWebDriverAgentのインストールが成功するようになるので、Appiumテストが実行できるようになるはず。

## お気持ち
日本語で手に入るAppium関連の情報が少ないのでこれからも投稿していきたい。
Invalid project selection, please verify project *** exists and you have access.というエラーの解決法

## はじめに
GithubActionsでfirebaseプロジェクトのデプロイ時に今回のエラーが発生しました。
今回デプロイしたいプロジェクトにアクセスできていなかったので、GCPでfirebaseプロジェクトのサービスアカウントキーを発行する方法についてまとめます。

# 発生したエラーとエラー内容について
```
Invalid project selection, please verify project *** exists and you have access.
```
* プロジェクトの選択が無効
* プロジェクトにアクセス権があるか確認してください

# 問題の原因
* デプロイしたいプロジェクトとは違うプロジェクトでサービスアカウントキーを発行していた

# エラー発生時の状況
* デプロイをする際に必要な権限を持ったサービスアカウントをGCPで作っていたが、GCPで新規作成されたプロジェクトでサービスアカウントキーを発行していた。

GCPで選択されていたプロジェクト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789688/77bfa048-63c0-ebfa-fb56-a5546e886782.png)
⇒ここでサービスアカウントキーを発行してしまっていた

firebaseで作成したプロジェクト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789688/727901fb-e0b2-4f5e-9214-4d336cacb7f9.png)
⇒このプロジェクトに対してサービスアカウントキーを発行する必要があった。

GCP上でfirebaseで作成したプロジェクトを選択している必要がある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789688/072feaf3-fcb3-0f4f-550c-e6bebafeaa6e.png)

* firebaseのプロジェクトからGCPのサービスアカウントに行く方法については下記の方の記事が分かりやすかったです。
「Error: Invalid project selection, please verify project *** exists and you have access.」　　　https://qiita.com/acu8/items/85852e0b014510d63b6c

# GCPでのサービスアカウントキー発行方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789688/1f0306b8-b943-f403-d060-589d80c04c76.png)
⇒作成したサービスアカウントにチェックを入れて選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789688/d10b0282-9802-9f63-729a-770547df065d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789688/e18e3b86-893a-34b3-4fc2-83f505e7da1b.png)
⇒作成ボタンを押すとサービスアカウントキーが発行できる

# おわりに
違うプロジェクトを選択していてエラー解消に時間を要したので、同じようにデプロイ時にエラーが発生した方の参考になれば幸いです。
Salesforce 管理者の役割に就くにはどうしたらよいか



英語での回答例

+ [Can anyone suggest how I can get a job in Salesforce administrator role I have completed trailhead and associate certificate and I don't have job experience in sf admin I have 8 years of experience in customer support excellence in Fintech company.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007erQtj)

:::note
 I think the most adapted move would be to try to get the admin one (please follow these suggested materials from the [admin certification guide](https://trailhead.salesforce.com/help?article=Salesforce-Certified-Administrator-Exam-Guide))

; Trailmix: [Prepare for Your Salesforce Administrator Credential](https://trailhead.salesforce.com/en/users/strailhead/trailmixes/prepare-for-your-salesforce-administrator-credential)
+ Trail: [Study for the Administrator Certification Exam](https://trailhead.salesforce.com/content/learn/trails/administrator-certification-prep)
+ Practice Test: [Administrator Practice Test](https://developer.salesforce.com/files/ti/thi/THI-000393/administratorpracticetest.html?_ga=2.209288018.1517722473.1725828224-848654301.1725434924)
+ Superbadge: [Lightning Experience Reports & Dashboards Specialist](https://trailhead.salesforce.com/en/superbadges/superbadge-lex-rd)
+ Superbadge: [Business Administration Specialist](https://trailhead.salesforce.com/superbadges/superbadge_business_specialist)
+ Superbadge: [Security Specialist](https://trailhead.salesforce.com/content/learn/superbadges/superbadge_security_specialist)

And then after, once you have cleared the Admin prerequisite, to work on the Service Cloud certification to take advantage of your experience : https://trailhead.salesforce.com/help?article=Salesforce-Certified-Service-Cloud-Consultant-Exam-Guide

+ Trailmix: [Prepare for Your Salesforce Service Cloud Consultant Credential](https://trailhead.salesforce.com/users/strailhead/trailmixes/prepare-for-your-salesforce-service-cloud-consultant-credential)

And then, do not hesitate to contact consultancy firms based on these skills / experience/ knowledge. + @Jobs for Salesforce @Remote Jobs
:::

+ [Salesforce管理チームにおけるレビュー運用について](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000O3uU)
Censysのスキャンをブロックする方法

# はじめに
近年セキュリティで重要視されているAttack Surface Management（以下、ASM）とは、攻撃者の視点で外部から到達可能な組織の資産情報を収集及び評価するプロセスです。

日本では経済産業省によってASMに関する導入ガイダンスが公開されています。2023年に公開されたもので、詳細については以下から確認できます。

- [「ASM（Attack Surface Management）導入ガイダンス～外部から把握出来る情報を用いて自組織のIT資産を発見し管理する～」を取りまとめました](https://www.meti.go.jp/press/2023/05/20230529001/20230529001.html)

ASMは、OSINT情報を基に外部公開されているIT資産を発見するプロセスですが、ASMツールで利用される情報は攻撃者によって悪用される可能性もあります。例えば、ShondanやCensysなどは一部無料で利用可能なため、簡単に脆弱性を持つシステムを特定することができます。

本記事では、ASMツールであるCensysのスキャンをブロックする方法について記載しています。

## 攻撃対象領域
attack surfaceは、日本語では攻撃対象領域と呼ばれています。

攻撃リスクを減らすためには、**攻撃対象領域を把握し、最小限にするなど適切に管理することが重要**です。

::: note
NICTではattack surfaceの用語が定義されています。

>  The set of points on the boundary of a system, a system element, or an environment where an attacker can try to enter, cause an effect on, or extract data from, that system, system element, or environment.

出典元：[attack surface](https://csrc.nist.gov/glossary/term/attack_surface)
:::

## Censys
**Censys**は、2015年にミシガン大学のZMapの開発者によって開発された脅威ハンティングと攻撃対象領域管理を目的とした最先端のインテリジェンスプラットフォームです。

https://censys.com/

Shodanに比べると後発ですが、ASMのツールとしてShodanと比較されることが多いと思います。

どちらが良いかは一概には言えませんが、Censysが公開している以下の情報より検出スピードやガバレッジの観点でCensysの方が優れているとのことです。

- [Censys-vs.-Shodan-v2-2024.pdf](https://anchor-u.com/wp-content/uploads/Censys-vs.-Shodan-v2-2024.pdf)

## Censysのスキャンをブロックする方法
Censysのホームページから[Censys](https://about.censys.io/)のページを参照すると、以下の記述が確認できます。

>Censys scans the Internet from the subnets listed on this page, which you can allowlist or blocklist if you wish.

従って[Opt Out of Data Collection](https://support.censys.io/hc/en-us/articles/360043177092-Opt-Out-of-Data-Collection)の情報を基に運用するシステムのファイアウォールで記載のあるIPアドレスからのアクセスを拒否することにより、Censysのスキャンをブロックできます。


### ブロック前確認
以下は例として、Censysによってスキャンされた筆者が運用しているWebサーバのデータです。

![スクリーンショット 2024-08-30 16.34.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/5bd910b9-acb0-860a-a8f8-6bf8e686035a.png)

### ブロック後確認
本記事の例では、ブロックしてから2日後程度で以下の様に443番ポートのステータスが変わっていることが確認できました。また、80番ポートについてはCensys上から見えなくなっていました。

![PENDING REMOVAL.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/284a0348-85ad-f89a-93f1-3f6285858dcd.jpeg)

ブロックしてから3日後には公開されていた全てのポートに関する情報が見えなくなりました。また、`We haven't found any publicly accessible services on this host or the host is on our blocklist.`のメッセージが表示される様になりました。

![スクリーンショット 2024-09-05 20.45.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/23f2d6e8-b1e2-f443-ae7e-f459cb1e37f2.png)

ファイアウォールでブロック以降、アクセスログからもCensysからのアクセスが存在しないことを確認しました。

![スクリーンショット 2024-09-06 22.06.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221759/f90e1837-88e2-a248-bb5b-3e4713f8924e.png)

:::note
Webサーバのアクセスログから特定のユーザーエージェントからのアクセスを確認するために、lnavを使用しています。lnavについては、以前書いた[lnavで行うログファイルの分析](https://qiita.com/Brutus/items/4d459d2ac46fd8cd410e)をご参照ください。
:::

# おわりに
Shodanについては、スキャンで使用しているIPアドレスなどは公開されていませんが、IPFireの以下ブログにShodanに関する情報が記載されています。

https://www.ipfire.org/docs/configuration/firewall/blockshodan
Arduino UNO 3でmax(最大)を求めて遊ぶ


Arduino UNO 3でmax(最大)を求めて遊ぶ


目的
マクロを使い配列から最大値をサーチして求める
(正の数)(中学生以上からマイナスを習うから)(そもそも、ぱつと、見た瞬間、負のかずは、ないだろう)

いろいろ
アルゴリズムの教科書では、
ドラクエ1的に言ったらレベル99で最終章
いろいろ違うが、火山でふぅいやードラゴンが出るレベル

![o_coq379.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/c284f535-aa50-d305-c0c3-5075029bd300.jpeg)




```c++


#include <Arduino.h>

//max_wo_sagasu_UNO_1

//初期化
// the setup routine runs once when you press reset:
void setup() {

  //シリアルポートの初期化
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

}//setup


#define n 20

//メインループ
// the loop routine runs over and over again forever:
void loop() {

  int a[n] = {
    67, 36, 69, 73, 51, 55, 40, 43, 29, 35,
    70, 49, 34, 01, 41, 41, 53, 67, 34, 03
  };

  int max_a = 0;
  for (int i = 0; i < n; i++) {
    max_a = max(max_a, a[i]);
  }//for

  //結果の表示
  // print out the value you z:
  Serial.println(max_a);
  delay(1000);        // delay in between reads for stability

}//loop


```
【AWS】VPC を作成する

# はじめに
この記事では、AWS VPC を作成する手順を記載します。

https://aws.amazon.com/vpc/

:::note
以後の画面キャプチャは 2024年8月時点のものです。
:::

# VPC 作成画面へアクセスする
VPC ダッシュボードで「Create VPC」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/7fe1ab3b-9180-951e-a320-f7df137876ef.png)

# VPC を作成する
VPC settings で以下の値を設定します。

- Resources to create : VPC only
- Name tag : my-vpc
- IPv4 CIDR block : IPv4 CIDR manual input
- IPv4CIDR : 10.0.0.0/21
- IPv6 CIDR block : No IPv6 CIDR block
- Tenancy : Default

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/97d64334-74af-c5a4-2a86-ced404450d55.png)

全て入力したら「Create VPC」をクリックします。

画面上部に作成成功メッセージが表示されていれば、成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/d1774089-c2ef-e0ab-23bc-1850e0e9e085.png)


# 参考
- [Amazon Virtual Private Cloud Documentation](https://docs.aws.amazon.com/vpc/)
- [What is Amazon VPC?](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html)
- [小山雄太「WebアプリをAWSで公開しよう【AWSハンズオン虎の巻シリーズ】: 初心者も安心！手を動かしながらAWSの基本がしっかり学べる一冊！」2023](https://www.amazon.co.jp/Web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92AWS%E3%81%A7%E5%85%AC%E9%96%8B%E3%81%97%E3%82%88%E3%81%86%E3%80%90AWS%E3%83%8F%E3%83%B3%E3%82%BA%E3%82%AA%E3%83%B3%E8%99%8E%E3%81%AE%E5%B7%BB%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%E3%80%91-%E5%88%9D%E5%BF%83%E8%80%85%E3%82%82%E5%AE%89%E5%BF%83%EF%BC%81%E6%89%8B%E3%82%92%E5%8B%95%E3%81%8B%E3%81%97%E3%81%AA%E3%81%8C%E3%82%89AWS%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%8C%E3%81%97%E3%81%A3%E3%81%8B%E3%82%8A%E5%AD%A6%E3%81%B9%E3%82%8B%E4%B8%80%E5%86%8A%EF%BC%81-%E5%B0%8F%E5%B1%B1-%E9%9B%84%E5%A4%AA-ebook/dp/B0CH7P3SQM)