OmniAICreator/Qiita-1.07M huggingface dataset:
google clone Part14　Create Search result component 2/3 検索結果を実装

# 概要
目次

https://qiita.com/RYA234/items/7cf917e4e5cdea668e2e

今回は文字検索の結果を実装します。
以下実装後のgifアニメです。

![ddadaasaads.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/3eeb6977-a0f5-e088-aa7a-30b8213fd67e.gif)


# 開発環境

OS:Windows10
IDE:VSCode

"@next/font": "13.1.5",
"autoprefixer": "10.4.14",
"eslint": "8.39.0",
"eslint-config-next": "13.3.1",
"next": "13.3.1",
"postcss": "8.4.23",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-icons": "^4.8.0",
"tailwindcss": "3.3.2"

# 実装のポイント
## 検索結果のレイアウト
flex-colを使って各要素を縦並びに配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/b3811016-22f6-b77a-e89a-dd716851385b.png)



## groupを使ってhover時にタイトルだけハイライトするようにする
親要素にてgroupを指定することで、他の子要素（URLとスニペット）をhoverしてもタイトルがhoverすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/cc4b013c-971e-f088-ae3a-613c57a81b18.png)



# コード部分
## WebSearchResults
```diff_jsx:WebSearchResults.jsx
+import Link from "next/link";

export default function WebSearchResults({results}){
   return(
    <div>
        <p className="text-gray-600 text-sm mb-5 mt-3">
            About {results.searchInformation?.formattedTotalResults}
            results ({results.searchInformation?.formattedSearchTime} seconds)
        </p>  
+        {results.items?.map((result) => (
+            <div className="mb-8 max-w-xl" key={result.link}>
+                <div className="group flex flex-col">
+                    <Link className="text-sm truncate" href={result.link}>
+                        {result.formattedUrl}
+                    </Link>
+                    <Link className="group-hover:underline decoration-blue-800 text-xl truncate font-medium text-blue-900" href={result.link}>
+                        {result.title}
+                    </Link>
+                    <p className="text-gray-600">
+                        {result.htmlSnippet}
+                    </p>
+                </div>
+            </div>
+        ))}
    </div>
   ) 
}

```




# 参考

## css

### ml-8

https://tailwindcss.com/docs/margin

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/d8a64582-73f5-fafd-3047-27e05d08c6ac.png)



### group

https://tailwindcss.com/docs/hover-focus-and-other-states#styling-based-on-parent-state

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/0bec9c8e-da4c-bdf1-d2a5-fb39f07ac6bc.png)


## truncate

https://tailwindcss.com/docs/text-overflow

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/9ce93104-58db-931d-001f-6975165caa7c.png)


## その他
Google API レスポンス

https://developers.google.com/custom-search/v1/reference/rest/v1/Search?hl=ja


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/3fb14de1-9111-7117-6ef1-02847b1cb19d.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/8e534299-79c0-4df8-bcec-8b8841e35a5a.png)



Udemy

githubコミット分

https://github.com/RYA234/googlecone12/commit/6e31ab2295c138d77e13263d9654f845069cbe5a
google clone Part13　30 Create Search result component 1/3 検索結果　時間を実装

# 概要
目次

https://qiita.com/RYA234/items/7cf917e4e5cdea668e2e

今回は検索結果画面の　検索件数と検索に要した時間を実装します。
以下実装後の様子です。

![zzzzzzzzzzzxxza.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/bfa899df-de51-2cd5-50e0-3b69b683ed9e.gif)


# 開発環境

OS:Windows10
IDE:VSCode

"@next/font": "13.1.5",
"autoprefixer": "10.4.14",
"eslint": "8.39.0",
"eslint-config-next": "13.3.1",
"next": "13.3.1",
"postcss": "8.4.23",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-icons": "^4.8.0",
"tailwindcss": "3.3.2"

# 実装のポイント
APIのレスポンス（earchInformation.formattedTotalResultsとresults.searchInformation.formattedSearchTime）を表示させます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/75dddf42-6651-5145-2843-349e20194a4f.png)

# コード部分
## app/search/web/page.jsx
```diff_jsx:page.jsx
import WebSearchResults from "@/components/WebSearchResults";
import Link from "next/link";

export default async function WebSearchPage({ searchParams }) {
  await new Promise((resolve) => setTimeout(resolve,10000));
  const response = await fetch(
    `https://www.googleapis.com/customsearch/v1?key=${process.env.API_KEY}&cx=${process.env.CONTEXT_KEY}&q=${searchParams.searchTerm}}`
  );

  if (!response.ok) {
    throw new Error("Something went wrong");
  }

  const data = await response.json();
  const results = data.items;
  if(!results){
    return(
      <div className="flex flex-col justify-center items-center pt-10">
        <h1 className="text-3xl mb-4">No results found</h1>
        <p className="text-lg">
          Try searching for something else or go back to the homepage
          <Link href="/" className="text-blue-500">
            Home
          </Link>
        </p>
      </div>
    );
  }

+  return <>{results && <WebSearchResults results={data}/>}</>;
}

```

## WebSearchResults
```diff_jsx:WebSearchResults.jsx
export default function WebSearchResults({results}){
   return(
    <div>
        <p className="text-gray-600 text-sm mb-5 mt-3">
            About {results.searchInformation?.formattedTotalResults}
            results ({results.searchInformation?.formattedSearchTime} seconds)
        </p>  
    </div>
   ) 
}

```


# 参考





## その他

https://developers.google.com/custom-search/v1/reference/rest/v1/Search?hl=ja

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/30ad2bf5-5e5b-f9cc-f283-65df78800473.png)



Udemy

githubコミット分

https://github.com/RYA234/googlecone12/commit/980e8723b43f4a0ccdcb9b4875fa3be391d324d2
google clone Part12　28 fetch data from google search api 　取得したデータをブラウザで表示

# 概要

目次

https://qiita.com/RYA234/items/7cf917e4e5cdea668e2e

今回はGoogleのProgrammable SearchEngineを使って検索結果のデータを取得ブラウザ上に表示します。

![cvzdfsaffdadfa.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/e159b594-f117-07f7-7058-0e79038cecc1.gif)



# 開発環境

OS:Windows10
IDE:VSCode

"@next/font": "13.1.5",
"autoprefixer": "10.4.14",
"eslint": "8.39.0",
"eslint-config-next": "13.3.1",
"next": "13.3.1",
"postcss": "8.4.23",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-icons": "^4.8.0",
"tailwindcss": "3.3.2"

# 実装のポイント
## Programmable Search Engineを作成する

https://programmablesearchengine.google.com/about/



以下作成結果。黄色線部で使われている部分はAPIのパラメーターで使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/2672b3f9-574c-fe0a-fbbf-cea2932b698e.png)


## APIキーの取得

https://developers.google.com/custom-search/v1/using_rest?hl=ja


Programmable Search EngineのドキュメントからAPIキーを取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/b376565a-9396-2414-762b-a49613f9d41c.png)


## 環境変数の設定
.env.localにAPI_KEYとCONTEXT_KEYを設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/0edac9e3-d9ce-59c6-d13b-5d93480e7abf.png)


## APIを叩いて検索結果のタイトルをブラウザに表示する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/3ac529a1-1454-8eab-0ca2-64fdb20fd95e.png)


# コード部分
## app/search/web/page
```diff_jsx:page.jsx
export default async function WebSearchPage({searchParams}) {
  const response = await fetch(
    `https://www.googleapis.com/customsearch/v1?key=${process.env.API_KEY}&cx=${process.env.CONTEXT_KEY}&q=${searchParams.searchTerm}`
  );

  const data = await response.json();
  console.log(data);
  const results = data.items;
  return (
    <>{results && results.map((result) => <h1>{result.title}</h1>)}</>
  )
}

```




# 参考

https://developers.google.com/custom-search/v1/using_rest?hl=ja


API　パラメーター

https://developers.google.com/custom-search/v1/using_rest?hl=ja

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/bc38c52d-8c9b-f877-ed39-dc81f92caaa0.png)


API　レスポンス

https://developers.google.com/custom-search/v1/reference/rest/v1/Search?hl=ja

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/12b469d5-8752-5603-2f11-da1b7849a5a2.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/eb8e1fd2-936e-ea3b-8006-264a7561af0b.png)



## その他



Udemy

githubコミット分

https://github.com/RYA234/googlecone12/commit/06a26ecdab40593308db3876a19dc9747d4230b3
google clone まとめ Part11-17完

# 参考
https://www.udemy.com/course/react-js-tutorial/learn/lecture/36592882#overview
# 一覧

## Part11　27 complete the search header options  Allタグと画像タグを追加　切り替えを行えるようにする

![cczdasadsa.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/375c9f08-c836-f5db-c251-dadd2d21597f.gif)

https://qiita.com/RYA234/items/d2fa019b14176a3a1f5f

##  Part12　28 fetch data from google search api 　取得したデータをブラウザで表示

![cvzdfsaffdadfa.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/e159b594-f117-07f7-7058-0e79038cecc1.gif)

https://qiita.com/RYA234/items/d52f8fa3a5f89967af21

## Part13　30 Create Search result component 1/3 検索結果　時間を実装

![zzzzzzzzzzzxxza.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/bfa899df-de51-2cd5-50e0-3b69b683ed9e.gif)

https://qiita.com/RYA234/items/d3028928b440fdedaeeb

## Part14　Create Search result component 2/3 検索結果を実装

![ddadaasaads.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/3eeb6977-a0f5-e088-aa7a-30b8213fd67e.gif)

https://qiita.com/RYA234/items/3195a084519556ee8892

## Part15　30 Create Search result component 3/3 APIのレスポンスのHTMLを反映するために　react-parserを導入

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/2ea5de5a-c9f2-de8d-b173-65570e82e120.png)


https://qiita.com/RYA234/items/cbf512b1c5210e20bdae

##  Part16　Imageの検索結果を実装

![dfagggggaddfafda.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/83cc797c-5cab-fb99-a1a7-abfb43fffdea.gif)

https://qiita.com/RYA234/items/865993d581085bb625e1

## Part17　Pagination実装

![nnnmn..,.m,.m,.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/b9dc0a61-acc4-907d-a0b2-a4a2b87cffcb.gif)


https://qiita.com/RYA234/items/83e14437e259958941cd
【解決方法】ActiveRecord: :NoDatabaseError とは？

Ruby on rails を学習中の方の参考にしてもらえたら嬉しいです。 
今回はアプリケーションを作成している時に出てくるエラーとその解決方法について掲載します。少しでも参考にしていただけると幸いです。 まず最初にActiveRecord: :NoDatabaseErrorというエラーの解決方法をお話しします。

結論から先にお伝えすると、ターミナルで　【rails g model モデル名】を実行した後に　【rails db:create】をしていなかったために起きたエラーでしたので、実行してあげれば解決しました。

![スクリーンショット 2023-05-18 7.07.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356902/7711b061-691f-8165-ae79-eabd6d0ee631.png)

▲上の画像のようにエラー画面ができてきたら以下の手順で解決していきましょう。

▼下の画像ではChatGPTに解決策を質問しています。
![スクリーンショット 2023-05-18 7.08.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356902/fd37a39b-c8a7-caa5-a402-a98d55c1c962.png)

▼今回の私のエラーについて、以下のようにChatGPTが指示してくれていますが、関係ない部分かと思います。
![スクリーンショット 2023-05-18 7.08.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356902/183670b9-657b-7d76-333e-66d3be8321a0.png)

▼そして、ターミナルで実行してあげる
![スクリーンショット 2023-05-18 7.09.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356902/3f65b52a-c52d-3a66-318f-17c2479deac8.png)

▼最後にブラウザを再読み込みして確認するとエラーが消えたことが確認できました。
![スクリーンショット 2023-05-18 7.10.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3356902/57960009-a4ac-51f2-b3af-03f5bb83d023.png)

いかがでしたでしょうか？
他にも記事を発信していきますので、私の QiitaやTwitterをフォローしていただけると嬉しいです。
個別の質問もぜひ歓迎します。
私自身、初学者ではありますが、1歩先を行くものとして回答できたらと思います。
paiza.ioでelixir その222

# 概要
paiza.ioでelixirやってみた。
Zenスタイル、やってみた。

# 参考にしたページ。

https://qiita.com/yasuhiro-okada-aktsk/items/9ee247aac0fcd06b1cfa

# サンプルコード

全ての組み合わせを列挙

```

defmodule K do
	def echo(x, y) do
	    IO.inspect {x, y}
	end
end

IO.puts "recursion"
defmodule Sample do
	def show([], _) do
	end
	def show(_, []) do
	end
	def show([x | tl], y) do
		show(x, y)
		show(tl, y)
	end
	def show(x, [y | tl]) do
    	K.echo(x , y)
		show(x, tl)
	end
end
Sample.show [1, 2, 3], [4, 5, 6]

IO.puts "Zen"
Enum.map([1, 2, 3], fn x ->
	Enum.map([4, 5, 6], fn y ->
    	K.echo(x , y)
    end)
end)

IO.puts "for"
for x <- [1, 2, 3], y <- [4, 5, 6] do
	K.echo(x , y)
end




```

# 実行結果

```
recursion
{1, 4}
{1, 5}
{1, 6}
{2, 4}
{2, 5}
{2, 6}
{3, 4}
{3, 5}
{3, 6}
Zen
{1, 4}
{1, 5}
{1, 6}
{2, 4}
{2, 5}
{2, 6}
{3, 4}
{3, 5}
{3, 6}
for
{1, 4}
{1, 5}
{1, 6}
{2, 4}
{2, 5}
{2, 6}
{3, 4}
{3, 5}
{3, 6}
```

# 成果物

https://paiza.io/projects/7wAWH1y-VI3dv5g7VyOprg

以上。
これからの時代求められる品質①

# 概要
この記事はシステムオブシステムズという手段を通してそこに関わるステークホルダーが
どのようなコトを体験することによって、何をなし得たいのか？
これからのプロダクト～システム開発に求められる品質に関しての考察内容である。

# 品質特性ISO規格
<img width="600" alt="スクリーンショット (80).png (401.2 kB)" src="https://img.esa.io/uploads/production/attachments/5827/2023/05/20/135213/6f498d90-489b-44f0-aff2-dad51237254a.png">

この図に記載されているのは、システムに求められる利用者視点の品質(Service視点)と
開発者視点の品質(Resource視点)である。

開発者と利用者は見ている視点が違うが、ざっくりいうと
利用者の方がマクロな抽象的視点でシステムを見ているのに対して、
開発者はミクロな具体的な内部のシステムの品質を見ている。

この規格はあくまでも１つのResourceシステムに求められる特性であり、
システムオブシステムズのようなさらに巨大なスケールのものに関しては、
自分たちでその対象のSoSにどんな特性が求められているのか？
という新たな品質特性変数(ISOにすらまだないもの)を探さなくてはならない。

そしてその上でその変数が測定可能なのか？まで詳細に落とし込めるのか？
などまで考察しなくてはならないため、従来のシステム設計の専門家というだけでは
このような考察は難しい。
なぜなら専門家は従来の今までの品質の延長線上に新たな画期的な品質を見出す傾向にあるが、
そもそもの様々なステークホルダが絡んだ結果の落としどころを満たす新たな品質は。
その延長線上にそもそも存在しているとは限らないからである。
従来の型に慣れている人も初心者も新しいフィールドでは共に初心者だから、
お互いに対等に尊重しあえる関係性を常に意識しないといけない。

## 個人的な思い
ただ自分の中で、従来のやり方の型にはまった人から何度も壮絶ないじめやパワハラを体験してきた過去があり、
従来のやり方に固執する人＝悪人、価値を創造できない人という認知バイアスがかかってしまい、
プロジェクトでも原理主義者の方への口調がたまに荒くなってしまう場面があるし、
具体なところに視点がいき、抽象なマクロ視点で視られない人へ軽蔑してしまうこともある。
この過去の強烈なトラウマという従来の記憶に固執して、
新しいことへの足かせになっているのは自分も全く同じ立場であるので、
ここを乗り越えるという感動体験も一種のSoS×DXのプロジェクトで得られる品質価値に繋がっていくのかもしれない。

きっとこれがプロジェクトのモデルで出てきた
「ユーザーと企業のエンゲージメントを高める」というものだと予想。
ただシステムの技術力を磨くだけでなく、
自分の過去や従来の型とも状況に応じてサヨナラして成長していくという体験をとおした
人間的成長力もプロダクトに本質的に求められているコトの品質なのかもしれない。


## 人材育成
あらゆるクリティカルシンキングやデザイン思考などを使いこなし、
トップダウンで新しい品質を見つけ出し、
それを実現手段として支えるリソースに求められる従来の品質特性と、
新たな品質特性の発見とに分けて、さらにそれらのトレードオフ関係を仮説を立ててから検証で明らかにしていく、
というスタイルが求められるため、
人材育成のスタイルも変化させなくてはいけないし、従来の100点中90点だったら
ダメなところを指摘するおじ様たちの減点主義なスタイルから、
「前回は50点だったけども、今回は55点だったね！どんな改善をしたのか聞かせてくれないかなwkwk」
という加点主義に変えていかなくてはならない。
(これは書籍への批評然り、こういったQiita記事へのコメント内容なども然りである。)

これは大変なことかもしれないが、DXプロジェクトだけでなく、
これからのプロジェクトを進めていくうえでも常に意識しなくてはいけないところに感じた。
ハッキリ言って、DX系のプロジェクトでここがもっとも重要なポイントに感じている。
従来のやり方で新しい変化を生もうと無理にしているから、うまく行かない。
従来のやり方に慣れたプロのメンバーで無理に変革を生もうとしているからうまく行かない。
2023/5/20主にITとかセキュリティの記事

SMB向けCisco製スイッチに深刻な脆弱性 - PoCが入手可能
https://www.security-next.com/146200

「WordPress」にアップデート - 複数脆弱性を解消
https://www.security-next.com/146198

「MLflow」にパストラバーサルの脆弱性 - 過去の修正をバイパス
https://www.security-next.com/146217

革服通販サイトに不正アクセス - システム移行後に判明
https://www.security-next.com/146203

RPCフレームワーク「Apache bRPC」に脆弱性
https://www.security-next.com/146211

なりすましメール対策、BIMI対応252ドメインで設定不備 - TwoFive(5/18)
https://news.mynavi.jp/techplus/article/20230518-2682432/

TwoFive、なりすましメール対策実態調査の最新結果を発表(5/18)
http://news1st.jp/archives/9509

Microsoft、2件のRCE脆弱性を修正した「Office for Mac v16.73」をリリース。(5/18)
https://applech2.com/archives/20230518-microsoft-office-for-mac-security-updates.html

Google「2年ログイン無しならアカウント削除」の新ポリシー、余裕？ 問題ない？ ネットは賛否の声(5/18)
https://news.mynavi.jp/article/20230518-2682345/

チャットGPT、神奈川県が業務に試験導入　アイデア出しや資料要約(5/18)
https://news.yahoo.co.jp/articles/121ffcd86038c9e6ede96904f6c5c5f2b326ef1d

東北大、業務に対話型ＡＩ　事務手続きや広報に利用(5/18)
https://www.sankei.com/article/20230518-W6OY6DL3DZIMRITQSJGPLT26OA/?ownedutm_source=owned%20site&ownedutm_medium=referral&ownedutm_campaign=ranking&ownedutm_content=%E6%9D%B1%E5%8C%97%E5%A4%A7%E3%80%81%E6%A5%AD%E5%8B%99%E3%81%AB%E5%AF%BE%E8%A9%B1%E5%9E%8B%EF%BC%A1%EF%BC%A9%E3%80%80%E4%BA%8B%E5%8B%99%E6%89%8B%E7%B6%9A%E3%81%8D%E3%82%84%E5%BA%83%E5%A0%B1%E3%81%AB%E5%88%A9%E7%94%A8

クラウド事業者ら「重要インフラ」に　自民、政府に提言(5/18)
https://www.nikkei.com/article/DGXZQOUA184H20Y3A510C2000000/

マイナ保険証は大丈夫? 情報誤登録は約7300件 他人データひも付けのトラブルも…一方で「最大2万円分のポイント還元」手続き 名古屋の区役所には多くの市民(5/18)
https://news.yahoo.co.jp/articles/d2ce620bb944e37ce0d87a592b8d9ff6ed1e68b0?source=rss

不正アクセスなどの容疑で中国籍の男逮捕　佐賀県警など合同捜査本部(5/18)
https://news.yahoo.co.jp/articles/83fd8475d9b68d16a3c00e27a750f4c6c06e09ce?source=rss

セキュリティー製品にLLMを搭載　エンジニア不足の特効薬になるか(5/19)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100111/051600098/

「検出不能」のマルウエアを生成　ChatGPTをどうだましたのか(5/19)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100113/051200107/

IPAがサイト刷新で利用者アクセスに支障、トップページ以外の流入想定せず(5/19)
https://xtech.nikkei.com/atcl/nxt/column/18/01157/051700086/

「AIならPython」は本当か　ChatGPT時代に学ぶべき言語(5/19)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100112/051200069/

ドコモ回線に「遅い」と不満続出　釈然としない言い訳で不安高まる(5/19)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100110/051500105/
Azure VMの自動パッチ適用にスケジュール実行が追加されている件

### 構築時に自動パッチ適用オプションを構成する

デフォルトで自動パッチ適用されるような設定になっているためそのままにしている方もいらっしゃるかもしれませんが、Azure VMのパッチを自動適用させるか、マニュアルにするかを設定することができます。（これ後から変更できないので意外と大事な設定です。）

![Autopatch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/af3e0cb7-a4c7-3c99-15f2-7f2e7f3ea0f8.png)

Azure CLIで確認してみると、以下のように設定されていることが確認できます。
```
az vm get-instance-view --resource-group myResourceGroup --name myVM
```
![Autopatch2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/0a3c8e19-6a82-616a-d5fb-73c1d6a1e280.png)

### どのパッチがいつ、どのように適用されるのか

重大、セキュリティのパッチがVMのタイムゾーンのピーク外の時間帯に自動で適用されます。このパッチ自動適用はAzureによってオーケストレートさせることができ可用性を優先しながら適用させるということが可能です。その場合はpatchModeの値がAutomaticByPlatformに設定されている（Azure Portalでの設定ではAzure-Orchestrated）必要があります。

> VM で VM ゲストの自動パッチ適用が有効になっている場合、使用可能な [重大] および [セキュリティ] パッチが自動的にダウンロードされて VM に適用されます。 このプロセスは、毎月新しいパッチがリリースされるたびに自動的に開始されます。 パッチの評価とインストールは自動的に実行され、このプロセスでは必要に応じて VM の再起動が行われます。
https://learn.microsoft.com/ja-jp/azure/virtual-machines/automatic-vm-guest-patching

### どのOS、バージョンがサポートされるのか

[Microsoftのドキュメント](https://learn.microsoft.com/ja-jp/azure/virtual-machines/automatic-vm-guest-patching#supported-os-images)をご確認ください。Windows Server、LinuxのOSが含まれます。

### マニュアル適用に戻したい

Windows VMの場合`osProfile.windowsConfiguration.enableAutomaticUpdates`を`false`に変えると`patchMode`を`manual`に変更することができるのですが、`enableAutomaticUpdates`はVM作成時のみ設定可能なプロパティであり後から変更することが今のところできなさそうです。

### スケジュール実行はできる
ただAzure VMの更新メニューを触ってみると以下のページへのバナーが出ていました。マニュアルに変更しようとすると怒られましたが、スケジュールはカスタムすることがPreviewでできるようになっています（Azure Arc VMは未対応）。
![Autopatch4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/2297535b-4feb-5563-bcc7-f190fc020e53.png)

実際にスケジュール実行がうまく動いているところまで検証できておらず恐縮ですが、一応スケジュールを設定できたと思います。
これで間違えてパッチ自動適用にしてしまって勝手に望まない時間に更新が実行されてしまうけどどうにもできないみたいな話が解消できそうです。

![Autopatch6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/303f8cae-382c-ea89-5011-3489f72cc751.png)

Microsoftドキュメントは[こちら](https://learn.microsoft.com/Ja-jp/azure/update-center/prerequsite-for-schedule-patching?tabs=new-prereq-portal%2Cauto-portal)。
アルゴリズムと数学 演習問題集 031 - Taro's Vacation

# 記事概要
アルゴリズムと数学 演習問題集 031 - Taro's Vacationのとりあえず動くコードと説明．https://atcoder.jp/contests/math-and-algorithm/tasks/math_and_algorithm_ac?lang=ja

# 注意
アルゴリズム初心者が書いています．時間内の動作は確認してますが、必ずしも最適解ではないです．

# とりあえずコード
~~~C++:031_main.cpp
///////////////////////////
// 031 - Taro's Vacation //
///////////////////////////

#include <iostream>
#include <vector>
#include <iomanip>

#define ULL unsigned long long int 

using std::vector;

int main(void) 
{
	//============================== 入力==============================//
	int N;
	std::cin >> N;

	vector<ULL> A(N);
	for (int i = 0; i < N; ++i) {
		std::cin >> A[i];
	}

	//============================== 計算==============================//

	vector<vector<ULL>> dp(2, vector<ULL>(N + 1));

	for (int i = 1; i <= N; ++i) {
		// 今日勉強しないとき
		dp[0][i] = std::max(dp[0][i - 1], dp[1][i - 1]);

		// 今日勉強する時
		dp[1][i] = dp[0][i - 1] + A[i - 1];
	}

	/*
	// dp確認
	for (int i = 0; i < dp[0].size(); ++i) {
		std::cout << std::setw(5) << dp[0][i] << " ";
	}
	std::cout << std::endl;

	for (int i = 0; i < dp[1].size(); ++i) {
		std::cout << std::setw(5) << dp[1][i] << " ";
	}
	std::cout << std::endl;
	*/

	//============================== 出力 ==============================//
	std::cout << std::max(dp[0].back(), dp[1].back()) << std::endl;
}
~~~

# 説明
・太郎君はi日目に勉強するとA_iだけ実力が上がる．
・しかし、太郎君は2日以上連続で勉強できない．
・太郎君のあげることのできる実力の最大値を求めよ．
というのがこの問題の概要です．

この問題はx日目までにあげることのできる実力の最大値が、x-1日目までにあげることのできる実力の最大値から求められます．よって、動的計画法で解くことができる．

ただし、太郎君は2日以上連続して勉強できないため、x-1日目は勉強したかどうかを考慮する必要があります．

このコードの場合、dp[0][i]にはi日目に勉強しなかったときのi日目までにあげることのできる実力の最大値が格納してあり、dp[1][i]にはi日目に勉強した場合の最大値が格納してあります．

i日目に勉強しない場合、i-1日目に勉強をしているかどうかを考慮する必要はありません．よって、dp[0][i]には、i-1日目に勉強した場合と勉強しなかった場合のうち、大きい方が入ります．

対してi日目に勉強をする場合、i-1日目は勉強をしていない必要があります．よって、i-1日目に勉強しなかった場合の上がる実力の最大値と今日勉強することで上がる実力の和で計算できます．つまり、dp[1][i]にはdp[0][i - 1] + A[i - 1]が入ります．(i日目に勉強した場合に上がる実力はA[i-1]に入っています)

最後に最終日に勉強しなかった場合と勉強した場合のうち、大きい方が求める「太郎君があげることのできる実力の最大値」になります．
Railsでの商品購入機能実装: 特に初心者が陥りやすいエラーとその解決法


# 1. introduction
こんにちは、[uni](https://twitter.com/uni_on_tw) です。
Twitter👉 https://twitter.com/uni_on_tw
blog👉 https://toarukasou.com/
この記事では、Railsを用いて商品購入機能を実装する際に、エンジニアやプログラミング学習初心者が陥りやすいエラーとその解決法について語ります。

# 2. 商品購入機能とは
商品購入機能は、オンラインショッピングサイトにとって絶対に欠かせない機能の一つです。基本的には、ユーザーが商品を選択し、支払い方法を選んで注文を確定する一連の流れを含みます。

```ruby
# サンプルコード: 商品購入機能の基本的なフロー
def purchase
  @item = Item.find(params[:item_id])
  @user = current_user
  @payment = Payment.new
end
```
# 3. 実装中に陥りがちなエラーとその解決法
## 3.1 データベースの設定エラー
データベースの設定エラーは、商品購入機能の実装において非常によく見られるエラーです。具体的には以下のようなエラーメッセージが表示されます。

```ruby
Copy code
# エラーメッセージの例
ActiveRecord::StatementInvalid: PG::ObjectInUse: ERROR:  database "furima_38666_production_yz7k" is being accessed by other users
```
このエラーは、他のユーザーがデータベースにアクセスしているときにデータベースをドロップしようとしたときに発生します。解決方法は、データベースにアクセスしているセッションを確認し、適切に切断することです。以下のコマンドは、現在の接続を確認するためのものです：

```sql

SELECT * FROM pg_stat_activity WHERE datname = 'your_database_name';
```
接続を切断するには以下のコマンドを使用します：

```sql

SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'target_database'
  AND pid <> pg_backend_pid();
```
# 4. 特に初心者が陥りがちなエラーとその解決法
## 4.1 バリデーションエラー
初心者が陥りやすいエラーの一つは、バリデーションエラーです。これはモデルに設定したバリデーションがうまく機能していないときに発生します。例えば、以下のようなエラーメッセージが表示されることがあります。

```ruby
# エラーメッセージの例
ActiveRecord::RecordInvalid: Validation failed: Email has already been taken
```
これは、一意性を保証するためのバリデーションが働き、既に存在するメールアドレスで新たなユーザーを作成しようとしたときに発生します。この問題を解決するには、一意性のバリデーションが適切に設定されていることを確認する必要があります。以下のように設定できます：

```ruby

# モデルの一例
class User < ApplicationRecord
  validates :email, uniqueness: true
end
```
# 5. 最後に
商品購入機能の実装は複雑なプロセスであり、エラーは避けられません。しかし、エラーは問題ではなく、それをどう解決するかが重要です。エラーメッセージを理解し、それに対応する適切な解決策を見つけることが大切です。そして、その過程で学んだことを共有することは、私たちがより良いエンジニアになるための重要なステップです。
LOCAL環境でHTTPSが必要なときはlocal-ssl-proxyが便利

nextauth.js でシングルサインオン機能を実装する場合、SlackなどはアプリケーションがHTTPS接続をサポートしていることが前提となっており、開発時にもHTTPSのサポートが必要となる場合があります。このような場合には、local-ssl-proxyを利用して、リバースプロキシのようにする方法が簡単で便利です。

以下、LOCAL環境＝Windows PC、という前提です。

# local-ssl-proxyのインストール

local-ssl-proxyはグローバルインストールしかサポートしていません。ので、グローバルインストールします。

```powershell:
npm install -g local-ssl-proxy
```

以下は利用例です。Next.jsのアプリは3000番ポートで起動している状態で、local-ssl-proxyを3001番ポートで起動して、向き先を3000番ポートに向けてやります。こんな感じ。

```powershell:
npx local-ssl-proxy --source 3001 --target 3000
```

とりあえずこれで、HTTPで動作しているアプリケーションに対してHTTPSで呼び出すことができるようになります。

https://github.com/cameronhunter/local-ssl-proxy

# 動くには動くが毎回SSL警告が出る

> You'll get a warning because the certificate is self-signed, this is safe to ignore during development.

デフォルトの証明書が自己署名であるため、アクセス時にSSL警告が出ます。有効な証明書を作成しましょう。

## mkcertのインストール

[scoop](https://scoop.sh/)からインストールするのが容易です。クイックスタートに従って以下のコマンドを実行します。

```powershell:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
irm get.scoop.sh | iex
```

インストールできたら、以下のコマンドを実行。

```powershell:
scoop bucket add extras
scoop install mkcert
```

https://scoop.sh/

https://github.com/FiloSottile/mkcert

## mkcertの実行

**以下のコマンドは管理者権限で実行しないとエラーになるので注意。** もし一般ユーザーで実行してしまった場合、`mkcert -uninstall` してやり直す。

```powershell:
mkcert -install
```

以下でlocalhost用の鍵と証明書を作成する。

```powershell:
mkcert localhost
```

これで、`localhost-key.pem`と`localhost.pem`が作成されました。

## 証明書を有効にして起動する

```bash:
npx local-ssl-proxy --key localhost-key.pem --cert localhost.pem --source 3001 --target 3000
```

# 毎回local-ssl-proxyを起動するのはめんどい

`npm-run-all`が便利です。

```bash:
npm install -D npm-run-all
```

インストールできたら、`package.json`を以下のように修正します。

```js:package.json
{
  "scripts": {
    "dev": "npm-run-all -p dev:*",
    "dev:app": "next dev",
    "dev:ssl": "local-ssl-proxy --key localhost-key.pem --cert localhost.pem --source 3001 --target 3000"
    /* 省略 */
  }
  /* 省略 */
}
```

これで、`npm run dev` とすると、`dev:*`に一致するものを並列実行（`-p`）してくれます。

https://www.npmjs.com/package/npm-run-all

# 余談

好評なので英語版も書きました。

https://dev.to/cress/when-you-need-https-on-local-environment-local-ssl-proxy-is-the-best-solution-24n6
CSSの基本

# CSSとは
CSSは"<font color="Blue">C</font>ascading <font color="Blue">S</font>tyle <font color="Blue">S</font>heets"の略で，HTMLで記述されたWebページの見栄え，スタイルを効率的に定義するための技術．HTMLで文書の意味を定義し，CSSで見栄えを定義することにより，意味と見栄えを分離することが可能となる．

# CSSの基本文法
CSSの基本文法は以下の３つで構成される．
![CSS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3133563/7e29f2fe-3eb5-e6d3-35e8-8ff36b2577ea.png)
**１．セレクタ**
→HTML要素のどれに適用させるかを定義するもの
**２．プロパティ**
→指定した要素の何を変化させるかを定義するもの
**３．指定値**
→実際に指定する値を記述するもの

# セレクタの種類
CSSの指定したい範囲に応じて，セレクタを使い分ける必要がある．以下は基本的なセレクタである．

**１．全称セレクタ**
```css
* { color: red;}
```
アスタリスク``*``を指定することで，全てのがスタイルの適用対象となる．


**２．要素型セレクタ**
```css
要素名 { color: red;}
```
タグ名で指定した要素がスタイルの適用対象となる．

**３．クラスセレクタ**
```css
.クラス名 { color: red;}
```
クラス名にドット``.``を付けて，指定することで，そのクラスを持つ全ての要素がスタイルの適用対象となる．

**４．IDセレクタ**
```css
#ID名 { color: red;}
```
id名にシャープ``#``を付けて，指定することで，そのidを持つ全ての要素がスタイルの適用対象となる．

**5.属性セレクタ**
```css
[属性=属性値] { color: red;}
```
属性の値とその属性値を指定することで，同様の属性と属性値を持つ全ての要素がスタイルの適用対象となる．

## その他のテクニック
**・セレクタの組合せ**
```css
要素名.クラス名 { color: red;}
要素名#ID名 { color: blue;}
```
クラス名やID名で指定する場合，その前にタグ名をつけることで，より詳細にスタイルの適用対象を指定することができる．

**・複数のセレクタ**
```css
h1,h2 { color: red;}
```
複数の要素について指定したい場合は，セレクタをカンマ``,``で繋げることで複数の要素をスタイルの適用対象とすることができる．

# セレクタの優先順位
CSSのスタイルの適用には優先順位がある．もし同じ要素に対して異なるスタイルを指定した場合，その優先順位に応じてスタイルが適用される．優先順位は**書く位置**と**セレクタの種類**によって決められる．

**◯書く位置による優先順位**
CSSは上から読み込まれるため，下に位置するものほど優先順位が高い．これはHTMLでも同様となる．

**◯セレクタの種類による優先順位**
セレクタは，「idセレクタ＞classセレクタ＞要素型セレクタ」という順で優先度が強く，要素タグをつけるとより優先度が強くなる．

|優先度|セレクタ|例|
|:-:|:-:|:-:|
|強|タグ名＋idセレクタ|``div#id名 {style}``|
|↑|idセレクタ|``#id名 {style}``|
||タグ名＋classセレクタ|``div.class名 {style}``|
|↓|classセレクタ|``.class名 {style}``|
|弱|要素型セレクタ|``要素名 {style}``|


# CSSの読込み方法
HTMLにCSSを適用する方法として，以下の３つの方法がある．
**１．style属性で指定する方法**
```html
<p>CSSなし</p>
<p style="color: red;">CSSあり(style属性で指定)</p>
```
↓結果
![c1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3133563/497a7da1-eb79-6d16-097a-f08d982051fa.png)
要素のタグの中にstyle属性を用いて記述することによって，その要素にのみCSSを適用することができる．

**２．styleタグで指定する方法**
```html
<head>
    <style>
        .sample{ color: blue;}
    </style>
</head>
<body>
    <p>CSSなし</p>
    <p class="sample">CSSあり(styleタグで指定)</p>
</body>
```
↓結果
![c2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3133563/0cc3a035-6bb2-758c-afcc-b199c20bf6d3.png)
``<style>``タグを配置して，CSSのコードをその中に記述することによって適用する．``<head>``または``<body>``タグ内に書いていれば適用される．

**３．外部CSSファイルから指定する方法**
```html
<!-- HTML -->
<head>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <p>CSSなし</p>
    <p class="sample">CSSあり(外部CSSファイルで指定)</p>
</body>
```
```css
/* CSS */
.sample{
    color: green;
}
```
↓結果
![c3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3133563/6460df90-86d9-6079-c39c-359289371cbf.png)
``<head>``タグ内で``<link>``タグを用いて外部のCSSファイルを指定することによってCSSを適用する．``rel``には必ず``stylesheet``,`href`にはCSSのファイル名(正確にはCSSファイルのパス)を記述する．外部CSSファイルを用いることで、複数の HTML文書で共通のCSSを共有することが可能となる．
s-nailで外部SMTPサーバーを利用してメール送信

mailとかmailxとかこれまで色々使って来ましたがRHEL9でs-nailを使うことにしました。DDNSでのメールサーバー運用は工数がかさみ割に合わないので、契約しているプロバイダのSMTPを使用してます。

外部送信SMTPサーバー: smtp.external
SMTP認証ポート: 587
SMTP認証ユーザーID: xxx@xxx.external
SMTP認証パスワード: xxx[xxx\xxx
From: from@xxx.external
To: to@yyy.zzz

以下備忘。

基本構文は以下。
*s-nail -:/ -s "Subject" -S v15-compat -S mta=smtp://USER:PASS@smtp.external:PORT -S from=From@Address To@Address < MailBody*

やってみる。
~~~
$ s-nail -:/ -s "Test Mail" -S v15-compat -S mta=smtp://xxx@xxx.external:xxx[xxx\xxx@smtp.external:587 -S from=from@xxx.external to@yyy.zzz < ./MailBody 
s-nail: Not URL percent encoded (use `urlcodec enc'): xxx[xxx\xxx
s-nail: *mta*: invalid or unsupported value: smtp://xxx@xxx.external:xxx[xxx\xxx@smtp.external:587
/home/user/dead.letter 8/188
s-nail: ... message not sent
$
~~~

percent encodeされてないよ、urlcodec encを使え、と言っている。
s-nailのman pageを確認。

*:
:
   On URL syntax and credential lookup
     For accessing protocol-specific resources Uniform Resource Locators (URL, RFC 3986) have become
     omnipresent.  Here they are expected in a “normalized” variant, not used in data exchange, but
     only meant as a compact, easy-to-use way of defining and representing information in a well-
     known notation; as such they do not conform to any real standard.  Optional parts are placed in
     brackets ‘[]’, optional either because there also exist other ways to define the information, or
     because the part is protocol specific.  ‘/path’ for example is used by the [Option]al Maildir
     folder type and the IMAP protocol, but not by POP3.  __If ‘USER’ and ‘PASSWORD’ are included in an
     URL server specification, URL percent encoded (RFC 3986) forms are needed, generable with
     urlcodec.__
:
:
   __Raw data arguments for codec commands__
     A special set of commands, which all have the string “codec” in their name, like addrcodec,
     shcodec, urlcodec, __take raw string data as input,__ which means that the content of the command
     input line is passed completely unexpanded and otherwise unchanged: like this the effect of the
     actual codec is visible without any noise of possible shell quoting rules etc., i.e., the user
     can input one-to-one the desired or questionable data.  To gain a level of expansion, the entire
     command line can be evaluated first, for example
:
:*



うーむ、とりあえずやってみる。
~~~
$ echo 'urlcodec enc xxx@xxx.external' | s-nail -#
xxx%40xxx.external
$
~~~

お、意味が分かった。
~~~
$ echo 'urlcodec enc xxx[xxx\xxx' | s-nail -#
xxx%5Bxxx%5Cxxx
$
~~~

percent encodedのユーザー名とパスワードを入力してリトライ。
~~~
$ s-nail -:/ -s "Test Mail" -S v15-compat -S mta=smtp://xxx%40xxx.external:xxx%5Bxxx%5Cxxx@smtp.external:587 -S from=from@xxx.external to@yyy.zzz < ./MailBody 
$
~~~

無事メールが届きました。

//
【iTerm】コマンドの処理終了した時に通知する方法

## iTerm2で処理終了時に通知する方法
iTerm2で処理終了時に通知するようにできます。
![image220425_234415.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/b77084c9-7b3d-3dd6-d02c-fb45ae36c522.png)

設定方法を以下に記載します。

### `Shell Integration`をインストール
iTerm2を開いてメニューから`iterm2` > `Install Shell Integration`と選択します。
![image220425_232859.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/fd908b31-b005-dfa8-cf24-e75ff1969e91.png)


以下のように表示されます。
`Continue`をクリックします。
![image220425_235436.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/32f6350b-c1c0-e9fc-4177-6fb35e72bfef.png)
`Download and Run Installer`をクリックします。
![image220425_235251.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/e1adb511-c60d-cf1d-1632-b0d1d67d1fd6.png)
`Continue`をクリックします。
![image220425_235551.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/e6b816d1-82dd-1db3-5326-cf888f41e19e.png)
すると`.iterm2_shell_integration.zsh`がダウンロードされます。
また`.zshrc`に以下のように追記されます。

```.zshrc
test -e "${HOME}/.iterm2_shell_integration.zsh" && source "${HOME}/.iterm2_shell_integration.zsh"
```

### 通知の設定をする
メニューから`Edit` > `Marks and Annotations` > `Alerts`と選択します。
`Post Notification`にチェックがついていることを確認してください。
![image220426_001304.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/2356571b-89ea-cdb9-8fc7-c1ca61809418.png)
次にシステム環境設定を開き、iTerm2の通知が許可されているか確認します。
許可されていなければ許可します。
![image220426_003332.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/5a2cf246-864e-b762-b348-de5a9ad153bd.png)
`cmd + opt + a`を入力すると画面右上に目のマークがつきます。
![image220426_002224.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/fe09a158-b66a-fe7f-4c2d-3413514c70da.png)
この状態でコマンドを実行すると処理が終了すると以下のように通知されます。
![image220425_234415.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/b77084c9-7b3d-3dd6-d02c-fb45ae36c522.png)
JavaScriptのスプレッド構文と残余引数について

# スプレッド構文とは  
スプレッド構文とは、配列やオブジェクトリテラルを一つづつ取り出し展開する構文を指します。 
例えば、配列を`array`とすると、スプレッド構文は`...array`と表現されます。 
同じ記号を用いた表現に、残余引数というものがありますが、違いは以下になります。 

- スプレッド構文 
  - 配列リテラルやオブジェクトリテラルを展開する
- 残余引数
  - 複数ある引数を配列に圧縮する
  - 引数の個数が不明な関数の引数として使用する

したがって、残余引数はあくまで関数の引数を配列として圧縮した形で表現するのに対し、スプレッド構文は要素を展開する機能を持ちます。 
以下でその使い方を詳しくみてみます。

## 配列リテラルへの使用例  

```.js
const alphabet = ["a", "b", "c", "d", "e"];
const anotherAlphabet = ["x", "y", "z"];

//配列を複製  
const replacedAlphabet = [...alphabet];
console.log({replacedAlphabet});
//{ replacedAlphabet: [ 'a', 'b', 'c', 'd', 'e' ] }

//配列をマージ（結合）
const mergedAlphabet = [...alphabet, ...anotherAlphabet];
console.log({mergedAlphabet});
//{mergedAlphabet: ['a', 'b', 'c','d', 'e', 'x','y', 'z']}

//配列に別の要素を追加して、新しい配列を定義
const addedAlphabet = [...alphabet, "f", "g"];
console.log({addedAlphabet});
//{ addedAlphabet: ['a', 'b', 'c','d', 'e', 'f', 'g']}
```

## オブジェクトリテラルへの使用例  
```.js
const objAlphabet = {char1: "a", char2: "b", char3: "c"}
const anotherObjAlphabet = {char4: "y", char5: "z"};

//オブジェクトリテラルを複製  
replacedObjAlphabet = {...objAlphabet};
//{ replacedObjAlphabet: { char1: 'a', char2: 'b', char3: 'c' } }

//オブジェクトリテラルをマージ（結合）
mergedObjAlphabet = {...objAlphabet, ...anotherObjAlphabet};
//{mergedObjAlphabet: { char1: 'a', char2: 'b', char3: 'c', char4: 'y', char5: 'z' }}

//オブジェクトリテラルに別のオブジェクトリテラルを追加して、
//新しいオブジェクトリテラルを定義
addedObjAlphabet = {...objAlphabet, char6: "j", char7: "k"};
//addedObjAlphabet: { char1: 'a', char2: 'b', char3: 'c', char6: 'j', char7: 'k' }
```  

# 残余引数とは 
関数に渡す引数を、配列リテラルとして圧縮した引数を指します。　

## 残余引数の使用例 
```.js
//引数の数が不明な関数を使用する
let restParam = function(...args){
    let sum = 0;
    for (const arg of args) {
           sum += arg;
    }
    return sum;
}

console.log(restParam(...args1));
//console.log(restParam(1, 3, 5));と同じ意味になり、
//1 + 3 + 5 = 9が表示される。

console.log(restParam(...args2));
//console.log(restParam(1, 3, 5, 7));と同じ意味になり、
//1 + 3 + 5 + 7 = 16が表示される。
```
qiitaの練習

qiitaの使い方を把握するための投稿です。
```python
import testqiita
    print("hello qiita")
```

これは
```
```(プログラミング言語名)
コード```
```
で書けるのですね。シンタックスハイライトと同じと理解しました。
で

# これはH1タグです
```html
# これはH1タグです
```

#1個ならh1タグ

## これはH2タグです

```html
## これはH2タグです
```

##でh2タグになると。理解しました。ほとんどはチートシートに載っていますね。okok



これからよろしくお願いします
AWS CCP（Certified Cloud Practitioner）の試験対策

# はじめに
先日、表題の試験を受験し、無事合格することができました。
試験を受けようか迷っている方、試験対策を知りたい方へ向けて、私が取り組んだことや考えたことを共有します。
# 受験の目的
AWSについて、とりあえずサービスの基本を知っておきたいと思ったからです。
ゆくゆくは自分で運用・管理ができる、お客様により良い提案をできるようになるため、その足掛かりとして受験しました。

# どんな人が受験すべき？
* これからAWSを使っていきたい人
* （初心に立ち返りたい経験者にもいいかも）

「AWSに入門するならとりあえずこれ」という認識でよいと思います。
私も「名前は聞いたことあるけど中身はよく知らない」くらいの状態でしたが、そこそこ幅広く学べて良かったです。

# 学習方法
試験対策に利用した教材、学習方法などを共有します。
## 使用した教材
自分は以下の教材を利用しました。
* 『AWS認定資格 ソリューションアーキテクトアソシエイトの教科書: 合格へ導く虎の巻』
* Udemyの模擬試験問題（有料）

### AWS認定資格 ソリューションアーキテクトアソシエイトの教科書: 合格へ導く虎の巻
こちらはCloudTech書籍作成委員会さんから出ている書籍で、無料で購読することができます（2023/06現在）。

私はSAA（Solutions Architect - Associate）の受験も考えていたのでこちらを利用しましたが、CCP向けのテキストも出版されていますので、そちらも参考にして頂ければと思います。

読み進め方としては、自分はざっとひと通り読んで何度か読み返す、といった感じでした。
ここは好みだと思います。
### Udemyの模擬試験問題集
こちらの模擬試験問題集を使用しました。
[この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（6回分390問）]( https://www.udemy.com/course/aws-4260/ )

テキストをあまり読み進めていない段階でも、**「一度通して問題を解いてみる →　解説を読む」** というサイクルを繰り返していれば、着々と知識が身についてきます。
私も初めの方は5割くらいしか正答できず絶望していましたが、継続が大切です。

# 対策に充てた時間
総時間で言うと25時間くらいです。

よく言われますが、受験を決めた時点ですぐに予約をしておきましょう。
試験日が近づくと焦って嫌でも勉強するようになります（自分はそうでした）。

# 所感
簡単だった、と言いたいところですが、実際に試験で回答したときはあまり自信がなかったです。
自分の学習方法が「試験に合格する（＝点数を取る）」ためのものになってしまっていて、実際のサービスのイメージが湧きにくかったからかなと思います（単純に勉強不足もあります）。

これから実際にAWSを使っていくことを考慮すると、AWSの無料期間やエミュレータで色々なサービスを触りながら学ぶのが良いかもしれません。

# おわりに
自分は昔から勉強ぎらいな節があるので、久々に試験勉強をした気がします。
今回を一つの成功体験として、今後も精進していきます。
ここまで読んでいただき、ありがとうございました。
【SwiftUI】ネストを考慮して、ボタンを右下に配置

# 目的
ボタンを右したに配置すると、それだけでネストが深くなってしまうことがある。
できる限りシンプルにボタンを配置したい！

# コード
```swift
var body: some View {
    Button()
        .frame(maxWidth: .infinity,
	       maxHeight: .infinity,
	       alignment: .bottomTrailing)
}
```
【Laravel初心者向け】ECサイトのオープンソースをリーディングしてみた

# 概要
今回はララベルで実装されたECサイトのリーディングをしていきたいと思います。
使用するオープンソースのURLはこちらです。
https://github.com/jsdecena/laracom

## ターゲット
- プロダクトを作ったことはないLaravelの初心者
- まだLaravelの恩恵を受けていない人

## 目指すこと
以下のことをに留意し、「良いコード」を体系的に理解する
- MVCモデルを理解する
- ララベルのロジックを深掘りする
- データの受け渡しを追う

## 機能
一般的なECサイトです。

#### 顧客画面
- 商品一覧画面
    - 商品の詳細画面
    - 並べ替え、ソート、検索
- カート
    - セッションを使ったカート機能
    - カート内での商品個数の変更
- 支払い
    - PayPal、銀行支払い、クレカ支払い
- 顧客情報や購入履歴の管理
    - 住所の複数登録
    - 購入履歴の確認
    
#### 管理者画面
- 顧客情報の管理
- 商品の管理
    - 画像、説明、価格、数量の設定
- 注文の管理
    - 購入商品のリスティング
    - 支払いステータスの確認
- 配送業者の設定
- 従業員の管理
# 終わりに
次回から少しずつ進めていきます。ユーザーストーリーの順に書きたいと思っているので顧客の商品一覧画面からいきます。
AWS CDKで作成したAPIGateway+Lambda(Node18)をローカルで動かしてみたメモ

## 概要

[前々回](https://qiita.com/hibohiboo/items/942cd4192523d82faf0f)と[前回](https://qiita.com/hibohiboo/items/4d1c62ea98ecf0798064)はベータ版を試したが、ベータ版が取れていたので試した。([参考: ローカルでのテスト](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-cdk-testing.html))

[ソースコード](https://github.com/hibohiboo/RinneCircle/tree/63b9cbcf4a92c674d7acc412b172977115fe8b80/cdk)

## 環境
- Windows 10
- docker desktop v4.19.0
- aws-cdk 2.83.0
- sam-cli 1.84.0 ※

※ 2023/06/08 sam-cliの最新バージョンは1.86.1だが、 docker の 変更 と sam-cliの変更がコンフリクトしているらしく、`Error: request() got an unexpected keyword argument 'chunked'"`のエラーが出て動作しなかった。 [Issues](https://github.com/aws/aws-sam-cli/issues/5243 )。
[1.84.0をDLし](https://github.com/aws/aws-sam-cli/releases/download/v1.84.0/AWS_SAM_CLI_64_PY3.msi)、ダウングレードしたところ、うまくいった。

## 実践
まずはsynthでcdk.outにCloudFrontテンプレートを出力する。

```bash
cdk -a \"npx ts-node --prefer-ts-exts bin/rest.ts\" synth rinne-circle-RineCircleRESTAPIStack
```

つぎに、SAMでローカル起動する。
指定するテンプレートはスタック名で作成されている。

```
sam local start-api -t ./cdk.out/rinne-circle-RineCircleRESTAPIStack.template.json
```
下記のように`http://127.0.0.1:3000`でデフォルトでは実行される。
警告が赤字で出ているが、本番では使わないでくれ、みたいな意味なので問題ない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/f6e8cc5f-ef9e-8026-abd9-565c1cf72500.png)


RESTを投げて、動作することを確認した。

```rest
put http://127.0.0.1:3000/api/scenario

{
"id": "xxxxxxx-xxxx-4dff-be34-xxxxxxx",
"authorId": "test",
"title": "シナリオタイトル",
"imageUrl": "/scenarioTitle.png",
"path": "/scenario.json",
"published": true
} 
```
Oracle CloudのAlways Free マイクロ・インスタンスを有効に活用する方法

# はじめに
[Oracle CloudのFree Tier](https://www.oracle.com/jp/cloud/free/)には「Always Freeクラウド・サービス」と「30日間無料トライアル」の二つの無料プログラムがあり、両方同時に利用することが可能です。そして、Always Freeクラウド・サービスは期間の定めなく無料で利用することが可能というお得なサービスとなっています。
Always Freeクラウド・サービスの一覧は [Oracle CloudのFree Tier](https://www.oracle.com/jp/cloud/free/) を確認すると以下のようなサービスがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/8be9e5f3-7def-b929-70bd-88c28a5eed61.png)

今回はこのサービスの中の赤枠「2つのAMDベースのCompute VM、それぞれに1/8 OCPU**と1GBのメモリ」をほんのちょっとだけお得に？利用する方法をシェアします。

# Free TierのCompute VMの状況

Free TierのCompute VMには1GBのメモリが割り当てられているはずですが、実際に確認すると以下のように680MBのメモリしか割り当てられておらず、1GBのメモリが利用できていません。
```sh:メモリの状況
$ free -m
              total        used        free      shared  buff/cache   available
Mem:            680         192         237           1         250         384
Swap:          1360         348        1012
```

dmesgを確認すると、以下の通り、crashkernelとして280MBが割り当てられてしまっていることが確認できます。
```:dmesg
[    0.008900] Using crashkernel=auto, the size chosen is a best effort estimation.
[    0.008903] Reserving 280MB of memory at 678MB for crashkernel (System RAM: 1018MB)
```

Productionの環境で利用する場合には、kdumpの機能は必要な場合もありますが、基本的にAlways Freeで利用するような状況の場合には、不要と考えてます。以下でkdumpを無効化します。

```sh:kdump無効化
$ sudo systemctl disable --now kdump.service
Removed /etc/systemd/system/multi-user.target.wants/kdump.service.
$ sudo vim /etc/default/grub
## crashkernel=auto → crashkernel=no
$ ﻿sudo grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Adding boot menu entry for EFI firmware configuration
done
## インスタンス再起動
```

kdump無効化後のメモリ割り当て状況は以下のようになり、960MBのメモリが利用できるようになりました。

```sh:メモリ割り当て状況
$  free -m
              total        used        free      shared  buff/cache   available
Mem:            960         518          21           1         420         412
Swap:          1360           6        1354
```

# まとめ
Always Freeのリソースは無料で利用できるため、必要に応じて今回紹介した方法等を活用し、少しでも有効にリソースを利用していければと考えてます。
（特にAlways Freeのマイクロ・インスタンスに限定した話ではありませんが、Always Freeのマイクロ・インスタンスなら今回のような活用をしやすいと思い、このような形で紹介しました）
資格勉強にNotionを使ってみた結果

# はじめに
私は、某SIerに勤めるシステムエンジニア(プログラマ)です。昨年から今年にかけてOracle Database Administration Iと応用情報技術者試験を受験したのですが、試しに資格勉強にNotionを使ってみたので、その体験談を話してみたいと思います。
# Notionを使い始めるまで
それまで資格勉強のやり方といえば、とにかく、書く。書く。書く。書きまくる。という勉強の仕方でした。ルーズリーフにひたすら書きまくる。以前に基本情報技術者試験も受験しましたが、その時もひたすら書きまくってました。

ただし、紙に書いて勉強するのはいいのですが、勉強を進めるスピードが極端に遅いことと、ルーズリーフを買うお金がかかるのが課題でした。こんな便利なツールがあることなど知らなかった私は、しょうがないと思いながらも、ひたすら書いて勉強をしていました。
# Notionを使い始めた後
その後、Oracle Databaseの資格や応用情報技術者試験も、しばらくは書いて勉強していましたが、先述の課題をどうにかしたいと感じていました。そんなところに、使えそうだと感じたのが、その当時存在を知りたてだったNotionでした。

Notionを使って、セクションごとにページをぶら下げて重要ポイントを打ち出すという方法に勉強方法を切り替えてみました。いざ、始めてみると、ルーズリーフの購入に使ってしまうお金が0になったことはもちろん、知識を入れるスピードが格段に上がりました。スマホアプリ版もあるため、紙のときと違って勉強した内容をいつでもどこでも手軽に振り返ることができるようになったので、通勤時間を勉強に充てるハードルもグッと下がりました。
# 最後に
Notionに勉強方法を切り替えた成果は、十分にあったと感じていますし、Oracle Databaseの試験合格に寄与した部分はかなりあったように思います。(応用情報技術者試験は、記事投稿時点では、結果待ちです)

もっと早くNotionに出会えていたら...もっと早くツールの使用を検討していたら...と今になっては思います。
RubyでAtCoder ABC248(A, B, C, D)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC248のA, B, C, Dを解きました。備忘録として解き方をまとめていきたいと思います。

# A - Lacked Number
https://atcoder.jp/contests/abc248/tasks/abc248_a
```ruby:a-248.rb
puts [*"0".."9"] - gets.chomp.chars
```
## 解説
0~9の配列から与えられた文字列を配列にしたものを引いた後の数字が答えとなります。

# B - Slimes
https://atcoder.jp/contests/abc248/tasks/abc248_b
```ruby:b-248.rb
a, b, k = gets.split.map(&:to_i)
ans = 0
while a < b
  a *= k
  ans += 1
end
puts ans
```

# C - Dice Sum
https://atcoder.jp/contests/abc248/tasks/abc248_c
```ruby:c-248.rb
n, m, k = gets.split.map(&:to_i)
mod = 998244353

dp = Array.new(n + 1){Array.new(k + 1, 0)}
dp[0][0] = 1
n.times do |i|
  k.times do |j|
    1.upto(m) do |l|
      dp[i + 1][j + l] += dp[i][j] if j + l <= k
    end
  end
end
puts dp[n].sum % mod
```
## 解説
（[公式解説を参考にしました](https://atcoder.jp/contests/abc248/editorial/3745)）

dp[i][j] := 先頭からi項目までの総和がjであるような数列の決め方の総数として、dpの値を更新していくことで解くことができます。

# D - Range Count Query
https://atcoder.jp/contests/abc248/tasks/abc248_d
```ruby:d-248.rb
gets.to_i
a = gets.split.map(&:to_i)

hash = Hash.new{ |h, k| h[k] = [] }
a.each_with_index{ |number, index| hash[number] << index }

q = gets.to_i
q.times do
  l, r, x = gets.split.map(&:to_i)
  l -= 1
  r -= 1
  val = hash[x]
  val_size = val.size
  nl = val.bsearch_index{ |i| l - 1 < i } || val_size
  nr = val.bsearch_index{ |i| r < i } || val_size
  puts nr - nl
end
```
## 解説
最初に連想配列hashにAの要素の数字をキー, インデックスを値として記録します。そして、与えられたクエリごとにAにおけるインデックスがL~Rの範囲で値がXとなるものの個数を出力することで解くことができます。なお、TLEを避けるため、`nl`と`nr`のインデックスを求める際には`bsearch_index`メソッドを使って二分探索しています。

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
【SwiftUI】NavigationTitleの新しいDisplayMode

# はじめに
iOS17からNavigationTitleに`inlineLarge`という新しいスタイルが加わりました。
他のスタイルとの見た目の違いを比較しながら紹介しようと思います。

# 見た目の違い
||||
|:-:|:-:|:-:|
|![Simulator Screenshot - iPhone 14 Pro - 2023-06-08 at 22.56.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/600ff00b-f47e-a2ae-d9cd-4fda96fac7cf.png)|![Simulator Screenshot - iPhone 14 Pro - 2023-06-08 at 22.55.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/9636a242-d5bf-e90c-2337-391a44da715c.png)|![Simulator Screenshot - iPhone 14 Pro - 2023-06-08 at 22.52.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/0bcb995a-c196-fc68-ee83-78d7b2c69418.png)|

# 実装
### large
```diff_swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            List {
                ForEach(0..<50) { index in
                    Text("セル\(index)")
                }
            }
            .navigationTitle("テスト")
            .toolbarTitleDisplayMode(.large)
        }
    }
}
```

### inline
```diff_swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            List {
                ForEach(0..<50) { index in
                    Text("セル\(index)")
                }
            }
            .navigationTitle("テスト")
            .toolbarTitleDisplayMode(.inline)
        }
    }
}
```

### inlineLarge
```diff_swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            List {
                ForEach(0..<50) { index in
                    Text("セル\(index)")
                }
            }
            .navigationTitle("テスト")
+           .toolbarTitleDisplayMode(.inlineLarge)
        }
    }
}
```

# ドキュメント
https://developer.apple.com/documentation/SwiftUI/View/toolbarTitleDisplayMode(_:)

# おわり
![スクリーンショット 2023-06-06 17.23.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/db95fd18-31ae-6410-6ae7-029a5673996c.png)
「Appleが一般に開示した情報」に該当してると思うので大丈夫だとは思いますが、
もしアウトだったらコメントで教えて欲しいです。
【React】Suspense によるコンポーネントの dynamic import を振り返る

# Suspense によるコンポーネントの dynamic import

この記事では、React 16.6 で追加された Suspense によるコンポーネントの dynamic import について紹介します。

(React 18 の Suspense の新機能についてはあえて触れませんが、続きの記事で解説する予定です。)

## dynamic import とは

JavaScript には **静的インポート(static import)** と **動的インポート(dynamic import)** があります。
ES2019までのインポート方法である **[import 文](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/import)** では、非同期にモジュールを読み込むことができませんでした。

```javascript:従来のインポート(静的インポート)
import xxxxx from yyyyy
```

このように従来のインポートが **静的(static)** であるのに対し、ES2020で追加された `import()` 式を使用することで、非同期にインポートができるようになりました。これが **動的インポート(dynamic import)** です。

```javascript:dynamic import
const xxxxx = await import(yyyyy)
```

dynamic import のメリットとして、webpack 等によるバンドルで生成される JavaScrript ファイルのサイズを削減することがよく上げられます。

https://webpack.js.org/api/module-methods/#import-1

## サスペンスを使った React コンポーネントの dynamic import 

ここからが本題です。React のコンポーネントを dynamic import する方法を紹介します。

React は `Suspense` と `lazy` を使うことで dynamic import ができます。
以下のように、`lazy` で `import()` 式を返す関数を渡し、それを `Suspense` の `children` として渡します。
注意点として、`Suspense` には `fallback` を指定する必要があります。`import()` を使った動的な読み込みが完了するまでの間、代わりに表示しておくものが `fallback` です。

```tsx
import { Suspense, lazy } from "react"

// lazy で import する
const SomeComponent = lazy(() => import("some_component")

// lazy で import したものを Suspense の children に
const Component = () => {
  return (
    <Suspense fallback={FallbackComponent}>
      <SomeComponent />
    </Suspense>
  )
}
```

この Suspense を使って dynamic import すれば必ずパフォーマンスされるわけではありません。
例えば Suspense によってファイル分割を行ったとしても、そのコンポーネントをページ初期読み込み時に render される場合は、追加でサーバーへリクエストする回数が増え、読み込むファイルも増えてしまいます。

逆に、Suspense が有効な例として、ページの下の方に位置する重いコンポーネントがある場合に、スクロール後に dynamic import されるようにしておくことで、ページ初期読み込み時に読み込む JavaScript ファイルを削減し、ページ読み込み速度が改善されます。Qiita でも、記事ページの下にあるコメント一覧は、Suspense によってスクロール後に読み込まれるようになっています。

# そして、React 18 の Suspense へ...

この記事を書いたきっかけは、Qiita社内での React新機能勉強会 です。そこで、React18 の Suspense の新機能の前に、React18以前の Suspense と lazy を使う方法を振り返りました。本記事はその際の資料を基に作成しています。

本記事では React 16.6 で追加された Suspense としての機能の紹介でしたが、React 18 では `lazy` を使った dynamic import だけでなく、一般的な非同期処理と Suspense を組み合わせることができるようになったらしいので、社内の React 勉強会で出てきたら、続きの記事を書こうと思います！

# 参考文献

- [Dynamic imports(ダイナミックインポート) - 現代の JavaScript チュートリアル](https://ja.javascript.info/modules-dynamic-imports)
- [import() - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/import)
- [Code Splitting | webpack](https://webpack.js.org/guides/code-splitting/)
- [Suspense - react.dev](https://react.dev/reference/react/Suspense)
[Python] logger実装


### loggerの実装
```
logger.py

from logging import getLogger, StreamHandler, INFO, Formatter


def main():
    logger = get_logger()

    logger.info("logger実装")
    // [INFO]2023-06-08 22:35:49,969-logger実装(logger.py)


def get_logger():
    logger = getLogger("log")
    handler = StreamHandler()
    handler.setLevel(INFO)
    logger.setLevel(INFO)
    logger.addHandler(handler)

    formatter = Formatter('[%(levelname)s]%(asctime)s-%(message)s(%(filename)s)')
    handler.setFormatter(formatter)
    return logger


if __name__ == "__main__":
    main()
```

### 他のclassでも使用する場合
```
test.py

logger = getLogger("log")

logger.info("logger test")
// [INFO]2023-06-08 22:35:49,969-read args(test.py)
```