OmniAICreator/Qiita-1.07M huggingface dataset:
imdb clone Part20(完)　13 search ability 2/2 検索結果のページを実装

# 概要
今回は検索後表示されるページを実装します。
下gifアニメは実装後の様子です。

![pppppppppppppnnnnn.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/46bbd636-71d3-6a4b-4d18-566f05643d8b.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"

# 実装のポイント
app/search/[searchTerm]/page.jsxを新規作成して検索結果のページを作ります。
pageが開かれる段階でTMDBのAPIを使い該当する映画を取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/57c40007-ffba-db9c-8194-1ea276719a00.png)


# コード部分
## app/search/[searchTerm]/page.jsx
```diff_jsx:page.jsx
import Results from "@/components/Results";

export default async function SearchPage({params}){
    const res = await fetch(`https://api.themoviedb.org/3/search/movie?api_key=${process.env.API_KEY}&query=${params.searchTerm}&language=en-US&include_adult=false`)
    if(!res.ok){
        throw new Error("Error fetching data")
    }

    const data = await res.json();

    const results = data.results

    return(
        <div>
            {results && results.length === 0 && (
                <h1 className="text-center pt-6">No results found</h1>
            )}
            {results && <Results results={results}/>}
        </div>
    )
}

```




# 参考

## TMDB API Search

https://developers.themoviedb.org/3/search/search-movies

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/43e1a770-a387-d441-d7b6-3d3bbd73ad60.png)


## その他



Udemy

githubコミット分

https://github.com/RYA234/imcbclone/commit/15267add8fdc482444ff6f43feb115e16c700da8
imdb clone Part19　13 AddSearch ability 1/2 検索コンポーネントを新規作成

# 概要
今回は検索機能のコンポーネントを作成します。

![ppppppppppppp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/2dd2d20e-1d62-d954-6c6b-3bca171688f6.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"

# 実装のポイント
以下画像は検索したときの処理です。
next.jsのdynamicRoutingを使って個別のページを実現しています。
検索後のページは未実装なので404エラーになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/533e497b-be26-dcd2-cb35-1d2f29684be9.png)



# コード部分
## SearchBox
```diff_jsx:SearchBox.jsx
"use client"
import { useState } from "react";
import { useRouter } from "next/navigation"  

export default function SearchBox() {
    const [search,setSearch] = useState("");

    const router = useRouter();
    function handleSubmit(e){
        e.preventDefault();
        if(!search) return;
        router.push(`/search/${search}`);
    }
  return (
   <form onSubmit={handleSubmit}
    className="flex max-w-6xl mx-auto justify-between items-center px-5">
        <input
            value={search} 
            onChange={(e)=>setSearch(e.target.value)}
            type="text" 
            placeholder="Search keywords..."
            className="w-full h-14 rounded-sm placeholder-gary-500 outline-none bg-transparent flex-1"
        />
        <button disabled={!search} type="submit" className="text-amber-500 disabled:text-gray-400">
            Search
        </button>
   </form>
  )
}
```


## layout
```diff_jsx:layout.jsx
import './globals.css'
import Header from '@/components/Header'
import Providers from './Providers'
import Navbar from '@/components/Navbar'
+import SearchBox from '@/components/SearchBox'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <Providers>
          {/* Header */}
          <Header />

          {/* Navbar */}
          <Navbar />

          {/* SearchBox */}
+          <SearchBox/>

          {children}
        </Providers>
      </body>
    </html>
  );
}
```




# 参考


## その他



Udemy

githubコミット分

https://github.com/RYA234/imcbclone/commit/51e3f78f90e9fc8cb7034f9767fefaf84760fdc6
異なる型を複数取る関数のテストを簡単に書く

複数の型（例えばintとかdoubleとか）を複数引数取る関数fに関するテストを書きたい時に、f(int, int), f(int, double), ... に関するテストを書くのは辛い（引数が3つ、4つ、。。。となったら死にそうになる）ので、まとめてテストする方法が必要になりました。
templateとenable_ifを使ってtupleに関する2重ループで実装してみました。(N重ループにするのは簡単ですね。)
C++11で実行できるようになっているはずです。

```c++
#include<iostream>
#include<cstdlib>
#include<tuple>

template <typename T1, typename T2>
void test_main(T1 &a, T2 &b){
  std::cout << typeid(a).name() << "(" << a << ") and " << typeid(b).name() << "(" << b << ") test" << std::endl;
  return;
}

template <typename T1, std::size_t J = 0, typename... Tp>
inline typename std::enable_if<J == sizeof...(Tp), void>::type
test2(T1& a, std::tuple<Tp...>& B){
  return;
}

template <typename T1, std::size_t J = 0, typename... Tp>
inline typename std::enable_if<J < sizeof...(Tp), void>::type
test2(T1& a, std::tuple<Tp...>& B){
  test_main(a, std::get<J>(B));
  test2<T1, J+1, Tp...>(a, B);
  return;
}

template <std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type
test1(std::tuple<Tp...>& A, std::tuple<Tp...>& B){
  return;
}

template <std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
test1(std::tuple<Tp...>& A, std::tuple<Tp...>& B){
  test2(std::get<I>(A), B);
  test1<I+1, Tp...>(A, B);
  return;
}

int main(void){
  size_t x1 = 1;
  int x2 = 2;
  float x3 = 3.0;
  double x4 = 4.0;

  auto A = std::make_tuple(x1, x2, x3, x4);
  auto B = A;

  test1(A, B);

  return 0;
}
```

実行結果：

```bash
m(1) and m(1) test
m(1) and i(2) test
m(1) and f(3) test
m(1) and d(4) test
i(2) and m(1) test
i(2) and i(2) test
i(2) and f(3) test
i(2) and d(4) test
f(3) and m(1) test
f(3) and i(2) test
f(3) and f(3) test
f(3) and d(4) test
d(4) and m(1) test
d(4) and i(2) test
d(4) and f(3) test
d(4) and d(4) test
```

test_mainを外に出すか引数にするかはお好みですね。
c++17以上だとconstexpr ifを使うと良いらしいです。（https://blog.browniealice.net/post/tuple_iterate/）

参考記事
https://stackoverflow.com/questions/1198260/how-can-you-iterate-over-the-elements-of-an-stdtuple
imdb clone Part18　Add Movie page 2/2 画像テキスト類を追加

# 概要
今回は映画の個別ページにテキストと画像を追加していきます。
以下gifアニメは実装後の様子です。

![zzzzzzzzzzzzzzzzzzzzzzzzzzzzxxxz.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/868660a7-2886-90a9-820a-7e159917eaeb.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"

# 実装のポイント
cssのflexを使ってディスプレイサイズによって縦並びか横並びになります。
ディスプレイのサイズが768px以上のときのレイアウトは横並びになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/4568398f-66e0-035f-19dc-8614b850f7ea.png)




ディスプレイのサイズが768px以下のときのレイアウトは縦並びになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/ae31e92f-25a3-eeb6-a10e-244c21716fe8.png)


# コード部分
## app/movie/[id]/page.jsx
```diff_jsx:page.jsx
import React from 'react'
+import Image from 'next/image';

async function getMovie(movieId){
    const res = await fetch(
        `https://api.themoviedb.org/3/movie/${movieId}?api_key=${process.env.API_KEY}`
    );
    return await res.json();
}

export default async function MoviePage({params}) {
  const movieId = params.id;
+  const movie = await getMovie(movieId);    
    return (
+    <div className="w-full">
+        <div className="p-4 md:pt-8 flex flex-col md:flex-row items-center content-center max-w-6xl mx-auto md:space-x-6">
+            <Image
+                src={`https://image.tmdb.org/t/p/original/${movie.backdrop_path || movie.poster_path}`}
+                width={500}
+                height={300}
+                className="rounded-lg"
+                style={{
+                    maxWidth:"100%",
+                    height:"100%",
+                }}
+                placeholder="blur"
+                blurDataURL="/spinner.svg"
+                alt="Movie poster"
+                ></Image>
+                <div className="p-2">
+                    <h2 className="text-lg mb-3 font-bold">
+                        {movie.title || movie.name}
+                    </h2>
+                </div>
+                <p className="text-lg mb-3">
+                    <span className="font-semibold mr-1">Overview</span>
+                    {movie.overview}
+                </p>
+                <p className="mb-3">
+                    <span className="font-semibold mr-1">Date Released</span>
+                    {movie.release_date || movie.first_air_date}
+                </p>
+                <p className="mb-3">
+                    <span className="font-semibold mr-1">Rating</span>
+                    {movie.vote_count}
+                </p>
+        </div>
    </div>
  );
}
```




# 参考

## css

### flex-col

https://tailwindcss.com/docs/flex-direction


https://developer.mozilla.org/ja/docs/Web/CSS/flex-direction




## その他

Udemy

https://www.udemy.com/course/react-js-tutorial/learn/lecture/36119304#content

githubコミット分

https://github.com/RYA234/imcbclone/commit/082b6272edeb73fa1c4557da9c2e949ed643081e
imdb clone Part17　 Add Movie page   1/2 動的ルーティングとデータ取得

# 概要

目次

https://qiita.com/RYA234/private/61143e3405c1f1c6f077

今回は映画毎のページを作ります。Next.jsのdynamic Routingを使って実装していきます。
以下gifアニメは個別ページのURLを開いている様子です。

![zzzzzzzzzzzzzzzzzz.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/cc2393fe-370f-78d2-3aae-79d6eb90e043.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"

# 実装のポイント
Next.jsの公式ドキュメントを参考にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/2fd287ae-9879-cf68-068e-16b85021b8e3.png)


# コード部分
## movie/[id]/page.jsx
```diff_jsx:Layout.jsx
import React from 'react'

async function getMovie(movieId){
    const res = await fetch(
        `https://api.themoviedb.org/3/movie/${movieId}?api_key=${process.env.API_KEY}`
    );
    return await res.json();
}

export default async function MoviePage({params}) {
  const movieId = params.id;
  const movie = await getMovie(movieId);
  console.log(movie.title);

    return (
    <div>
    </div>
  );
}
```




# 参考

next.js dynamic routing

https://nextjs.org/docs/pages/building-your-application/routing/dynamic-routes

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/a30882c3-2d02-6a62-fa82-b18934afc548.png)


## その他


githubコミット分

https://github.com/RYA234/imcbclone/commit/4eaf9f07f3a7ac30f3aa1ae27d353c5cf69791cd
imdb clone Part15　11 CardComponent   2/3カードコンポーネントの画像を実装

# 概要

目次

https://qiita.com/RYA234/private/61143e3405c1f1c6f077

今回はNext.jsのImageコンポーネントを使ってカードに画像を追加しています。
下画像は実装後の様子です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/2c0d030c-b2f1-de04-dae5-3a4007daf67a.png)



# 開発環境

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"

# 実装のポイント
Next.jsのドキュメントを参考にして実装します。
画像のURLは背景用のbackdrop_path（横長の画像）とPoster_path（縦長の画像）があり今回はbackdrop_pathを優先的に使うようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/696d4d4f-dba1-1317-4df8-24def13651f7.png)




# コード部分
## Card
```diff_jsx:Card.jsx
import React from 'react'
+import Link from 'next/link'
+import Image from 'next/image'

export default function Card({result}) {
  return (
    <div className="cursor-pointer sm:p-3 sm:hover:shadow-slate-400 sm:shadow-md rounded-lg sm:border sm:border-slate-400 sm:m-2 transition-shadow duration-200 group">
+      <Link href={`/movie/${result.id}`}>
-      {result.id}
+        <Image 
+         src={`https://image.tmdb.org/t/p/original/${
+            result.backdrop_path ||
+            result.poster_path
+         }`}
+         width={500}
+         height={300}
+         className="sm:rounded-t-lg
+         group-hover:opacity-80
+         transition-opacity
+         duration-200"
+         style={{
+             maxWidth:"100%",
+              height:"auto",
+         }}
+         placeholder="blur"
+         blurDataURL="/spinner.svg"
+         alt="image is not available"
+        ></Image>
+      </Link>
    </div>
  )
}
```


## next.config.js
```diff_jsx:nextconfig.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    appDir: true,
  },
+  images:{
+    domains:["image.tmdb.org"]
  }
}

module.exports = nextConfig

```




# 参考

## next Image

https://nextjs.org/docs/pages/api-reference/components/image

Prop

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/287ca570-fdcf-647e-cc14-3444ec75d402.png)



## その他

https://www.themoviedb.org/movie/238-the-godfather

API Response

https://developers.themoviedb.org/3/movies/get-movie-details

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/92830702-56be-907b-a7fa-0e53cc190507.png)



Udemy

https://www.udemy.com/course/react-js-tutorial/learn/lecture/36119296#overview

githubコミット分

https://github.com/RYA234/imcbclone/commit/427757d9d2badf9f78a6d69026ade775d21f4759
【TypeScript】@ts-ignoreと@ts-expect-errorの違い

## 共通点

以下のように記述するとどちらも次の行の型エラーを無視できます。  

```ts
// @ts-ignore
```

```ts
// @ts-expect-error
```

![スクリーンショット 2023-05-11 21.38.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/f9128db7-30da-633e-8747-34faeb9dc550.png)

画像のようなエラーが発生している場合に以下の画像のようにするとエラーが出なくなります。

![スクリーンショット 2023-05-11 21.38.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/1e4a188b-49f3-393f-9664-07ec0ede1419.png)
![スクリーンショット 2023-05-11 21.39.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/b018f1e2-6965-423f-b06d-b4393187d42f.png)

## 違い

次の行にエラーがない場合の挙動に違いがあります。  
`@ts-ignore`は何も起こらないのに対し、`@ts-expect-error`はエラーとなります。  

エラーのあった`<List />`を削除すると`@ts-expect-error`ではエラーが出ています。

![スクリーンショット 2023-05-11 21.40.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/cd100d54-a7d7-cc09-0104-6b1120585f61.png)
![スクリーンショット 2023-05-11 21.40.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/36dbcd58-aabb-9050-69fd-f2d3d12a3807.png)

## 参考

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-9.html#-ts-expect-error-comments
imdb clone Part13　10 読み込み処理を追加する

# 概要
目次

https://qiita.com/RYA234/private/61143e3405c1f1c6f07


今回は読み込み時のアニメーションを実装します。

以下gifアニメは読み込み処理が実行されている様子です。

![fffffffffff.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/2bfbb385-190a-be78-fdcc-2417b36b9f8d.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"

# 実装のポイント

loading-ioから　画像を用意します。

https://loading.io/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/3e3ec1e4-62ce-d05e-966c-5727b7bc495e.png)

loading.jsを新規作成します。next.js側の機能の模様。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/ccfa8268-d26e-f54a-1c84-474de306a8d4.png)



# コード部分
## loading
```diff_jsx:loading.jsx
export default function loading(){
    return(
        <div className="flex justify-center">
            <img className="h-96" src="spinner.svg" alt="loading..." />
        </div>

    )
}
```




# 参考
next.js Loading UI and Streaming

https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/1c9f8df5-6f84-8c3b-01f3-d40d71ddc342.png)


{next:{revalidate: 10000}}→　ISR(動的サイト作成）

https://nextjs.org/docs/app/api-reference/functions/fetch#optionsnextrevalidate

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/7f7358cc-83b7-2d4a-497e-ebc8f2c28c23.png)


## その他



Udemy

https://www.udemy.com/course/react-js-tutorial/learn/lecture/36119294#overview

githubコミット分


https://github.com/RYA234/imcbclone/commit/151096e64297c9f318cc19b87d736859ae917675
imdb clone Part11　8 fetching data 2/2　TMDBから取得したデータをブラウザ上で表示

# 概要
目次

https://qiita.com/RYA234/private/61143e3405c1f1c6f077

TMDBから取得したデータをブラウザ上で表示できるようにします。
以下gifアニメはTMDBから取得したデータをブラウザ上に表示している様子です。

![gggggggggggg.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/dd7c7981-c772-686f-176e-605192997c32.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"

# 実装のポイント
実装する上で難しい点は無いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/4b7575ef-31de-5ffc-b824-257949bce0b9.png)


# コード部分
## page
```diff_jsx:page.jsx
import { Inter } from "@next/font/google"
+import Results from "@/components/Results";
const API_KEY = process.env.API_KEY;


export default async function Home({searchParams}) {
  const genre = searchParams.genre || "fetchTrending";

  const res = await fetch(
    `https://api.themoviedb.org/3/${
      genre === "fetchTopRated" ? "movie/top_rated" : "trending/all/week"
  }?api_key=${API_KEY}&language=en-Us%&page=1`,
  {next:{revalidate: 10000}}
  );

  if(!res.ok){
    throw new Error("Failed to fetch data");
  }

  const data = await res.json();
-   console.log(data);
+  const results = data.results;

  return (
-    <h1 className='text-red-300'>HOME</h1>
+    <div>
+      <Results results={results} />
+    </div>
  )
}
```


## Result
```diff_jsx:Result.jsx
export default function Results({results}) {
  return (
    <div>
        {results.map((result) => (
                <div key={result.id}>{result.original_title}</div>
            ))}
    </div>
  );
}

```




# 参考





## その他



Udemy

https://www.udemy.com/course/react-js-tutorial/learn/lecture/36119286#content

githubコミット分

https://github.com/RYA234/imcbclone/commit/2749ac42b5c07b7a6bc8adb4dc58729b9cd0b0c5
TuringPi v1 （あまりに時間がかかって腐った）　氷河期編

## 旬を過ぎてしまった機材　
皆さん、rapsberry pi で遊んでますか？
というか、仕事で使ってますか？

2017-18年あたりはなんの問題もなく（というか知られていなくて）気楽に買っていた記憶があるんですが、2020年からの半導体不足のためCM3の入手性に関しては本当にとんでもないことになってしまいました。

## Turing PI v1 

私は2021年の２月初頭に、TuringPI v1 を買ったのです。本当に馬鹿でしたね。
もう少し待てば、CM4 を載せられる TuringPi v2 が出たのに。
こいつがなかなか待てど暮せど出荷されてこない。来ないんです。いやもうこれで心が折れかけてしまいます。
しかも肝心のCM3は、もうどのショップにも在庫なく、入荷待ちということがわかります。
そして図体に比べて、華奢な私の心が折れます。やるきどこいった。
なんだか2021年は忙しく、注文は見送ってなんとなんと2022年になりました。　

いや流石にこれではゴミになってしまう！　となって2022年6月にダメ元で "DIGIKEY" に　CM3を7枚注文します。これが来たのが2022年12月（うへー）

## DigiKey とダイエット (よくわからないつながり）
私のカラダもこの年の検診でついに引導を渡されてしまいます。血圧が150越えました。運動でもなんでもして痩せなければ死ぬだろうと。猛烈なダイエットが始まり、TuringPiのことなんてどっかいっちまいます。
とりあえずめちゃくちゃ自転車漕いでカロリーコントロールしてたら、11月までに15キロ痩せてダイエット計画は完全に軌道に乗ってしまいました。やったー！
そして12月になったら、忘れてたDIGI-KEYさんからメールが来て勝手に配達されてました。びっくりー！

コロナもひどかったし個人的な大変動を迎えて、もうほったらかしの基板は箱で眠り、やる気も何をしようとしていたのかもわからないひどい状況でしたが、せっかくCM3が来たのですから２年越しの計画がようやく動き出します。

基板だけで箱がないと嫌だと、SFX300W電源搭載 マイクロATXスリムケース 筐体に詰め込んでやります。何やら起動？せず？　CM3の扱いがまーた面倒くさくなってしまいました。

ということで、AT電源相当に化けさせる基板が必要になります。なんとまあ忙しく年を越してしまいました。
ainex アイネックスKM-02C [ATX 電源検証ボード]　が来たのが１月の半ば。２月を越えたら２年目。
またやる気が失われて、４ヶ月。ようやく５月になってあちこちが片付けられて来たので手を出してやりましたよ。

もう供給に対して需要がめちゃくちゃアンバランスなってしまったので、CM3って、手を出しているヒトは、PICOにくらべたらほとんど見かけない感じですよね。 なにかに付けて素人の私は、誰もやってない　usbbootでなにかするのが本当に億劫になってしまい、自分の勝手な希望で筐体に入れてしまったTuringPiの基板だけじゃあ、検証も出来ねえと思いまして、 Waveshare の　CM3/PoEベースを買ってしまいました・・・。
こいつで普通のRaspbian動かしたら、カメラ３個繋げられるとかそこそこ便利じゃん。
まあ、普通にRasPi 3Bだって、市場価格は倍ほど高くなってしまってます。セドリビジネスがあまりにひどくてDIGIKEYみたいな真面目なところでオーダ出してないと、めちゃくちゃ高いものを掴まされます。

まあ、WaveShareの基板で usbbootが出来て、eMMCに RPの64bit版も書き込めたしあ～よかった。
じゃねえや、 TuringPiで　k3s をやるんですよ私。

というところで、TuringPi v1 を買ったはいいがまさに氷河期を迎えていた顛末でした。
個人的には色々片付いたのでできるようになったという感じはありますね。

続きはちゃんと書きます（予定ではなくて、現在進行系）。
Laravel10 + Vue3.js環境にVue Router4を導入する

## はじめに
[laravel sailを使ってlaravel10 + vue3.js + postgresSQL環境を作る](https://qiita.com/riiiii/items/66f49c6f3a84de8bfa88) 
laravel sailで作成した環境にVue Router4を導入する方法を記載します。


### Vue Routerとは
Vue.js公式のルーターです。
- https://router.vuejs.org/introduction.html

## 環境
- WSL2
- DockerDesktop
- laravel10
    - sailと入力するだけでSailコマンドを実行できるように設定済
- Vue3.js

## インストール
以下を実行し、Vue Router4をインストールします。
```bash
sail npm install --save-dev vue-router@4
```

## 表示するvueファイルの作成
`resources/js`にて`views`ディレクトリを作成し、その中に試しに表示する`AboutView.vue`ファイルを作成します。

```AboutView.vue
<template>
    <h1>About</h1>
</template>

<script>
export default {
    name: "AboutView",
};
</script>
```

## index.jsファイルの作成
`resources/js`にて`router`ディレクトリを作成し、その中に`index.js`ファイルを作成します。

```index.js
import { createRouter, createWebHistory } from "vue-router";
import AboutView from "../views/AboutView.vue";

const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes: [
        {
            path: "/about",
            name: "about",
            component: AboutView,
        },
    ],
});

export default router;
```

## app.jsを修正し、Vue Routerを使えるようにする
`resources/js/app.js`を以下のように修正します。
```diff_javascript
import "./bootstrap";

import { createApp } from "vue";
import App from "./App.vue";
+ import router from "./router";

const app = createApp(App);

+ app.use(router).mount("#app");
- app.mount("#app");
```
## App.vueにrouter-viewを読み込ませる
`resources/js/App.vue`を以下のように書き換えます。

```App.vue
<template>
  <router-view />
</template>
```
## web.phpの修正
このまま、`http://localhost/about`へアクセスすると、404エラーとなってしまいます。
これは、laravelにて、`http://localhost/`以外のルーティングが設定されていないからです。

`routes/web.php`を以下のように書き換えます。

```web.php
Route::get('/{any}', function () {
    return view('app');
})->where('any', '.*');
```
whereメソッドを使用して正規表現で`any`を0文字以上とマッチするよう制約します。
（`/`以下に何もなくても、何かが入ってもOKとなる）

再度`http://localhost/about`へアクセスすると、`resources/js/views/AboutView.vue`で設定した通りに表示されました！

![スクリーンショット 2023-05-11 210803.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868789/199247ad-a83b-c791-fac9-7ee1bca7f71c.png)



## 参考
- [Vue Router 4基礎から理解(Composition API＋Vite環境)](https://reffect.co.jp/vue/vite-vue-router)
- [Laravel 10.x ルーティング 正規表現の制約](https://readouble.com/laravel/10.x/ja/routing.html#parameters-regular-expression-constraints)
SQLServerで複数行のデータをカンマ区切りで1行にする

## やりたいこと
group byで同じデータを集約するとき、複数行を1行の文字列としてまとめたい。
GROUP_CONCAT や ARRAY_TO_STRING のようなことをSQLServreで実装したい。

## 方法
STRING_AGG 集計関数を使うとできそう。

STRING_AGG (Transact-SQL) - SQL Server | Microsoft Learn
https://learn.microsoft.com/ja-jp/sql/t-sql/functions/string-agg-transact-sql

### やってみる

```sql:TBL
Bunrui Col1
------ ----------
精肉     1:豚肉
精肉     2:牛肉
精肉     3:鶏肉
精肉     4:合挽
青果     1:トマト
青果     2:りんご
青果     3:きゅうり
```


```sql:STRING_AGG 集計関数 のサンプル
SELECT
	 TBL.Bunrui
	,STRING_AGG( CONVERT(VARCHAR(max), TBL.Col1), ',') AS Result
FROM
	(
			SELECT '精肉' AS Bunrui, '1:豚肉' AS Col1
	UNION	SELECT '精肉' AS Bunrui, '2:牛肉' AS Col1
	UNION	SELECT '精肉' AS Bunrui, '3:鶏肉' AS Col1
	UNION	SELECT '精肉' AS Bunrui, '4:合挽' AS Col1
	UNION	SELECT '青果' AS Bunrui, '1:トマト' AS Col1
	UNION	SELECT '青果' AS Bunrui, '2:りんご' AS Col1
	UNION	SELECT '青果' AS Bunrui, '3:きゅうり' AS Col1
	) AS TBL
GROUP BY
	TBL.Bunrui
;

Bunrui Result
------ ------------------------------
精肉     1:豚肉,2:牛肉,3:鶏肉,4:合挽        
青果     1:トマト,2:りんご,3:きゅうり               
```

### 集計関数内の並び替え
STRING_AGG の後ろに WITHIN GROUP を追加。

```sql:STRING_AGG 集計関数 のサンプル (降順指定)
SELECT
	 TBL.Bunrui
	,STRING_AGG( CONVERT(VARCHAR(max), TBL.Col1), ',') WITHIN GROUP (ORDER BY TBL.Col1 DESC) AS Result
FROM
	(
			SELECT '精肉' AS Bunrui, '1:豚肉' AS Col1
	UNION	SELECT '精肉' AS Bunrui, '2:牛肉' AS Col1
	UNION	SELECT '精肉' AS Bunrui, '3:鶏肉' AS Col1
	UNION	SELECT '精肉' AS Bunrui, '4:合挽' AS Col1
	UNION	SELECT '青果' AS Bunrui, '1:トマト' AS Col1
	UNION	SELECT '青果' AS Bunrui, '2:りんご' AS Col1
	UNION	SELECT '青果' AS Bunrui, '3:きゅうり' AS Col1
	) AS TBL
GROUP BY
	TBL.Bunrui
;

Bunrui Result
------ ------------------------------
精肉     4:合挽,3:鶏肉,2:牛肉,1:豚肉        
青果     3:きゅうり,2:りんご,1:トマト    
```
@EnvironmentObjectについて基本を学ぼう

SwiftUIのEnvironmentObjectは、ビュー階層全体で共有されるデータを提供するための強力なツールです。これを用いることで、異なるビュー間でデータを簡単に共有することができます。

### 1. 共有するデータを準備する
まず、共有したいデータを保持するクラスまたは構造体を作成します。このクラスや構造体は ObservableObject プロトコルに準拠する必要があります。これにより SwiftUI はデータの変更を検知し、ビューを更新できるようになります。

以下に一例を示します：
```swift
import SwiftUI

class UserData: ObservableObject {
    @Published var username = "User"
    @Published var isLoggedIn = false
}
```

ここで、@Published プロパティラッパーは、その変数が変更されるたびにオブジェクトが更新を発行することを示します。

### 2.EnvironmentObject をビューに注入する
EnvironmentObject を使用するには、それを最上位のビューに注入する必要があります。通常、これはアプリケーションのエントリーポイント、つまり SwiftUI App の body プロパティで行われます。

```swift
@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(UserData())
        }
    }
}
```
### ３. ビューで EnvironmentObject を使用する
最後に、EnvironmentObject を使用するビューで、@EnvironmentObject プロパティラッパーを用いてそのオブジェクトを取得します。

```swift
struct ContentView: View {
    @EnvironmentObject var userData: UserData

    var body: some View {
        VStack {
            Text("Hello, \(userData.username)!")
            
            Button(action: {
                userData.isLoggedIn.toggle()
            }) {
                Text(userData.isLoggedIn ? "Log out" : "Log in")
            }
        }
    }
}
```

以上が基本的な使い方です。ただし注意点として、ビューが EnvironmentObject にアクセスするたびに、そのオブジェクトが既にビューの環境に存在することを期待しています。もし存在しない場合、ランタイムエラーが発生します。

EnvironmentObject をうまく使用すると、アプリ全体で状態を共有し、同期することが非常に容易になります。

最初にこれを学んだ時、「全てもうこれでいいじゃん」って思いましたがデメリットもあります。

### デメリット

１.明示的な依存関係が不明確: EnvironmentObjectはグローバルにアクセス可能であり、それによってビューとそのデータの依存関係が明確でなくなる可能性があります。ビューが具体的にどのデータに依存しているかを理解するためには、ソースコード全体を調べなければならない場合があります。

2.テストの困難さ: EnvironmentObjectはテストをより困難にする可能性があります。ビューがEnvironmentObjectに強く依存している場合、そのビューを単独でテストするためには、適切なEnvironmentObjectを設定する必要があります。これは、特に大規模なアプリケーションや多くの依存関係があるアプリケーションでは、テストの設定が複雑になる可能性があります。

3.ビュー間の疎結合性の欠如: EnvironmentObjectはビュー間の疎結合性を損なう可能性があります。一つのビューが変更されると、それがEnvironmentObjectの状態を変更する可能性があるため、他の全てのビューが影響を受ける可能性があります。これは予期しないバグを引き起こす可能性があります。

4.ランタイムエラー: EnvironmentObjectはビュー階層に明示的に追加されていなければなりません。もしビューがEnvironmentObjectを期待しているのに、それが存在しない場合、アプリはランタイムエラーを引き起こしクラッシュします。

ざっと調べた感じ以上のようなデメリットが挙げられるようです。
これらの欠点を考慮に入れて、最適な状態管理戦略を選択することが重要です。EnvironmentObjectは強力なツールである一方で、必要に応じて他の状態管理ツール（例えばState、Binding、ObservedObjectなど）と組み合わせて使用することが良いでしょう。
【Windowsコマンド】リモート接続先のPCが起動しているかを確認する方法

■目的
リモートデスクトップ接続で作業をする際に、接続先にアクセスできるかをpingコマンドで確認する方法を記載。
※想定されるケースの一例
・突然リモート接続先にログインできなくなった場合

■参考にしたURL
https://atmarkit.itmedia.co.jp/ait/articles/0012/01/news002.html

■前提条件
所属先の規定や以下に基づいてリモート接続できるようにパソコンを設定済であること
https://josysnavi.jp/2023/remote_desktop_connection_solution

■コマンド
pingの後ろはリモート接続先を指定し、いずれかのコマンドを使うこと
'---------------------
ping リモート接続先のコンピュータ名
ping ipアドレス
'---------------------
※「リモート接続先のコンピュータ名」とは以下赤枠を指す
![pingに入力するコンピュータ名.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917622/5286ac6f-45c0-1efb-eacd-84b96bd27dc8.png)


■実行結果
リモート接続「できる」場合は以下のようになる
![リモート接続先が「起動している」場合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917622/6bc035f1-9cdf-fc7f-037c-709e9e7064a2.png)

リモート接続「できない」場合は以下のようになる
![リモート接続先が「起動していない」場合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917622/2cb2c538-c229-e17a-e20a-bd9f8329dbed.png)
【SwiftUI】貞子が出てきそうなUIを作成する

# はじめに
貞子が出てきそうなUIをSwiftUIで作成してみます。

# 完成形
![simulator_screenshot_398401BE-05A8-4C3C-843D-42AFFD202FB8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/429d29f3-38cc-4e55-a4d9-b7f22367df8d.png)

# 実装
```swift
import SwiftUI

struct ColorNoiseView: View {
    let size: CGSize
    
    var body: some View {
        let colors = (0..<Int(size.width * size.height)).map { _ in
            Color(red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1))
        }
        GeometryReader { geometry in
            ZStack {
                ForEach(0..<Int(size.width * size.height), id: \.self) { index in
                    Rectangle()
                        .fill(colors[index])
                        .frame(width: 1, height: 1)
                        .position(CGPoint(x: CGFloat(index % Int(size.width)), y: CGFloat(index / Int(size.width))))
                }
            }
        }
        .frame(width: size.width, height: size.height)
    }
}
```

# 使い方
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        ColorNoiseView(size: .init(width: 300, height: 300))
    }
}
```

# おわり
作ってる途中に貞子出てきました
bindParam()とbindValue()とは

# bindParam()とbindValue()とは

bindParam()とbindValue()は、PHPのPDOクラスで使用されるデータバインドのメソッドです。

両方とも、プリペアドステートメント内のプレースホルダーに値をバインドするために使用されます。

以下は、それぞれのメソッドの長所と短所、そして使い分けについての説明です。

### **bindParam()の長所と短所**

### 長所

- 値が変わっても同じステートメントを再利用できる
- パラメータの参照渡しが可能で、メモリ効率が良い
- カラムのバインドに利用可能

### 短所

- パラメータ値を変更するには、bindValue()よりも手順が多い
- パラメータ値を直接バインドすることはできないため、プロシージャの実行に向いていない

### **bindValue()の長所と短所**

### 長所

- パラメータ値を変更する手順が容易である
- 直接値をバインドすることができ、プロシージャの実行に向いている

### 短所

- バインドされた値が変わると、同じステートメントを再利用することができない
- パラメータのコピーが作成されるため、メモリ効率が悪い
- カラムのバインドには利用できない

### **使い分け**

- 値を変更する可能性がある場合や、複数の値を同じステートメントで再利用する場合には、bindParam()を使用することが適切です。
- パラメータ値を変更する必要がなく、ステートメントを再利用する必要がない場合には、bindValue()を使用することが適切です。
- カラムのバインドが必要な場合には、bindParam()を使用する必要があります。

# 用語解説

### **データバインド**

データバインドとは、プログラムで使用される変数やパラメーターに、データベース内のカラムや値を関連付けることを指します。データバインドを使用することで、プログラム内でデータベースの値を操作することができます。データバインドには、bindParam()やbindValue()といったメソッドが用意されています。

### **プリペアドステートメント**

プリペアドステートメントとは、SQLステートメントのテンプレートを事前に準備しておくことで、実行時のパフォーマンスを向上させる機能です。プリペアドステートメントを使用することで、SQLインジェクション攻撃を防ぐこともできます。プリペアドステートメントは、prepare()メソッドを使用して作成します。

### **プレースホルダー**

プレースホルダーとは、SQLステートメント内の値が入る部分を、名前や記号などで表したものです。プレースホルダーを使用することで、SQLインジェクション攻撃を防ぐことができます。プレースホルダーは、通常「?」や「:name」といった形式で表されます。

### **プロシージャ**

プロシージャとは、データベース内で実行される手続きのことを指します。プロシージャは、通常ストアドプロシージャとも呼ばれます。プロシージャは、一連のSQLステートメントをまとめたもので、プログラムのように構成されます。プロシージャを使用することで、複雑な処理を簡単に実装することができます。プロシージャは、CALLステートメントを使用して呼び出します。
いろいろなプログラミング言語でHelloWorldプログラムを実装してみた結果をまとめてみた

# Elixir
https://qiita.com/nori-channel/items/b01f947240deb27b7702
# Dart
https://qiita.com/nori-channel/items/aba4631c6c9769325888
# Prolog
https://qiita.com/nori-channel/items/5c1e9481ee194fc5d02d
# Clojure
https://qiita.com/nori-channel/items/837fb1d1dc7ae07af292
# Julia
https://qiita.com/nori-channel/items/9c9c4b629d4c9d2b4a3b
# Perl
https://qiita.com/nori-channel/items/a62b68ad14ae3077b535
# Scala
https://qiita.com/nori-channel/items/a6fc93f0d11cc369c02d
# Haskell
https://qiita.com/nori-channel/items/572a1356707ded90cb74
# GFortran
https://qiita.com/nori-channel/items/6c76c9c6c82fe7580ea5
# clisp
https://qiita.com/nori-channel/items/213fcf4cbc48b2e0dc22
# Python
https://qiita.com/nori-channel/items/094f1df0f9c3a20f2fef
# Java
https://qiita.com/nori-channel/items/f3826c65cc1c02ca45d9
# PHP
https://qiita.com/nori-channel/items/b1dbf7b163a5b2e0b08c
# C
https://qiita.com/nori-channel/items/f29d714896c3536ce752
# C++
https://qiita.com/nori-channel/items/b78e1b2654df8ab637ed
# Rust
https://qiita.com/nori-channel/items/b3be5c4969f214ac7677
# Vue.js
https://qiita.com/nori-channel/items/02d9dcd8c205aac10807
# React
https://qiita.com/nori-channel/items/1555ba6f100337e8309b
# TypeScript
https://qiita.com/nori-channel/items/8a97b3b6b797c6cfd0ad
# Kotlin
https://qiita.com/nori-channel/items/c7e89792a95ce3422711
# Swift
https://qiita.com/nori-channel/items/0c99a54f161f9dcb2bfd
# JavaScript
https://qiita.com/nori-channel/items/2f5e6b84e4c8f224a229
# Ruby
https://qiita.com/nori-channel/items/f111b37d35839deb90aa
# Node.js
https://qiita.com/nori-channel/items/ae5539aa847e80d1e113
# Go
https://qiita.com/nori-channel/items/67c91a0423c88cc054ac
python maya export fbx

```python
import pymel.core as pm
import maya.mel as mel
from maya import cmds

def ExportFbx(file_path):
    if not cmds.pluginInfo('fbxmaya', q=True, loaded=True):
        pm.loadPlugin("fbxmaya")

    mel.eval("FBXProperty Export|IncludeGrp|Geometry|BlindData -v false")

    fbx_export_options = [
        ("-s",),  # Selection Only
        ("-v", "FBX201400"),  # FBX Version
        ("-f", "MotionBuilder.fbx"),  # File Name
        # ("-es",),  # Embed Textures
        # ("-ea",),  # Embed Media
        ("-fr", "30"),  # Frame Rate
        ("-q",),  # Quiet Mode
        ("-p", "256"),  # Optimization Level
        # ("-axisUp", "y"),  # Up Axis
        # ("-axisFront", "z"),  # Front Axis
        ("-a", "model", "camera"),  # Animation Only (Model and Camera)
        ("-enablePointCache",),  # Point Cache
        ("-enableSampling",),  # Animation Sampling
        ("-stripNamespaces",),  # Strip Namespace
        ("-filterType", "AnimCurve"),  # Filter Type
        # ("-fcp", "0"),  # Bake Start Time
        # ("-fcp", "0"),  # Bake End Time
        ("-tp", "0"),  # Use Default Take
        ("-simplify", "1"),  # Simplify Animation Curves
    ]

    # Export the FBX file with the options
    cmds.file(file_path, force=True, options=";".join([str(opt) for opt in fbx_export_options]), type="FBX export", exportSelected=True)
```
pythonで@overloadを使って複数の引数の型に応じて返り値を変える

# 異なる型や引数を持つ関数を型ヒントを使って定義したい！

複数の異なる型や引数を持つ関数を型ヒント付きでしかもPythonで作ることは簡単ではありません。`Union`  や `TypeVar`　の合併型や変数型では対応で対応できるものであればいいですが、そんなに世の中は甘くないようです。

では、そんな関数を定義するためにはどうしたらいいのか？

**そこで、使われるのが、`typing` モジュールの `@overload` デコレータです！**

# 実例

この例では、**`add`** 関数をオーバーロードしています。最初の2つのデコレータで異なる型の引数と戻り値を定義し、その後の通常の関数定義では、具体的な実装を提供しています。

この場合、**`add`** 関数は整数型の引数を受け取り整数を返すバージョンと、浮動小数点数型の引数を受け取り浮動小数点数を返すバージョンの2つが定義されています。適切な型の引数を渡すことで、適切なバージョンの関数が呼び出されます。

```python
from typing import overload

@overload
def add(a: int, b: int) -> int:...

@overload
def add(a: float, b: float) -> float:...

def add(a, b):
    return a + b
```

以下は、この例を使用した実行例です。

```python
print(add(1, 2))       # 整数の足し算: 3
print(add(1.5, 2.5))   # 浮動小数点数の足し算: 4.0
```

ただし、Pythonでは **`@overload`** デコレータによる静的な型チェックや実行時のオーバーロード解決は行われません。このデコレータは主に型チェッカーやIDEなどのツールが関数のシグネチャを認識しやすくするために使用されます。実行時のオーバーロード解決や型チェックは、通常の条件分岐や型の検査によって行われます。

## `@overload` の注意点

`@overload` は、Pythonの実行時には無視されます。つまり、引数の型や数に応じた処理を実行するためには、実際にその関数を呼び出す必要があります。

また、`@overload` を使用する場合は、関数本体には処理を書いてはいけません。`@overload` は、あくまで関数のオーバーロードを定義するためのデコレーターであり、実際の処理はオーバーロードされた関数の本体に記述する必要があります。

## より実践的なコード

**`typing`** モジュールの **`@overload`** デコレータを使用して、複数の引数の型に応じた挨拶文を生成する関数を定義しています。

```python
from typing import overload

@overload
def generate_greeting(name: str) -> str:
    pass

@overload
def generate_greeting(name: str, age: int) -> str:
    pass

def generate_greeting(name, age=None):
    if age is None:
        return f"Hello, {name}!"
    else:
        return f"Hello, {name}! You are {age} years old."

# テストケース
print(generate_greeting("Alice"))   # "Hello, Alice!"
print(generate_greeting("Bob", 25)) # "Hello, Bob! You are 25 years old."
```

この例では、**`generate_greeting`** 関数をオーバーロードしています。最初のデコレータでは、**`name`** 引数のみを受け取り、文字列を返すバージョンを定義しています。2番目のデコレータでは、**`name`** 引数と **`age`** 引数を受け取り、文字列を返すバージョンを定義しています。

通常の関数定義の部分では、引数のデフォルト値を使用してオプションの **`age`** 引数を実現しています。引数の有無に応じて、適切な挨拶文を生成しています。

テストケースとして、**`generate_greeting`** 関数を呼び出して異なるパターンを試しています。適切なバージョンの関数が呼び出され、期待通りの挨拶文が生成されることを確認しています。

このように、**`@overload`** デコレータを使用することで、関数のオーバーロードを定義し、型ヒントを活用して異なる引数の組み合わせに対応する柔軟性を持った関数を作成できます。

# @overloadとの出会い

そもそも、なんでこんな記事を書いたかというと、

機械学習系の論文や、パッケージのソースコードなんかを眺めているとよく、@overloadというデコレーターを最近になり見るようになりました。

なんのコードなんだかわからないけどあまり本筋に関係ないので、後回しにしていた理解のために今回はちゃんと記事にしてみました。

`@overload`は、Pythonで関数の引数の型に応じて異なる処理を行いたい場合によく使われるようです。特に、引数の型や数が複雑な場合や、引数の組み合わせによって戻り値が変わるような関数での使用が一般的です。また、型ヒントを利用して、より明確かつ堅牢なコードを書くことができるようになるようです。
DockerでAstroを立ち上げようとしたらエラーが出た

# この記事について
[こちらのサイト](https://qiita.com/mayomayo/items/6e640a067b2cd6592bcf) を参考に、Docker環境でAstroを立ち上げようとしましたが、依存関係のインストール中にエラーが発生してしまいました。
忘れないようにエラー内容と解決方法を記載しておきます。

### 環境
```
MacOS Big Sur: version 11.5.1
Docker Version: 20.10.24
```
## 準備
参考サイトどおり、必要なフォルダとファイルを作成する
```
astro-app
├─ app
├─ Dockerfile 
└─ docker-compose.yml
```

## 手順
1. Dockerコンテナの立ち上げ
    ```
    $ cd astro-app
        → astro-appまで移動
    $ docker-compose build 
        → image構築
    $ docker-compose up -d
        → コンテナの構築・起動
    $ docker-compose ps
        → コンテナ名の確認
    ```


1. 作成したコンテナに入る
    ```
    docker exec -it astro-app sh
    ```
1. コンテナ内でnpmを使用し、Astroの新規プロジェクトを作成
    ```
    npm create astro@latest
    ```
1. Houstonからの質問に答えていく
    -  Where should we create your new project?
        - app内のどこにプロジェクトを作りたいか
        →とりあえず`test`と入力
    - How would you like to start your new project?
        - 新しいプロジェクトのスタートはどうするか
        →チュートリアル通りにemptyを選択
    - Install dependencies?
        - 依存関係をインストールするか
        →yesを選択 : **ここでエラー発生**

## 発生したエラー内容

```
npm ERR! code 1
npm ERR! path /project
npm ERR! command failed
npm ERR! command sh -c create-astro .

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2023-04-20T05_27_02_814Z-debug-0.log
```

調べてみたところ、`/usr/src/app`内にjsonファイルがないため、依存関係がインストール出来ないという内容でした。


## 解決方法
1. `How would you like to start your new project?`という質問に答えた段階で、`Where should we create your new project?`で作成したフォルダ内に出来たAstro一式を、`/usr/src/app`へ移動させておく
![スクリーンショット 2023-05-11 17.45.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2534018/8c699cc0-1e5a-548e-4eb3-25d970e5f2ea.png)

## その後の手順
1. 引き続きHoustonからの質問にyesで答えていく
    - Install dependencies?
        - 依存関係をインストールするか
        →yesを選択 : 問題なくインストールが完了する
    - Do you plan to write TypeScript?
      - TypeScriptを書く予定はあるか
      →yesを選択
    - Initialize a new git repository?
      - 新しい git リポジトリーを初期化するか
      →yesを選択
1. 解答し終わったら下記コマンドを入力
    ```
    npm run dev -- --host 0.0.0.0
    ```
1. localhost:3000 へアクセスすれば、表示される


## 参考資料
https://qiita.com/mayomayo/items/6e640a067b2cd6592bcf

https://zenn.dev/k_neko3/articles/a0d874ab2af1eb
【Django】IntegerFieldのmax_lengthは11から変えられるのか？エラー「'max_length' is ignored when used with IntegerField」について

# 概要
* djangoでは`IntegerField`はデフォルトで11で、これは変更できない？と聞いたので、実際に検証してみました。
* 結論、整数値には「文字列の長さ」に関する制限はなく、あくまで「最大値」に関する制限があるということになります。

# IntegerFieldとは？
* `IntegerField` = データベースに保存される整数値を表すためのフィールド(Pythonのint型と対応)。
* Djangoの`models.py`で定義する際に使用されます。
* 検証しようと思ったのは、以下の記事。`IntegerField`には`max_length`を設定しても効果がない、という記述がありました。
    * [Documentation not clear about the effects of max_length for IntegerField](https://code.djangoproject.com/ticket/22637)

# `max_length=10`でマイグレートするとどうなる？
* 試しに、`max_length`オプションに以下の3パターンで実施することにしました。
    * `max_length=11`
    * `max_length=10`
    * `max_length`記載なし

### `max_length=11`の場合
* `max_length=11`を指定した状態でマイグレートしたら以下のメッセージが返ってきました。

```
System check identified some issues:

WARNINGS:
customer.Customer.id: (fields.W122) 'max_length' is ignored when used with IntegerField.
        HINT: Remove 'max_length' from field
```

* ご丁寧に、`max_length`を消してくださいというヒントまで記載しています。。。
* DBを見に行くと、もちろんですが`int(11)`となっています。

### `max_length=10`の場合
* やはり同じエラーメッセージが出ます。
* DBを見に行くと、、`int(11)`となっています。これで、デフォルトで`11`であり、変更ができないことがわかりました。

### `max_length`記載なしの場合
* 勿論エラーメッセージは表示されません。
* DBを見に行くと、`int(11)`となっています。確実ですね。

# 検証結果
* 以上の検証から、デフォルトで11桁であり、そこから変更ができないことがわかります。
* MySQLにおけるINT型の最大桁数は11桁。DjangoがMySQLをサポートするためにデフォルトで11桁にしたのでしょう。

### 整数値の場合は`min_value`と`max_value`を使え
* 冒頭でも記載したように、そもそも`max_length`オプションは文字列フィールド（`CharField`や`TextField`など）で使用されるオプションです。
* 整数値を保存する`IntegerField`の場合、`min_value`と`max_value`オプションがあり、これらを使うことで、フィールドに許可される値の範囲を制限します。
* ちなみにMySQLでは、INTEGERフィールドに保存できる最大値は`2147483647`（32ビット符号付き整数型で表現できる最大値）となっています。あれ、10桁では？と思ったが、マイナスも入るので`-2147483648`を考慮しているっぽい。
    * 正確にいうと、、、`-2147483648`は10桁の整数。符号を入れると11桁の桁数が必要、という意味

### デフォルトの最大桁数より大きいデータが入った場合は？
* MySQLではデフォルトで値の範囲チェックを行なってくれず、自動で丸めるようになっているようです。確かにテストで適当に999...とか以前入れたデータを突っ込んだら、この数値がたくさん出てきた記憶があります。そういう意味だったのか。
    * [MySQLのintの最大値を超えた場合の挙動はどうなるか？](https://qiita.com/a-nishimura/items/929f5082c72870c9a263)

### デフォルトの最大桁数より大きくしたい場合は？
* デフォルトでは21億までidを触れるわけですが、それを超える！という場合は、`BigIntegerField`を使用することで解決できます。
* 最大で20桁の整数値を保存することができるとのこと。

### 小数点以下を含むフィールドであれば最大桁数を指定できる
* `DecimalField`、`FloatField`、`DecimalRangeField`、`FloatRangeField`のような小数点以下を含むフィールドであれば、`max_digits`というオプションで数字部分の最大桁数を、`decimal_places`で小数部分の桁数の指定できます。
* 例えば、以下の場合は、整数部分は6桁が最大の有効値となります。最大値は999999.99です。

```models.py
    menseki = models.DecimalField(
        db_column='menseki',
        default=0,
        null=True,
        max_digits=8,
        decimal_places=2)
```

* 桁数オーバーの場合、`decimal.InvalidOperation`という例外が発生します。
扇風機とエアコンの違い

## 結論
温度調節を間違えたり、電気代を気にしなければ、エアコンが良い。

## 内容
扇風機とエアコンは、暑い時に部屋の中を快適にするための家電です。それぞれの仕組みと、体を冷やす原理について説明します。

扇風機の仕組みは、回転する羽根が空気を吸い込み、その空気を羽根の逆側から吹き出すことで風を起こします。この風は、周囲の空気を動かし、体表面の汗が蒸発することで体を冷やします。
エアコンは、冷房と暖房の両方ができる家電です。エアコンの仕組みは、室外機と室内機があって、室外機で外の熱を取り込み、室内機で冷たい空気を出すことで部屋を冷やします。体が暑いと感じた時には、エアコンで室温を下げることで体を冷やすことができます。

## メリットとデメリット
扇風機のメリットは、手軽に使えることと、電気代が比較的安いことです。一方、デメリットは、部屋の中を風で動かすため、涼しさを感じられる範囲が限られることや、空気中の埃や花粉を撒き散らすことがある点です。
エアコンのメリットは、部屋全体を快適に保てることや、空気を清潔に保てる点です。一方、デメリットは、使用する際の電気代が高いことや、使用しない時に室内機にたまった水滴がカビや菌を発生させることがある点です。

体を冷やす原理に関しては、扇風機は汗を蒸発させることで体を冷やし、エアコンは室温を下げることで体を冷やします。ただし、エアコンで過度に部屋を冷やすと、体調を崩すことがあるので、室温は28度前後に保つようにすると良いでしょう。また、エアコンは節電機能や、省エネ設計のものがありますので、適切に使うことで電気代の節約につながります。

## 補足

扇風機は、風を送ることで部屋の中の熱を拡散させ、体表面の水分が蒸発することで体を冷やします。この効果は、周囲の空気の動きが必要なため、扇風機は風を送る方向や角度によって効果が変わります。例えば、扇風機を直接向けると、風によって体表面の水分が急速に蒸発し、冷え過ぎてしまうことがあるので、体に向けすぎないように注意しましょう。逆に、風が全く届かなければ、同じ部屋で扇風機を回しても体は冷えることがなく、暑くままです。

一方、エアコンは、冷房機能を使用する場合、室外機で外気を取り込み、室内機でその空気を冷やし、送風することで部屋を冷やします。断熱膨張、断熱圧縮という原理で空気を温めたり、冷やしたりしています。また、エアコンは室温を一定に保つことができるため、季節や天候に関係なく快適な環境を作ることができます。

ただし、エアコンは過剰な使用や冷房過剰によって、体調不良を引き起こすことがあります。冷房を効かせ過ぎると、体温調整機能が低下してしまい、体内の水分量が減少して脱水症状を引き起こす可能性があるため、適度な温度管理が必要です。
以上のように、扇風機とエアコンは、それぞれにメリットとデメリットがあります。どちらを使う場合でも、適切な使い方をすることで、快適な生活を送ることができます。
imdb clone まとめ　Part11-20（完）

# 説明
IMDbのクローンサイトを作ります。
https://www.imdb.com/


# 参考にしたUdemyの講座

https://www.udemy.com/course/react-js-tutorial/learn/lecture/36119304?start=75#overview

# 一覧

## Part11　8 fetching data 2/2　TMDBから取得したデータをブラウザ上で表示

![gggggggggggg.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/dd7c7981-c772-686f-176e-605192997c32.gif)

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

## Part12　9 APIキーが一致しないときエラー画面を出す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/0a2ce6ea-b42a-2e70-9bfe-5dd014254c29.png)

https://qiita.com/RYA234/items/59006e45e6e31813e976


## Part13　10 読み込み処理を追加する

![fffffffffff.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/2bfbb385-190a-be78-fdcc-2417b36b9f8d.gif)

https://qiita.com/RYA234/items/88ff290e86eb90424e3b


## Part14　11 CardComponent   カードコンポーネント新規作成　idのみ表示

![zzzzzzzzzzzzzzzzz.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/fc9343ce-99d0-a3e8-6d5d-bcd137a395f8.gif)

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


## Part15　11 CardComponent   2/3カードコンポーネントの画像を実装

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/2c0d030c-b2f1-de04-dae5-3a4007daf67a.png)

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


## Part16　11 CardComponent   3/3 テキスト系をを実装　スクロールバーが出ないようにする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/1e3af8ba-6d07-81d4-3a5f-4794f54361ea.png)

https://qiita.com/RYA234/items/4d689512199b688132c6

## Part17　 Add Movie page   1/2 動的ルーティングとデータ取得

![zzzzzzzzzzzzzzzzzz.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/cc2393fe-370f-78d2-3aae-79d6eb90e043.gif)

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

## Part18　Add Movie page 2/2 画像テキスト類を追加

![zzzzzzzzzzzzzzzzzzzzzzzzzzzzxxxz.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/868660a7-2886-90a9-820a-7e159917eaeb.gif)


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

## Part19　13 AddSearch ability 1/2 検索コンポーネントを新規作成

![ppppppppppppp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/2dd2d20e-1d62-d954-6c6b-3bca171688f6.gif)


https://qiita.com/RYA234/items/14b14d90aea89aaf7520

## Part20(完)　13 search ability 2/2 検索結果のページを実装


![pppppppppppppnnnnn.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/46bbd636-71d3-6a4b-4d18-566f05643d8b.gif)

https://qiita.com/RYA234/items/049963bb13b5fcf8450e
Goの基本

## 初めに
 何もわからない状態からGoを勉強することになったので学んだことを備忘録として残します。

## buildとrunの違い
プログラムを実行するときにgo buildを使うとコンパイルされてバイナリファイルが生成される。go runの場合はコンパイルから実行まで行ってくれる。

## パッケージとは
コードをまとめる単位のこと。必ずmainパッケージが存在する必要がある。また、mainパッケージの中にmain.goが入っている必要がある。パッケージで定義した関数、グローバル変数、定数などをパッケージ外で使いたい場合は名前を大文字で始める必要がある。小文字で始まるものを外から使おうとするとエラーが出る。

## モジュールとは
パッケージの集まりでパッケージの依存関係を管理することができる。ルートフォルダにgo.modファイルを作ってモジュールを定義する。
【メモ】KeyCloakのキャッチアップで重要そうな項目


- Realm：アプリケーションのセキュリティ境界を定義するコンテナ
- Client：KeyCloakに認証を委任するアプリケーション
- User：認証を受けるユーザ
- Role：ユーザに割り当てる権限
- Group：ユーザをグループ化して管理するためのコンテナ
- Flow：認証・認可フローを定義する構成要素
- Identity Provider：外部の認証サービス（SAML, OAuth2.0）との連携を設定する
- Theme：KeyCloakの見た目を変更するテーマ
- Script：イベントドリブンのフックとして動作するJSのコード
- Credential：ユーザの認証情報（PWやクライアントシークレット）
- Authenticator：ユーザ認証をカスタマイズするための構成要素
- Federation：外部のIdP（Identity Provider）との連携を設定する機能
- Event：KeyCloakで発生するイベントログ
- Administration Console：KeyCloakの管理画面
- REST API：KeyCloakをAPI経由で操作するためのAPI
"moduleResolution": "bundler"がVSCodeでエラーになる

# はじめに

VSCodeでエラーが発生した際に解決に時間がかかったのでまとめます

# 問題

`tsconfig.json`の以下の箇所でエラーがでてしまいます

```json:tsconfig.json
"moduleResolution": "bundler"
```

それが起因して、Reactのコードでも`import`がうまくいかなくなっていました

エラーをみるとmoduleResolutionを`node`に変えろと言われました

https://qiita.com/Sicut_study/items/9dd4526e17e5a56bc057

# 解決方法

まずTypeScriptのバージョンが対応していなかったので変更しました

```
$ npm install -g typescript@latest
```

そしてVSCodeのバージョンがTypeScript5.0以降に対応していないことがわかったので更新しました

https://code.visualstudio.com/

`.deb`ファイルをダウンロードしてインストールします

```
$ apt-get install インストールしたファイル.deb
```

これでエラーがでなくなりました

# おわりに

私だけ周りと違う挙動をしていたので不安でしたが解決できてよかったです
このままエラーを表示したまま開発する選択肢を考えるほどでしたが一安心でした

# 参考

https://qiita.com/Sicut_study/items/9dd4526e17e5a56bc057

https://stackoverflow.com/questions/75870063/vscode-and-typescript-5-moduleresolution-bundler

https://code.visualstudio.com/