OmniAICreator/Qiita-1.07M huggingface dataset:
WordPressってなに？どうして使うの?

#### WordPressをインターンで触ったので、備忘録として概要や触ったイメージ、メリットデメリットを記します。

この記事は、

+ WordPressの概要を知りたい人
+ WordPressを始めるか迷ってる人
+ どんな人が使ってるのか知りたい人
+ なんでもいいから早くウェブサイトを作りたい人

向けです

:::note warn
(数十年触っている人からすれば検討外れの内容かもしれません)
:::

# 概要
#### WordPressは、Webサイトを作るためのものです。決まった型の記事や内容を投稿する際に力を発揮します。言語はPHPで書かれていて、バックエンドの処理を担当してます。

<br><br>

例えばあなたが何かの運営者や広報担当者、何かの情報をまとめている人であったとします。あなたは外部にもっと知ってもらうためにウェブサイトを作りたい。

「どんなウェブサイトにしようか、基本的な情報を載せるだけじゃなく、長く使えるサイトにしたいなあ。」

そう考えたとき、定期的に新しい情報を提供したいこともあるでしょう。そこで候補に上がってくるかもしれないのがWordPressです。

WordPressは決まった型の内容や似た内容の記事投稿が得意です。
WordPressには管理者画面というものがあって、そこで記事を投稿します。
<br>
![スクリーンショット 2024-04-05 13.14.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762895/0ad97e7c-b893-4889-837a-a720fd1fd899.png)




ここで表示されているのは入力画面です。投稿は決まった入力が予想されるのであらかじめ入力項目を用意しました。あとはここに入力して投稿すれば、自分が用意したPHPファイルが入力内容をうまく処理し、CSSやjavascriptが反映され動きのある装飾された記事が自動的に出来上がります。


<br>

あとはWordPressのメリット、デメリットを説明して終わりましょう。


# メリット(非エンジニア目線)

1. 同じ入力作業を減らすことができる
1. たくさんの記事の公開非公開を視覚的に管理できる
1.  SEOのフィードバックがあるので、検索結果上位に来て人の目に止まりやすい
1.  すぐサイトが作れる

# メリット(エンジニア目線)

1.  データベースを理解する必要がなく学習コストが低い
1.  タグやカテゴリで投稿内容を管理や表示ができる
1.  気軽に使えるプラグインで拡張性が高い
1.  PHPやCSS、HTML、JavaScriptを思った箇所に使えるので初学者に優しい
1.  Google Search Console、Google Analytics、Page Speed InsightsやAll in One SEO等のプラグインを使うことでSEOと呼ばれる検索エンジンに乗るか否かの視点を手に入れ、hタグの意味や無駄なデータ構造、無駄なアルゴリズムを排除することを念頭にコードを書き始める。記事の入力の際にどうしたら離脱率が低くなるか、どうしたら検索結果に乗れるかのマネージャー視点に近くなる

# デメリット(エンジニア目線)
1. MVCではないので意識してファイル分割しないとコードが汚くなりがち
1. 最近の主流ではない
1. あまり技術を知らなくていいので成長が少ない

<br><br>

簡単に思いつく範囲ではこんな感じです。基本的にWordPressでできないことはないです。

スタートアップや個人、小規模の運営で使われやすいです。世界のウェブサイトの４割はWordpressでできています。基本的になんでもできるのが売りで、記事や情報の更新のしやすさ、検索結果上位への乗りやすさ、すぐウェブサイトを作れることが後押ししています。

# 使われ方
あなたがもし何かの事業主で、会社の基本情報の表示と単に記事の追加、更新だけできればいいような場合、WordPressは十二分の力を持っています。欲しい機能を要件定義し外注しましょう。他にはじゃらんや食べログ、ぐるなびのようにたくさんのお店のまとめの紹介をし、そこから注文されたら出来高制でお金がもらえるシステムのサイトを作るのであればウェブサイトを外注し、ライターを何人か雇えば網羅性の高い感じのWebサイトができます。

# まとめ
触った印象は、あくまでプログラミングやWebサイトは手段でしかないことを感じさせるものでした。誰かに何かの情報を「届けたい」、「知ってほしい」を実現させるにはWordPressはいいかもしれません。次の記事ではどんな風にサイトを構築するのかをまとめます。
[Wagby EE Tips #1] サブモデルを利用した外部から連携されるCSVファイルのアップロード更新

# はじめに
[Wagby EE](https://wagby.com/ee/index.html) は、(株)ジャスミンソフトが提供する国産のローコード開発プラットフォームです。

JDK をインストールしている環境であれば Wagby Designer (開発ツール)から Webアプリケーションを自動生成することができます。

筆者は業務で Wagby EE で開発や保守を行うことが多いのですが、知っておくと役に立ちそうなトピックを不定期で公開していこうと思います。

初回はアップロード更新に関するTipsを紹介します。

# 実現したいこと
* 既に設計されている顧客モデルに対して新規でアップロード更新を実装したい
* アップロードするファイルは、特定の外部システムが出力するCSVファイルを想定

# 考え方と実装
既存モデルとアップロードファイルの項目名が異なる場合、既存モデルのアップロード画面を有効にするだけでは対応できません。この場合、__既存モデルのサブモデルを作成し項目名をアップロードファイルの項目名に合わせることで対応可能となります。__

ここからは実際に Wagby Designer の画面を用いて説明します。

## 既存の顧客モデル
「顧客ID」「顧客名称」「顧客カナ」「会社名称」「電子メール」「電話番号」「業種」の7項目が定義されています。
また、主キーの「顧客ID」は「順序を利用する」を無効としており、自動採番は行われないものとします。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588669/6f222873-fcf3-4ce3-e517-e2e32f98e2bf.png">

## アップロードするCSVファイル
今回は外部システムが出力するCSVの一例として、Excelのテンプレート「基本的な顧客の連絡先リスト」を利用します。

1行目に記載されている項目名は「顧客 ID」「会社名」「連絡先名」「請求先住所」「市区町村」「都道府県」「郵便番号」「国/地域、連絡先の役職」「電話番号」「FAX 番号」「電子メール アドレス」「メモ」となっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588669/a59bc179-a0b4-491d-4690-b2d9984156ef.png)

## アップロード対象項目の決定
CSVファイルの項目のうち、顧客モデルに反映したい項目を決定します。
今回は以下の表に記載した項目をアップロード対象とします。

| CSVファイルの項目名 | 対応する顧客モデルの項目名 |
|:-----------|:------------|
| 顧客 ID    | 顧客ID       |
| 連絡先名    | 顧客名称     |
| 会社名      | 会社名称     |
| 電子メール アドレス | 電子メール |
| 電話番号    | 電話番号     |

## サブモデルの作成
モデル一覧画面から顧客モデルをもとにサブモデルを作成します。サブモデルには顧客モデルのその時点での定義がコピーされます。ここでは、サブモデルのモデル名は「顧客アップロード用モデル」とします。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588669/3ef3da91-7756-4267-5abe-dbc4352fb017.png">
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588669/8c979f7b-9099-112f-5834-7635e5ce7f5f.png">

## サブモデルの設定
まず、前述の表の通りにサブモデルの項目名をCSVファイルの項目名に合わせて変更します。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588669/731ee4f1-d0c3-1d90-b252-b691a051335c.png">

次にアップロード更新画面を用意します。
「画面」＞「アップロード」とタブを選択した後に以下の設定を行います。
1. 「画面を作成する」にチェックを入れ、アップロード更新画面を有効化します
2. ページタイトルを "顧客情報アップロード更新" に設定します

また他のタブ(「検索・一覧表示」、「詳細表示」など)については、全て「画面を作成する」のチェックを外します。これで顧客アップロード用モデルはアップロード更新専用のモデルとなります。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588669/802048dc-2459-7d13-84fd-5d707418687b.png">

## ビルド実行
以上で Wagby Designer での設定は完了です。
ビルドを実行して Web アプリケーションを生成します。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588669/8ff4b522-d578-68c7-b01b-ef5f700e175a.png">

# さいごに
本記事では、外部システムが出力したCSVファイルをアップロードする方法として、サブモデルを利用した考え方を紹介しました。
aws iam code

```
# variables.py
role_config = {
    "lambda": {
        "trusted_role_services": ["lambda.amazonaws.com"],
        "custom_role_policy_arns": ["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]
    },
    "ec2": {
        "trusted_role_services": ["ec2.amazonaws.com"],
        "custom_role_policy_arns": ["arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess"]
    },
    # 添加其他角色的配置
}
```
```
# main.py
from variables import role_config
from somewhere import IamAssumableRole  # 假设IamAssumableRole是你定义的或者导入的类

for role_name, config in role_config.items():
    IamAssumableRole(
        self,
        role_name,
        trusted_role_services=config["trusted_role_services"],
        create_role=True,
        role_name=role_name,
        custom_role_policy_arns=config["custom_role_policy_arns"]
    )
```
累積和

https://paiza.jp/works/mondai/query_primer/query_primer__cumulative_sum

ひとまずやってみたのですが、
ケース３と４でタイムオーバーになってしまいました。

```py

N, K = map(int,input().split())
A = [int(input()) for _ in range(N)]
B = [int(input()) for _ in range(K)]

for i in B:
    sum = 0

    for j in range(0,i):
        sum += A[j]
        
    print(sum)


```

テーマが累積和っていうらしいですが
```
A_1 から A_i までの和を sum[i] とすると、
sum[i] = sum[i-1] + A[i] という関係が成り立つので
すべての i について sum[i] を計算しておく

```
ん？？？
ちょっとよくわかりませんでした。。。
でも調べると、

たとえば
３つの配列の要素が下にあり、与えられた整数がたとえば３だったら

69
12
28

69+12+28＝？ってのが答えになる。
だけど累積和だと
69、81、109　と少しずつ足していきこれらを配列に入れて
たとえば整数が３だったらA配列の3番目なので109が答え、
整数が2だったら81が答え、
整数が１だったら６９が答えとするやつで、
これだと、毎回１つずつ足していくだけなので計算量が減る、という考え方らしい。
たしかに毎回リクエストが与えられるたびに最初から計算していたら時間がかかってしまいますね。
そういう考え方か。
というわけで累積和のロジックを理解したのでやってみます。

```py

N, K = map(int, input().split())
A = [int(input()) for _ in range(N)]
#上までは同じ
#Ansという配列を作成してそこに上と同じことをやっていく

#まず配列の要素をあらかじめ入れる（下の書き方で入れられる）
ans = [0] + A[:]

#ループで下の計算をすることでロジック通りの配列がえられる
for i in range(1, N + 1):
    ans[i] += ans[i - 1]

#後はリクエスト通りに配列の要素を出力するだけ
for _ in range(K):
    q = int(input())
    print(ans[q])

```
ちなみに１５秒オーバーしてたケース３とケース４が０秒台に減りました。
累積和、恐ろしい子！
Juliaで画像をBase64に変換する方法

## 画像→Base64に変換

Matrix形式の画像をBase64形式に変換する方法。以下はplaceholder.comから取得した画像をカットしてJPEGのBase64形式に変換するサンプル。
```julia
using Images
using FileIO
using HTTP
using ImageMagick
using Base64

res = HTTP.get("https://via.placeholder.com/200x200")
img = ImageMagick.load_(res.body)
println(size(img))
cut_img = img[1:size(img)[1]÷2, 1:size(img)[2]÷2]

io = IOBuffer()
save(Stream(format"JPEG", io), cut_img)
img_base64 = base64encode(take!(io))
println(img_base64)
# /9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgM ...
```
SendGridでClick Trackingを無効化できないときの対応

## 経緯
メール配信サービス「SendGrid」を利用していると、メール本文に掲載したURLをクリックしたときに「不適切なリンク」とポップアップが表示。（例：Thunderbird）

![不適当なリンク.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762629/641c7921-3652-74c2-8fa2-8121306f6197.png)


これは、次の条件で表示されようですが、SendGridのコントロールパネルでは無効化できず…
いろいろ試して彷徨ったので、こちらに残しておきます。

＜条件＞
・Click Tracking設定が有効
・送信元ドメインとリンクのドメインが不一致

同じくトラッキング機能の無効化にハマった方の参考になれば幸いです。

## 結論
HTMLのaタグに「clicktracking="off"」を突っ込めば解決。
他にも手はありそうですが、手っ取り早く解決したい方は、こちらでしのいで下さい。

```HTML
#例
<a clicktracking="off" href="https://hoge.com">アンカーテキスト</a>
```


## 過程
ハマった痕跡です。

### １．Link Brandingを設定してみる
ググってみると次の記事を発見。Link Brandingを設定してみる。

参考：
<a href="https://support.sendgrid.kke.co.jp/hc/ja/articles/900000008483-%E3%83%A1%E3%83%BC%E3%83%AB%E5%86%85%E3%81%AE%E3%83%AA%E3%83%B3%E3%82%AF%E3%82%92%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E3%81%99%E3%82%8B%E3%81%A8-%E4%B8%8D%E5%AF%A9%E3%81%AA%E3%82%B5%E3%82%A4%E3%83%88%E3%82%92%E9%96%8B%E3%81%93%E3%81%86%E3%81%A8%E3%81%97%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99-%E3%81%A8%E8%AD%A6%E5%91%8A%E3%81%8C%E5%87%BA%E3%81%BE%E3%81%99">メール内のリンクをクリックすると、「不審なサイトを開こうとしています。」と警告が出ます。</a>

同じドメインの場合は、無論、ポップアップは表示されなくなったが、YouTubeのリンクなどは相変わらずポップアップを表示。他の策を検討。


### ２．SendGridの日本語サイトでドキュメントを確認。
「Click Tracking」で設定の無効／有効化ができることを知る。
Disableに設定してメール送信してみるが、解決せず。

参考：
<a href="https://sendgrid.kke.co.jp/docs/index.html">SendGridの日本語ドキュメント</a>


### ３．引き続き、ググってみたり、AIにお伺いを立ててみたり
Web-API周りの話を目にするも、時間をかけられないので（単に面倒くさがり）、そっとしておく。

そのなかで、直接、海外のサポートに問い合わせたという情報をゲット。
「あっ、これ海外のサービスやん。」と遅まきながら気づく。


### ４．本家のサポートをのぞく
SendGrid本家のサポートで次の記事を見つける。
どうやら、初期の状態では、トラッキング機能の無効／有効にかかわらず、トラッキングを行うとのこと。
（Web-API触れば、このあたりを変えられるんでしょうね。多分。）

参考：
<a href="https://support.sendgrid.com/hc/en-us/articles/4474878853147-SendGrid-Marketing-Campaigns-Click-Tracking-settings">SendGrid Marketing Campaigns Click Tracking settings</a>


## まとめ
海外のサービスの場合、日本では代理店がサポートしていることがあるので、日本のサイトで解決しない場合は、本家のサイトを確認すべしと良い教訓になりました。

英語が苦手でも、テキストならDeepl翻訳など手軽に日本語で読める環境も整いましたしね。
技術の進歩に感謝です。
Next.jsレンダリングパターン早見表

## はじめに
Next.jsでは、ページの内容生成のために異なるレンダリングパターンが提供されています。
これらのパターンは、アプリケーションがデータフェッチング、SEO最適化、パフォーマンスをどのように扱うかに影響します。
毎回公式ドキュメントに行って翻訳ソフト使うのが面倒なので、早見表的にレンダリングパターンの概要とコードの使用例をまとめてみました。

# SSG(Static Site Generation)
<details><summary>SSGとは</summary>
静的サイト生成 。
SSGはビルド時にページをプレレンダリングします。
つまり、アプリケーションをビルドするときにHTMLが生成され、CDNにキャッシュされて高速に配信されます。
コンテンツが頻繁に変わらないページに適しています。
</details>

`cache`を`"force-cache"`とすることで実現できる
```tsx
// app/page.tsx
const response = await fetch("[URL]", {
  cache: "force-cache",
});
```

# SSR(Server Side Rendering)
<details><summary>SSRとは</summary>
SSRは、各リクエストごとにページのHTMLを生成します。頻繁に更新されるデータを表示するページに有用で、ページが最新の情報を含むことを保証します。
</details>

`cache`を`"no-store"`とすることで実現できる
```tsx
// app/page.tsx
const response = await fetch("[URL]", {
  cache: "no-store",
});
```
# ISR(Incremental Static Regeneration)
<details><summary>ISRとは</summary>
ISRを使用すると、頻繁に更新する必要があるページでSSGを使用できます。サイト全体を再ビルドすることなく、静的コンテンツを更新することができます。
</details>

`next`の設定で`revalidate`を設定することで指定した時間が経過すると自動でページを最新の状態に更新してくれます。
```tsx
// app/page.tsx
const response = await fetch("[URL]", {
  next: { revalidate: 3600 },
});
```

# CSR(Client Side Rendering)
<details><summary>CSRとは</summary>
CSRでは、JavaScriptが直接ブラウザ内でページコンテンツをレンダリングします。SEOが関心事ではないユーザー固有のページに有用です。
</details>

:::note warn
Next.jsではCSR単体で動作することはないので、割愛
:::

# 補足
一応、それぞれのレンダリングパターンについて簡単な解説を付け加えておきます。
間違っていたら教えてください。

## SSG
静的サイト生成 ( Static Site Generation)

#### 概要
SSGはビルド時に全てのページをHTMLファイルとして事前に生成します。生成されたHTMLファイルはCDNを通じて配信されるため、高速なアクセスが可能です。

#### 特徴
- ビルド時に静的ファイルを生成
- 再ビルドなしでの更新が難しい
- SEOに優れている

#### 他との違い
- リクエストごとにページを生成しないため、SSRやCSRに比べて高速
- ISRと比較して、動的な更新に対応しにくい

#### メリット
- ページの読み込みが非常に高速
- セキュリティが高い
- SEOに強い

#### デメリット
- コンテンツの更新にはビルドの再実行が必要
- ユーザーごとの動的なページ生成には不向き

## SSR
サーバーサイドレンダリング ( Server-Side Rendering)

#### 概要
SSRは各リクエストに対してサーバー側でHTMLを動的に生成し、クライアントに送信します。常に最新の情報をページに反映できます。

#### 特徴
- リクエストごとにサーバーでHTMLを生成
- 常に最新のデータを表示可能
- ユーザーのリクエストに応じたカスタマイズされたコンテンツの提供が可能

#### 他との違い
- SSGやCSRと比べて、ページ生成までの時間が長くなる可能性がある
- ISRとは異なり、静的ファイルの事前生成は行わない

#### メリット
- 動的なコンテンツの表示に強い
- SEOに優れている
- 初回のページロードが高速

#### デメリット
- 高いサーバーリソースを必要とする
- キャッシュ戦略が複雑になる場合がある


## ISR
Incremental Static Regeneration 

#### 概要
ISRは、SSGの利点を保ちつつ、ページを部分的に再生成することでコンテンツの更新を容易にします。特定のページだけを再生成できるため、全体のビルド時間を大幅に短縮できます。

#### 特徴
- 静的サイトのメリットを保持しつつ、動的な更新が可能
- 特定のページのみを再生成することで、全体のビルド時間を削減

#### 他との違い
- SSGとは異なり、ページの一部だけを更新できる
- SSRやCSRと比べて、生成されたページの読み込みが速い

#### メリット
- 静的サイトの高速性とセキュリティ
- ページの動的更新が可能
- ビルド時間の短縮

#### デメリット
- 設定が複雑になる場合がある
- リアルタイムのデータ更新には向かない


## CSR
クライアントサイドレンダリング (Client-Side Rendering)

#### 概要
CSRでは、サーバーから送信されたJavaScriptがクライアント側で実行され、ページのコンテンツを生成します。ユーザーとのインタラクションに応じて動的にコンテンツを更新できます。

#### 特徴
- クライアント側でページを動的に生成
- ユーザーの操作に基づいたリッチなインタラクティブ性

#### 他との違い
- SSGやSSRと異なり、サーバーでHTMLを生成しない
- ISRに比べて、ページの初回読み込みが遅い場合がある

#### メリット
- ユーザーとのインタラクションが豊富なアプリケーションに適している
- ページの部分的な更新が容易

#### デメリット
- 初回読み込みが遅い場合がある
- SEOに弱い
AjaxやFetchAPIで「エラー: SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON」がでるとき

## 前書き
JavaScriptでFetchAPIを使用し、非同期通信を行おうとしていた際に下記のエラーが発生しました。

``` :コンソール
エラー:
SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
```

## 原因
CSRFトークンの記述を忘れていたことが原因でした。

## 解決方法
今回はLaravelの環境で開発しているので、bladeとJSファイルに下記の記述を追加することで解決しました。

``` php:sample.blade.php
<meta name="csrf-token" content="{{ csrf_token() }}">
```

```JavaScript:jQuerySample.js
headers: {
    // ↓ これが抜けてた
    'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content');
            
    // ↓ ここは任意です
    'Content-Type': 'application/json',
    'body': JSON.stringify(inputData);
},
```
trocco®でBoxのメタデータをSnowflakeに転送する（OAuth 2.0認証）

# はじめに

少し前に（[と思ったら2023年7月だった・・・](https://documents.trocco.io/docs/release-note-2023-07)）trocco®の転送元HTTP・HTTPSの認可方式にOAuth 2.0が追加されました。ずっと触れていなかったので今さらながら簡単な検証記事になります。

OAuth 2.0が使えることでデータ取得できるサービスが多く増えるというのはもちろんですが、認証の設定を接続情報に切り出せることで、個々の設定をシンプルに行えるのも便利ですね。


# こんな方におすすめ

- trocco®でのOAuth 2.0での認証について知りたい
- Boxのメタデータを取得して活用したい


# 接続情報を作成する

通常、HTTP・HTTPSコネクタでは接続情報は不要（個別に設定する）なのですが、OAuth 2.0での認証を利用する場合、事前に接続情報を作成しておく必要があります。ただし、trocco®での設定の前に、Boxの設定が必要になるので、そちらから進めましょう。

まず、Boxにログインしたあとに、[Boxの開発者コンソール](https://app.box.com/developers/console)にアクセスします。「アプリの新規作成」＞「カスタムアプリ」を選択し、必要事項を入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/d1db0a39-f06e-de4a-e324-0bb3ba83c8b5.png)

認証方法として、`ユーザー認証 (OAuth 2.0)`を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/42cbcb25-1d18-01c0-dbb7-e4b8d50eb5e6.png)

リダイレクトURIに`https://trocco.io/connections/http/callback`を入力し、アプリケーションスコープとして「Boxに格納されているすべてのファイルとフォルダの読み取り」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/1580d83f-0d90-5b73-a8c5-a9a306db6687.png)

続いて、trocco®の接続情報作成画面で、必要事項を入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/7e068fd3-251c-a23c-502c-3d8a2faf6279.png)

これで接続情報の作成は完了です。簡単ですね。


# 転送設定を作成する

転送元HTTP・HTTPSの設定を入力する際に、OAuth 2.0を利用するにチェックします。そのほか、必要事項を入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/5e6a1d65-6edf-aef4-901f-f83b12fb3fe5.png)

認証関連の情報を入力する必要がありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/24ffaab2-66c4-249b-3df3-4446221d1566.png)

転送先Snowflakeに必要な設定を入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/23d7d01e-81cc-16ae-6e20-06733a92a50b.png)

自動設定をすると、そのままではカラム名が小文字になっているので、一括変換で大文字にしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/be1d23ee-3da9-b06e-5374-84ca5f973cba.png)

これで設定完了し、実行するとSnowflakeにテーブルが作成されます。


# Snowflakeでデータを確認する

テーブルを確認すると、1レコードの`ENTRIES`のカラムに複数のファイルやフォルダの情報が配列形式で入っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/ec058d0b-3475-54a9-e66c-202878ccd3f7.png)

クエリを投げてさくっとパースしてあげます。必要に応じて調整してください。

```sql
select
  parse_json(e.value):type::varchar as type,
  parse_json(e.value):id::varchar as id,
  parse_json(e.value):name::varchar as name,
  parse_json(e.value)
from
  demo_db.public.box_file_list b
left join
  table(flatten(b.entries)) e
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/89a537c7-2fe0-de57-4b74-cb6d64344b71.png)


# さいごに

HTTPコネクタはいくつか利用してきましたが、OAuth 2.0を使えると確かに活用の幅が広がるなと改めて思いました。想像以上に設定が簡単な上に可能性も感じられたので、また色々試してみようと思います！


# 参考

https://zenn.dev/yud/articles/949ac4bae2f4ee
[AWS]クラウドプラクティショナーとは？

# クラウドプラクティショナーとは
Amazonが運営するクラウドサービス
「Amazon Web Services(AWS)」の公式認定資格です。
AWS認定資格の中でも土台となるクラウドの全体的な基礎が問われる資格になります。

# そもそもクラウドとは
簡単にいうと「ユーザーがソフトウェアを持たなくても、ネットを通じてサービスを利用する」というもの
そして「必要な時に必要な量だけ利用できる」ITサービスをクラウドと言います。

# サービスとして提供されるもの
「コンピューティング・データベース・ストレージ・アプリケーション」をはじめとしたITリソース

# なぜクラウドが必要なのか
最も多い意見としては「資産・保守体制を会社が持つ必要性がない」
こちらの理由に加え、「場所・機器を選ばずに利用できる」「安定運用・可用性が高くなる」
といった複数の理由があります。

# クラウドのメリット・デメリット
はじめにメリットですが、ビジネスとしてスピードが求められる現在、ビジネスを支えるITシステムに迅速さと柔軟性が求められます。
なのでクラウドであれば、物理的な機器の設置は不要、サービスの変更にもメニュー選択するだけで完了する場合も多く、まさに現在求められている「柔軟性・迅速性」の利用が可能です。

続いてデメリットになりますが、その前にオンプレミスについて説明します。
オンプレミスとは、インフラの構築に必要となるサーバーやネットワーク機器を自社で保有・運用するシステムです。
クラウドで利用できるサービスをわざわざ自社で保有するのにも理由があります。
クラウドではサービス提供者の都合に影響されることがありますが、オンプレミスでは自社の都合を優先してシステムを運用できるメリットに加え、利用するサーバーやネットワーク機器などを自由に選択できるのが大まかな理由になります。

オンプレミスで説明したことを踏まえ、クラウドのデメリットについて説明します。
デメリットとしましては、外部サーバーであるため、
「カスタマイズ性・障害作業に即時対応不可・サーバー自体がサイバー攻撃に狙われやすい」
などがデメリットの理由として挙げられます。

ですが、これらの理由を踏まえてもクラウドを利用するメリットは大きいと思います。

# 試験概要について
試験時間
90分
問題数
65問
合格基準
700点以上
問題タイプ
選択問題方式
受験料
11,000(税別)

# 受験場所
テストセンターでのCBTにおける試験
※自宅でも受けられますが、カメラなどカンニング対策として事前に準備が必要です。

# 受験対象者
公式サイトで対象とされている受験対象者は
・AWSクラウドに6ヶ月間触れている
・AWSクラウドにおけるサービスに関する知識がある
・課金、セキュリティコンセプト、クラウドがビジネスにどのような影響を与えるかの知識がある
こちらは推奨されている受験対象者のため、実際には実務経験なしで1ヶ月ほどで取る方もいます。

# 取得するメリット
未経験からエンジニアに転職する場合や、学生の場合、AWSの基礎的な要素を理解しているという証明になります。
もちろん、現役エンジニアの場合でも資格取得のモチベーションやクラウドに関する知識を活用できるようにもなります。

# 勉強方法
まずは、クラウドとはどういうものかを実際に動画を視聴して知ってください。
YouTubeに載っていますので個人的にわかりやすいと思ったリンクを貼っておきます。
https://youtu.be/2a9w43E8irg
次に、クラウドプラクティショナー(CLF)の問題集をひたすら解くことです。
いきなり問題を解いてもわからないと思いますが、英語が少し読める方でしたら、
単語の意味だけで理解できる問題もあります。
わからない問題は随時解説や、ネットで調べたりして深く理解することです。
いきなり覚えようとしても絶対に理解できるわけではないので、
YouTubeや、ネット検索でゆっくり覚えていくのが大切です。

# まとめ
最後になりますが、実際にクラウドサービスを利用してみてください。
設定次第で金額が大きく変わるので、逆にいってしまえば格安で利用できます。
未経験エンジニアとして初めて取得する資格に最適かつ、副業するのにも使える知識にもなってくると思いますのでこれらの内容を踏まえぜひ、勉強してみてください。
パケットをPythonで分析してみる① プロトコルのパレート図

# はじめに
Pythonを使ってネットワークのパケットを分析してみる。
今回はキャプチャーファイル（tcpdumpの結果）から作ったCSVをPythonで読み込み、プロトコル別にパケットを集計してグラフ化する。
キャプチャーファイルからCSVを作成する方法はこちらを参照。

https://qiita.com/ymiki0001/items/050911c0217881bc8d7f

# 前提
* JupyterNotebook
* 適当なtcpdumpから作ったCSVファイル（サンプルではYahooのトップページにアクセスした際のキャプチャーを使用）

# 必要なモジュールのインポート
今回使用するモジュールをインポートする。
なお、以降は全てJupyterNotebook上で実行している。
```
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
```
# CSVの読み込み
CSVをデータフレームdfに読み込む。
```
df = pd.read_csv('test002.csv', index_col=0)
```
dfの内容を表示してみる。
```
df
```
![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662088/0ae69877-1618-06e0-00da-720f54a59d22.jpeg)

# プロトコル別に集計する
データフレームのProtocol列を集計してみる。
```
df.Protocol.value_counts()
```
結果
```
TCP        3119
TLSv1.3    1435
TLSv1.2     599
DNS         294
OCSP         70
QUIC         39
HTTP          6
SSLv2         3
NTP           2
Name: Protocol, dtype: int64
```

これを新しいデータフレームdf2に入れる。
```
df2=pd.DataFrame(df.Protocol.value_counts())
```
累積（Cumulative_sum）と累積比率（Cumulative_ratio）を計算し、df2に列を追加する。
```
df2["Cumulative_sum"] = np.cumsum(df2["Protocol"])
df2["Cumulative_ratio"] = df2["Cumulative_sum"] / sum(df2["Protocol"]) * 100
```
この時点でのdf2の内容を表示してみる。
```
df2
```
![002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662088/9bc8ecd6-95e0-a6aa-5132-1c0ad15bc477.jpeg)

# パレート図を作成する
df2の内容をもとにパレート図を描画してみる。
```
fig = plt.figure()
ax = fig.add_subplot(111)

data_num = len(df2)
 
ax.bar(range(data_num), df2["Protocol"])
ax.set_xticks(range(data_num))
ax.set_xticklabels(df2.index.tolist(), rotation=90)
ax.set_xlabel("(Protocol)")
ax.set_ylabel("(Packets)")
 
ax_add = ax.twinx()
ax_add.plot(range(data_num), df2["Cumulative_ratio"], color='red')
ax_add.set_ylim([0, 100])
ax_add.set_ylabel("(Percent)")
```
以下のようなパレート図が出力される。
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662088/06644f8f-ac7b-abdd-22d5-75a4d3221dda.png)


このように、通信パケットの中で使用されているプロトコルをパケット数が多い順に可視化することができた。

以上。
GET／POSTとは？

# 背景
GETとPOSTの違いが正しく理解できていなかったので、情報を整理するためにこの記事を書きました。
# GET/POSTとは
Webサイトの閲覧をしたり、Webアプリケーションを使ったりする際にWebサイトが置かれているサーバとの間では、毎回リクエスト（要求）とレスポンス（応答）が行われています。
#### リクエストを行う具体的な方法
1\. ブラウザのアドレス欄にURLを直接入力する。
2\. お気に入り（ブックマーク）からアクセスする。
3\. ページ内のリンクやボタン、画像などをクリックする。
4\. 入力フォームに情報を入力して送信ボタンをクリックする。
5\. JavaScriptなどからバックグラウンドアクセスする

このような方法があります。

サーバはこう言ったリクエストを受け取って
データ取得など適切な処理を行い該当のページを出力することで、皆さんのパソコンやスマートフォンのブラウザ上にページが表示されるような流れになっています。

このリスクエスト（要求）を行う際に、サーバーに対して「何らかのデータ」を渡したい場合があります。

#### リクエスト（要求）を行う際にサーバーに渡したいデータ

WebリクエストにおけるGETとPOSTの違い
GETとPOSTとは？
ウェブサイトやウェブアプリケーションとのやり取りでは、デバイスとサーバー間でリクエストとレスポンスが行われます。これには次のような方法があります：

URLを直接ブラウザのアドレスバーに入力する。
ブックマークからアクセスする。
ページ内のリンク、ボタン、画像などをクリックする。
入力フォームから情報を送信し、送信ボタンをクリックする。
JavaScriptなどのスクリプトによるバックグラウンドアクセス。
サーバーはこれらのリクエストを受け取り、適切に処理して対応するページを出力します。

リクエストでデータを渡す
リクエスト時には、サーバーにデータを渡す必要があります。このデータには次のようなものがあります：

表示したい商品や動画のID。
ナビゲーションのためのページ番号。
ログインのためのメールアドレスやパスワード。
名前や住所などの個人情報。
このデータは「リクエストパラメータ」と呼ばれます。

GETメソッド：
GETはURLの末尾にパラメータを付加して送信します。
例：example.com/search?id=10&type=12
パラメータはURLに「？」で始まり、それぞれのパラメータは「＆」で区切られます。
URLにパラメータが表示され、長大なデータを送信することはできません。

POSTメソッド：
POSTはURLにパラメータを付加せずにサーバーに送信します。
ログインフォームやデータ送信フォームなど、データの送信が必要な場合に使用されます。
例：HTMLフォームの使用

```index.html
<form method="POST" action="http://example.com/article">
    <div><label>タイトル：<input type="text" id="title" name="title"></label></div>
    <div><label>著者：<input type="text" id="author" name="author"></label></div>
    <input type="submit" name="submit" value="検索">
</form>
```

送信するデータはURLに表示されず、フォームフィールドを通じて送信されます。

要約：
GETはページの表示に必要なパラメータに使用されます。
POSTはユーザーが入力するデータの送信に使用されます。
例外として、頻繁なページの遷移やブックマークの場合があります。

結論：
ウェブアプリケーションを開発する際には、各ページの要件に応じて適切なリクエストメソッドを選択してください。
gitをpowershell上で実行する

# パワーシェルを活用して、効率的に作業を進めたい

ちなみにリモートリポジトリとしては GitHubつかってます。
powershell からgit コマンドをたたけるようになりたいです。

### Git for Windowsのインストール

WindowsでのGitは、CLIを利用する際に独自のBashを提供しており、これがLinuxバージョンのコマンドライン体験を模倣しています。しかし、この独自Bashを使うことによる手間を考えると、パワーシェル上で直接Gitを操作できれば、よりスムーズな開発フローが実現できると思いました。いずれにしても、`Git for Windows`のinstallationは必須なので、実行します。

```
winget install --id Git.Git -e --source winget
```

### PATHをとおす

ユーザーの環境変数という設定画面を開き、Pathのところに`C:\Program Files\Git\cmd`を追加しましょう。

### ファイルでなくディレクトリを初期につくってしまう問題

どういうわけだか、`C://Users/(JonDoe)/.gitconfig`っていうディレクトリをつくってしまうのだが、ほんとうに作りたいのは同名のファイルなので、WSL側から`echo ""> .gitconfig`みたいな感じでつくりました。

### 既存の .gitconfigの中身をコピー

WSL側に同名のファイルがあるはずなので、その内容をコピーする。しかし、`credential.helper=store`でこれはWindowsには通用しないようで、他のものに変更します。

`credential.helper=wincred`にしました。

[このあたり](https://vlike-vlife.netlify.app/posts/git_credential_windows)を参考にしました。ありがとうございます！

### sshプロトコル通信でなくhttpであることを想定してます

エラーが発生した時にパニクって、`git remote set-url origin git@github.com:`やってしまったのですが、こっからリカバーするのに苦労しました。

### ねんのためにエディター設定も・・

WSL側では viつかってるので、`core.editor=vi`ですが、Windowsなので、以下のようにしました。

```
core.editor = 'C:/Program Files (x86)/Notepad++/notepad++.exe' -multiInst -nosession
```


### ご参考

https://vlike-vlife.netlify.app/posts/git_credential_windows
UniVRMのURP向けMToon10シェーダーでアウトラインを表示する

Unity（URP）でVRMを扱っている記事を見ていると、アウトラインが表示できずに困っている方が散見されます。
試してみたところ、簡単にアウトラインを表示することができたので、共有のために記事を書いておきます。

## 解決したいこと
UniVRM（VRM1.0版）にはURP向けMToonシェーダーが同梱されています。
シェーダーの設定にはアウトラインの項目も見受けられますが、どうやら初期設定ではうまく動いていないようです。

そこで今回はこれを修正してアウトラインを表示できるようにしてみます。

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418961/67553b7e-a78a-d884-5602-e562decec403.png)

### 環境
OS：Windows 10
Unity：2022.3.10f1

## 前提条件
* UniVRM（VRM1.0版）の導入が完了している
* 使用したいVRMモデルのインポートが完了している
* プロジェクトがURPに対応している

これらが完了していない場合は他の記事を参考に導入などを行ってください。

## Renderer Featuresの設定
[Renderer Features](https://docs.unity3d.com/ja/Packages/com.unity.render-pipelines.universal@14.0/manual/urp-renderer-feature.html) とは、URPの描画を開発者が自由に設定できる機能です。
これにUniVRMのアウトライン設定を追加することで、アウトラインを表示できるようにします。

URPのCoreテンプレートから始めた場合、初めからAssetsにSettingsというフォルダが存在します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418961/d4e0496b-4ef9-0a2d-a3e2-49cceeee0861.png)

これを開くと、表層またはさらに下の階層（画像では`Assets → Settings → PC`）に`〇〇_Renderer`（`〇〇-Renderer`の場合もあります）というファイルがいくつかあります。
これらの`〇〇_Renderer`というファイルがRenderer Featuresの設定をしているファイルになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418961/b8101d2b-66d2-1cbc-8867-836654913607.png)

これらのファイルのうち、レンダリングの設定で使用しているファイルにUniVRMのアウトライン設定を追加します。

今回は`PC_High_Renderer`ファイルを使用しているので、このファイルを選択してインスペクタから`Add Renderer Feature → M Toon Outline Render Feature`を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418961/f8cb6147-d938-315e-9367-d1a17f24bc82.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418961/6ce74927-65ad-95d1-2c5b-064778ff8379.png)

::: note warn
もし使用しているファイルが分からない場合は、ファイル数が3~4個程度なので全てのファイルにアウトライン設定を追加しておく方が後々楽かもしれません……

興味がある方は、`ProjectSettings → Quality`にてどの設定ファイルを使用しているか確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418961/40d5bcbd-3e46-3bd6-a6b8-71012e3d4794.png)

::::

`M Toon Outline Render Feature`を追加すると、以下の画像のようにアウトラインが表示されます。
以上で設定は完了です。お疲れ様でした！

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418961/67553b7e-a78a-d884-5602-e562decec403.png)


## 使用したVRMモデル

今回は無料で使える合成音声ソフトである[VOICEVOX](https://voicevox.hiroshiba.jp/product/sayo/)のキャラクター、小夜/SAYOちゃんの[ファンメイドモデル](https://tukimi-moti.booth.pm/items/5128366)を利用して解説の画像を作成しました。
とてもかわいらしい声でお話ししてくれるので、よかったら使ってみてくださいね！（ダイマ）


## トラブルシューティング
UnityにVRMをインポートした際にモデルがマゼンタ色になっている場合は、シェーダを正しく指定できていない場合があります。
以下の記事を参考に修正するとよいです。

https://qiita.com/Karakuri_Polta/items/b440b057e326ab35d30c
【R】ヒストグラムを作る

# はじめに

これまでに[散布図](https://qiita.com/nkojima/items/c008adec58c7834edfc1)や[箱ひげ図](https://qiita.com/nkojima/items/016bb9ace336e88bc9ad)の作成方法をまとめてきたので、今回はその続きとしてヒストグラムの作成方法を記事にまとめてみました。

# 解析に使うデータ

* ある低木の樹高(m)のデータを使って、ヒストグラムを作成します。

```text:樹高データ
tree_height = c(0.89,3.35,1.97,1.09,1.34,1.23,2.6,2.66,1.28,3.48,1.53,0.88,4.17,4.13,1.06,3.03,0.57,1.29,1.91,5.53,1.59,4.06,4.67,3.2,5.22,4.28,3.42,4.68,0.99,0.89,2.86,1.68,1.02,4.98,3.02,1.16,1.91,2.75,4.56,1.98,4.21,5.18,1.71,2.15,5.27,2.81,2.68,0.87,0.34,1.05,1.23,3.74,1.25,1.35,2.61,1.97,2.42,1.12,1.63,1.43,1.58,0.84,0.89,2.89,3.18,4.66,1.73,1.68,0.74,0.49,5.17,0.48,1.27,1.11,0.72,3.22,0.99)
```

# 単純なヒストグラムの描画

* `hist`関数の引数としてベクトルを指定するだけで、あとはRがよしなにヒストグラムを作図してくれます。
  * 横軸は樹高(m)、縦軸は各階級内での出現頻度を示しています。

```r:単純なヒストグラムの描画
hist(tree_height)
```

![histgram_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/e5ee8baf-186c-54b7-8492-03cadc4e174d.png)

# 縦軸を「確率密度」に変える

* `freq=F`というパラメーターを加えると、縦軸を確率密度に変更できます。
  * デフォルトは`freq=T`で、縦軸は出現頻度となっています。

```r:縦軸を「確率密度」に変えたヒストグラム
hist(tree_height, freq=F)
```

![histgram_002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/7994691e-8dba-a714-ece0-074c390878fc.png)

# 横軸の範囲と階級幅を指定する

* デフォルトだと横軸の範囲と階級幅（分割の幅）は「Rにお任せ」なので、これを変更したい場合は`breaks`というパラメーターを使います。
* 以下の例では、横軸の範囲を0～6、階級幅を1に設定しています。

```r:横軸の範囲と階級幅を指定したヒストグラム
hist(tree_height, breaks=seq(0,6,1))
```

![histgram_003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/1c955f5b-cfdf-9b5e-e4ba-b242c2e4791f.png)


# 見た目を整える

* 様々なパラメーターを使うことで、タイトルや縦軸と横軸のラベル、棒の色などを調整することができます。
* `density`の最小値は0（※棒は枠線のみ）ですが、最大値についてはヘルプを見てもよく分かりませんでした。

|パラメーター名|意味|
|---|---|
|xlab|横軸のラベル|
|ylab|縦軸のラベル|
|main|グラフのタイトル|
|col|棒の色|
|density|棒の斜線の密度|

```r:見た目を整えたヒストグラム
hist(tree_height, breaks=seq(0,6,1), xlab="Tree height (m)", ylab="Number of individuals", main="Height size class of shrub tree", col="#2ca559", density=20)
```

![histgram_004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/48d135cd-be44-acf5-1cdf-6551af59f9ee.png)

# 参考資料

* Histgram - R Documentation
  * Rに添付されているヘルプファイルです。
* [Rによるヒストグラムの描画](https://data-science.gr.jp/implementation/ida_r_histogram.html)
tailwind cssを導入しているプロジェクトにSystemSpecを導入・実行したらエラーが出る



- Rails 7.1.2
- tailwind css
上記を用いて開発しているプロジェクトにおいて、ModelSpecは実行できるが、SystemSpec実行時にエラーが出る。

config/environments/production.rb 
に以下を追記したら解決した記載があり、試したが効果なし
```
config.assets.css_compressor = nil
```
## 環境
Gemfile

```
group :development, :test do
  gem "debug", platforms: %i[ mri windows ]
  gem 'rspec-rails'
  gem "capybara"
  gem "selenium-webdriver"
  gem "webdriver"
  gem 'factory_bot_rails'
  gem 'faker'
end
```

spec/rails_helper.rb
```
 config.before(:each, type: :system) do
    driven_by(:selenium_chrome_headless)
  end
```

.rspec
```
--require spec_helper
--format documentation
```

app/views/layouts/application.html.erbのhead部分
```
<!DOCTYPE html>
<html>
  <head>
    <title>hogehoge</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
    <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
    <%= javascript_importmap_tags %>
    <%= render 'shared/favicon' %>
    <link rel="manifest" href="/manifest.json">
    <%= display_meta_tags(default_meta_tags) %>
  </head>
```

Rspec作成後、以下を実行すると、Model Specは問題なく通るが、System Spec実行時にエラーを吐く
```
bundle exec rspec
```

エラーログ(抜粋)
```
1) サンプルテスト項目
     Failure/Error: <%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
     
     ActionView::Template::Error:
       Error: Function rgb is missing argument $green.
               on line 1 of stdin
       >> ue-400{--tw-border-opacity:1;border-color:rgb(96 165 250/var(--tw-border-opa
          ------------------------------------------^
     
     # stdin:1
     # ./app/views/layouts/application.html.erb:8:in `_app_views_layouts_application_html_erb___3914676935796240984_33440'
     # ------------------
     # --- Caused by: ---
     # SassC::SyntaxError:
     #   Error: Function rgb is missing argument $green.
     #           on line 1 of stdin
     #   >> ue-400{--tw-border-opacity:1;border-color:rgb(96 165 250/var(--tw-border-opa
     #      ------------------------------------------^
     #   stdin:1
```


## 対処

プリコンパイルされたファイルを一度クリアし、再度プリコンパイルを実行することで解決
```
# プリコンパイルされたファイルをクリア
rails assets:clobber

# 再度プリコンパイル
rails assets:precompile
```

Rspec側が、Tailwind CSSが生成するスタイルをうまく読み込めていないことが原因だったみたい。


## 参考
https://github.com/tailwindlabs/tailwindcss/discussions/6738
https://github.com/Kei5665/tokyo_senkyo_matching/issues/45
https://qiita.com/takakou/items/b1cc3dca18966ed2b9f4
【生成AIアプリ100チャレンジ】（12）画像解析アプリ　VISION API

# 公開サイト

https://ai.nuevo.jp/vision/
※ユーザー限定

# 開発環境

|              |              |
|:------------:|:------------:|
| Server       | lightSail    |
| Language     | Python3.11   |
| Framework    | Django       |
| DB           | sqlite3      |

ローカル環境ではPythonのvenvを使用。エディタはvs codeです。

# 目的
画像解析の生成AIであるvison apiをつかったアプリ。アップした画像の説明をしてくれる。
最初はプロンプトの規定は「日本語で返して」という設定のみ。このプロンプトを設定すれば、「なんの食材か」「なんの機材か」のみレスポンスを返すようになるのかは、後日チャレンジしたい。

# コード
```python:qiita.rb
    OPENAI_API_KEY = os.environ['OPENAI_API_IMAGE_KEY']
    domain = request.build_absolute_uri('/')
    file_path = 'demo.jpg'
    if default_storage.exists(file_path):
        default_storage.delete(file_path)
    img_results = ""
    image_path = ""
    if request.method == "POST":
        form = ChatForm(request.POST, request.FILES)
        if form.is_valid():
            image_file = request.FILES['image']
            image_content = image_file.read()
            default_storage.save('demo.jpg', ContentFile(image_content))
            client = OpenAI(
                api_key = OPENAI_API_KEY,
            )
            image_path = settings.BASE_DIR / "uploads/demo.jpg"
            print(image_path)
            def encode_image(image_path):
                with open(image_path, "rb") as image_file:
                    return base64.b64encode(image_file.read()).decode('utf-8')
            base64_image = encode_image(image_path)
            headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {OPENAI_API_KEY}"
            }
            payload = {
            "model": "gpt-4-vision-preview",
            "messages": [
                {
                "role": "user",
                "content": [
                    {
                    "type": "text",
                    "text": "What’s in this image?　日本語で答えてください"
                    },
                    {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/jpeg;base64,{base64_image}"
                    }
                    }
                ]
                }
            ],
            "max_tokens": 300
            }
            response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload)
            img_results = (response.json().get("choices")[0]["message"]["content"])
    else:
        form = ChatForm()  
```

# アプリ画面
![スクリーンショット 2024-04-05 12.45.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398694/4a8a0fc7-011d-a976-488b-ada8aef16389.png)

ソニックユースのキムゴードンの最新アルバムのジャケットを解析しました。
  
# 感想
画像解析はプロンプトによって、いろんなアプリが作れるのではないかと思っている。LLMやファインチューニングなどのテクニックを使う必要もあるのかもしれない。色々と試していきたい。
axiosとfetchの違いについて

axiosとfetchは、どちらもJavaScriptでHTTPリクエストを行うための方法です。
## axiosとfetchの違い
### インターフェース
- fetch 
ブラウザの標準APIであり、グローバル関数として提供されます。ネイティブのPromiseベースのAPIであり、`fetch()`メソッドを使用してHTTPリクエストを行います。
- axios
サードパーティのライブラリであり、独自のAPIを持っています。axiosインスタンスを作成し、そのインスタンスのメソッドを使用してHTTPリクエストを行います。
### ブラウザの互換性
- fetch
モダンブラウザで広くサポートされていますが、一部の古いブラウザではポリフィルが必要な場合があります。
- axios
Promiseベースのライブラリであり、すべてのモダンブラウザで動作します。さらに、Node.js環境でも使用できます。
### デフォルトの動作
- fetch
クッキーなどの一般的なHTTPリクエストの動作をカスタマイズするために、fetch()メソッドを使用する場合は、設定オプションを手動で指定する必要があります。
- axios
デフォルトでクッキーの処理やリクエスト/レスポンスのインターセプトなど、よく使用されるHTTPリクエストの機能が組み込まれています。

fetchはブラウザの標準機能であるため、単純なHTTPリクエストを行う場合や、フロントエンドのライブラリやフレームワークに依存したくない場合に適しています。
一方、axiosはより高度な機能や拡張性が必要な場合に便利です。
## 現在どちらの方が使用されているか
現在のトレンドではaxiosが広く使われています。axiosは以下のような理由から人気があります。
### 使いやすさ
axiosはPromiseベースであり、よりシンプルなAPIを提供しています。fetchは低レベルのAPIであり、クッキーの処理やエラーハンドリングなどの面でaxiosよりも手間がかかる場合があります。
### 機能性
axiosはデフォルトでHTTPリクエストの機能が豊富であり、クッキーの処理やリクエスト/レスポンスのインターセプトなど、よく使用される機能が組み込まれています。一方、fetchは基本的なHTTPリクエスト機能しか提供していません。
### ブラウザとNode.jsの両方で使える
axiosはブラウザとNode.jsの両方で使えるため、クライアントサイドとサーバーサイドの両方で同じライブラリを使用できます。これは、特にサーバーサイドレンダリングやユニバーサルJavaScriptアプリケーションの開発時に便利です。

## Reactでaxiosを使用する場合の例
axiosを使用する際には、Promiseチェーンを使用して成功した場合の処理と失敗した場合の処理を指定します。
成功した場合には `.then() `メソッドを使用し、失敗した場合には `.catch() `メソッドを使用します。
また、axiosはPromiseベースのライブラリであるため、`async/await`構文を使用して非同期処理を行うこともできます。

下記の例では、axiosを使用してGETとPOSTリクエストを行っていますが、他のHTTPメソッド（PUT、DELETEなど）も同様に使用できます。
APIエンドポイントや送信するデータに応じて、適切なメソッドを使用してください。
### axiosをインストール
```bash
npm install axios
```
### GETリクエストを送信する例
```javascript
import axios from 'axios';

axios.get('https://api.example.com/data')
  .then(response => {
    // リクエスト成功時の処理
    console.log(response.data);
  })
  .catch(error => {
    // リクエスト失敗時の処理
    console.error('Error fetching data:', error);
  });

```
### POSTリクエストを送信する例
```javascript
import axios from 'axios';

const dataToSend = {
  name: 'testname',
  email: 'testemail@example.com',
};

axios.post('https://api.example.com/create', dataToSend)
  .then(response => {
    // リクエスト成功時の処理
    console.log('Data created:', response.data);
  })
  .catch(error => {
    // リクエスト失敗時の処理
    console.error('Error creating data:', error);
  });

```

## その他
fetchもモダンブラウザで広くサポートされており、特に単純なHTTPリクエストを行う場合には便利です。また、fetchは追加のポリフィルを使用すれば古いブラウザでも使用できるようになります。
総じて、axiosが使いやすさや機能性の面で優れているため、多くの開発者がaxiosを好んで使用しています。
【WSL2】インストール

# はじめに
開発環境を整えるためにWSL2のインストールを実施しましたので、記録しておきます。

# 実行環境
Windows 11

# WSLとは
WSLは、Windows Subsystem for Linux の略で、Windows上でLinuxを実行できる便利な仕組みです。

# インストール
https://learn.microsoft.com/ja-jp/windows/wsl/install

PowerShellを管理者として実行し、以下のコマンドを実行します。
```bash
> wsl --install
インストール中：仮想マシン プラットフォーム
仮想マシン プラットフォーム はインストールされました。
インストール中：Linux 用 Windows サブシステム
Linux 用 Windows サブシステム はインストールされました。
インストール中：Ubuntu
Ubuntuはインストールされました。
要求された操作は正常に終了しました。変更を有効にするには、システムを再起動する必要があります。
```

インストールが完了したら、PCの再起動を行ないます。

再起動後、ディストリビューションのインストールに移ります。
インストールできるディストリビューションを確認してみましょう。

```
> wsl --list --online
インストールできる有効なディストリビューションの一覧を次に示します。
'wsl --install -d <Distro>' を使用してインストールします。

NAME                                   FRIENDLY NAME
Ubuntu                                 Ubuntu
Debian                                 Debian GNU/Linux
kali-linux                             Kali Linux Rolling
Ubuntu-18.04                           Ubuntu 18.04 LTS
Ubuntu-20.04                           Ubuntu 20.04 LTS
Ubuntu-22.04                           Ubuntu 22.04 LTS
OracleLinux_7_9                        Oracle Linux 7.9
OracleLinux_8_7                        Oracle Linux 8.7
OracleLinux_9_1                        Oracle Linux 9.1
openSUSE-Leap-15.5                     openSUSE Leap 15.5
SUSE-Linux-Enterprise-Server-15-SP4    SUSE Linux Enterprise Server 15 SP4
SUSE-Linux-Enterprise-15-SP5           SUSE Linux Enterprise 15 SP5
openSUSE-Tumbleweed                    openSUSE Tumbleweed
```

今回は```Ubuntu 22.04 LTS```をインストールします。
UbuntuはトップシェアでWeb開発に使いやすいです。
LTSというのはLong-Term Suppotの略で、通常版よりサポート期間が長いバージョンです。
```
> wsl --install -d Ubuntu-22.04
インストール中: Ubuntu 22.04 LTS
Ubuntu 22.04 LTS はインストールされました。
Ubuntu 22.04 LTS を起動しています...
```
```
Installing, this may take a few minutes...
```
数分後
```
Enter new UNIX username:
```
ユーザー名とパスワードを求められるので入力します。
パスワードは画面に表示されないので間違えないようにしましょう。

入力が終わればインストールは完了です！
```
Installation successful!
Linux 用の Windows サブシステムが Microsoft Store で入手可能になりました。
'wsl.exe --update' を実行するか、https://aka.ms/wslstorepage
 にアクセスしてアップグレードできます。Microsoft Store から WSL をインストールすると、最新の WSL 更新がより速く提供され ます。
詳細については、https://aka.ms/wslstoreinfo
をご覧ください。
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.10.16.3-microsoft-standard-WSL2 x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This message is shown once a day. To disable it please create the
/home/hio/.hushlogin file.
```
PowerShellからディストリビューションのインストールができていることを確認します。
```
> wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-22.04    Stopped         2
```
「-l」は「--list」の略で、ディストリビューションを一覧表示するオプション。
「-v」は「--verbose」の略で、ディストリビューションに関する詳細情報を表示するオプション。

試しに-vオプションを外してみると、以下のようにstateとversionに関する情報が表示されなくなりました。
```
> wsl -l
Linux 用 Windows サブシステム ディストリビューション:
Ubuntu-22.04 (既定)
```

# おわりに
最後までご覧いただきありがとうございました。
勉強中の初学者ですので、誤りなどがありましたら訂正していただけますと幸いです。
Laravelでのartisanコマンド（入門）

## はじめに
Laravelでは、作業の効率化のために様々なartisanコマンドが使用できます。この記事では、Laravelのartisanコマンドの基本的な使用方法と一般的なコマンドの例を紹介します。
### artisanコマンドとは
artisanは、Laravelのコマンドラインツールであり、開発作業を簡素化し、効率化するための様々なコマンドです。以下は、よく使用されるartisanコマンドの一部です。

### ルート一覧の表示
```php
php artisan route:list
```
このコマンドは、アプリケーションのルート一覧を表示します。HTTPメソッド、URI、アクションなどの詳細が表示されます。

### マイグレーションの実行
```php
php artisan migrate
```
このコマンドは、データベースのマイグレーションを実行します。マイグレーションは、データベースの構造を変更するための便利な方法です。

### モデルの作成
```php
php artisan make:model Goods
```
このコマンドは、新しいEloquentモデルを作成します。上記の例では、Goodsモデルが作成されます。

### コントローラの作成
```php
php artisan make:controller GoodsController
```
このコマンドは、新しいコントローラを作成します。上記の例では、GoodsControllerが作成されます。

### キャッシュのクリア
```php
php artisan cache:clear
```
このコマンドは、アプリケーションのキャッシュをクリアします。キャッシュが古くなったりそれによる問題が発生した場合に使用します。キャッシュをクリアすることによってアプリケーションを最新の状態にして動かすことが出来ます。

#### さいごに
artisanコマンドは、Laravel開発において非常に便利なツールです。この記事では、artisanコマンドの基本的な使用方法と何個か一般的なコマンドの例を紹介しました。活用してみてください。僕自身知らないことはたくさんあるので調べ、どんどん使いLaravelに対する理解をどんどん深めていきましょう！

以上がLaravelのartisanコマンドに関する簡単な紹介でした。他にも様々な便利なコマンドがありますので、以下のサイト見てみてください。

## 参考
https://readouble.com/laravel/11.x/ja/installation.htmlhttps://readouble.com/laravel/11.x/ja/artisan.html
eBayのカテゴリー一覧をAPIで取得する方法

# 事前知識
- eBayのカテゴリーは、年に数回Seller Updateにて変更が発表されます
- 最新のカテゴリー及び変更内容、過去のカテゴリーは、以下のURLで知ることができます
https://pages.ebay.com/sellerinformation/news/categorychanges.html
- カテゴリーは、各販売サイトごとに違います（例えば、USとUKでは違います）
- 出品は、リーフノード（末端）にのみ可能です

# getCategoryTreeを利用する
RESTful APIs > Commerce APIs > Taxonomy API > getCategoryTree
https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getCategoryTree

```
GET https://api.ebay.com/commerce/taxonomy/v1/category_tree/{category_tree_id}
```
:::note
Traditional Selling APIs > Trading API側にも、[GetCategories](https://developer.ebay.com/devzone/xml/docs/reference/ebay/getcategories.html)があります。同じく、カテゴリーIDとカテゴリー名をツリーで取得できます。
:::
## category_tree_id
このIDはカテゴリIDではなく、販売サイトごとに割り振られたIDです。getDefaultCategoryTreeIdをコールすることで取得することができます。
https://developer.ebay.com/api-docs/commerce/taxonomy/resources/category_tree/methods/getDefaultCategoryTreeId
現時点(2024/4)では、eBay USは0、eBay Motorsは100です。

# USのカテゴリーを取得してみる
```
GET https://api.ebay.com/commerce/taxonomy/v1/category_tree/0
```
以下のような戻り値が返ってきます。
```
{
  "categoryTreeId": "0",
  "categoryTreeVersion": "130",
  "rootCategoryNode": {
    "category": {
      "categoryId": "0",
      "categoryName": "Root"
    },
    "childCategoryTreeNodes": [
      {
        "category": {
          "categoryId": "1",
          "categoryName": "Collectibles"
        },
        "parentCategoryTreeNodeHref": "https://api.ebay.com/commerce/taxonomy/v1/category_tree/0/get_category_subtree?category_id=0",
        "childCategoryTreeNodes": [
          {
            "category": {
              "categoryId": "34",
              "categoryName": "Advertising"
            },
続く…
```

# 他のcategory_tree関連コール
https://developer.ebay.com/api-docs/commerce/taxonomy/resources/methods
各カテゴリーの必須Item Specifics等を取得することが可能です。
Xcode Cloud アーカイブエラー：xcodebuild: error: Could not resolve package dependencies: Package.resolved file is corrupted or malformed; fix or delete the file to continue: unknown 'PinsStorage' version '3

## 背景
2024年4月5日
Xcode CloudでArchiveをしようとすると下記エラーが表示された。

```
xcodebuild: error: Could not resolve package dependencies: Package.resolved file is 
corrupted or malformed; fix or delete the file to continue: unknown 'PinsStorage' version '3' at 
'/Volumes/workspace/repository/XXXXXXX.xcodeproj/project.xcworkspace/xcshareddata/
swiftpm/Package.resolved'.
```

## 上記事象が起こるまでに行った変更点
`/swiftspm/Package.resolved`の"version"が2→3になった差分をコミットした。

## 調査
ローカル環境（Xcode）でのArchiveは成功するので、切り分けとしてはまずXcode Cloud側の問題であると判断した。

## 解決方法
- ローカルのXcodeの実行環境
    - Xcode バージョン： Xcode 15.3
    - MACOS バージョン： macOS Sonoma 14.3.1（23D60）
- Xcode Cloudの実行環境：
    - Xcode バージョン： Xcode 15.2（15C500b）
    - MACOS バージョン： macOS Sonoma 14.2（23C64）

上記の通りローカルと実行環境が異なっていた。
今回の事象としてSPM（Package.resolved）の何かが新しくなって、それの実行に最新の実行環境が必要かもしれないと考えた。

最終的にXcode CloudのWorkFlow設定で実行環境を「Latest Release」とすることで解決した。
cscの作法 その476

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
Buttonを、使え。

# 方針
- じゃんけんを書く。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/81403fca-d85e-fe9d-3fb7-e48e1ac678f0.png)


# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Data;
using System.Globalization;

class form1: Form {
	form1() {
		Text = "じゃんけん";
		ClientSize = new Size(200, 200);
		Button btn1 = new Button();
		btn1.Location = new Point(30, 30);
		btn1.Text = "グー";
		btn1.Click += btn1_Click;
		Button btn2 = new Button();
		btn2.Location = new Point(30, 80);
		btn2.Text = "チョキ";
		btn2.Click += btn2_Click;
		Button btn3 = new Button();
		btn3.Location = new Point(30, 130);
		btn3.Text = "パー";
		btn3.Click += btn3_Click;
		Controls.AddRange(new Control[] {
			btn1,
			btn2,
			btn3,
		});
	}
	void btn1_Click(object sender, System.EventArgs e) {
		string b = "2";
		string name = "012";
		Random random = new Random();
		StringInfo nameInfo = new StringInfo(name);
		int newNameIndex = random.Next(nameInfo.LengthInTextElements);
		b = nameInfo.SubstringByTextElements(newNameIndex, 1);
		string str = "";
		switch (b)
		{
		case "0":
			str = "グーとグーで、あいこ";
		break;
		case "1":
			str = "グーとチョキで、あなたの勝ち";
		break;
		case "2":
			str = "グーとパーで、あなたの負け";
		break;
		default:
		break;
		}
		MessageBox.Show(str);
	}
	void btn2_Click(object sender, System.EventArgs e) {
		string b = "2";
		string name = "012";
		Random random = new Random();
		StringInfo nameInfo = new StringInfo(name);
		int newNameIndex = random.Next(nameInfo.LengthInTextElements);
		b = nameInfo.SubstringByTextElements(newNameIndex, 1);
		string str = "";
		switch (b)
		{
		case "0":
			str = "チョキとグーで、あなたの負け";
		break;
		case "1":
			str = "チョキとチョキで、あいこ";
		break;
		case "2":
			str = "チョキとパーで、あなたの勝ち";
		break;
		default:
		break;
		}
		MessageBox.Show(str);
	}
	void btn3_Click(object sender, System.EventArgs e) {
		string b = "2";
		string name = "012";
		Random random = new Random();
		StringInfo nameInfo = new StringInfo(name);
		int newNameIndex = random.Next(nameInfo.LengthInTextElements);
		b = nameInfo.SubstringByTextElements(newNameIndex, 1);
		string str = "";
		switch (b)
		{
		case "0":
			str = "パーとグーで、あなたの勝ち";
		break;
		case "1":
			str = "パーとチョキで、あなたの負け";
		break;
		case "2":
			str = "パーとパーで、あいこ";
		break;
		default:
		break;
		}
		MessageBox.Show(str);
	}
	[STAThread]
	public static void Main() {
		Application.EnableVisualStyles();
		Application.SetCompatibleTextRenderingDefault(false);
		Application.Run(new form1());
	}
}



```

以上。
アラフォーエンジニア歴3年の男が1年間転職活動を行った備忘録

# はじめに
私は35歳のアラフォーですがエンジニア歴は3年と割と浅く、その上、転職回数もそれなりに多いのですが、何とか転職で年収UPを実現することができました。
同じような境遇の方の参考になればと思い、転職活動の備忘録とします。

# これまでの経緯
詳細な経歴までは書ききれませんが、ざっくりと言うと30歳まで**建築業界**で勤務しており30歳を過ぎてから**IT業界**で勤務しています。
26歳で建築系の大学院を修了し建築事務所へ就職。
何故26歳で大学院修了なのかと言うと、学部を22歳で卒業した後、2年間フラフラしてから大学院に入り直したためです。

新卒で入所した建築事務所を試用期間の1年で退職となり、その後派遣社員として2社（3年程）契約社員として1社（1年）経験した後にIT業界へと飛び込みました。
そのため、転職回数もそれなりに多く（正社員雇用がそれまで一度もない）30歳を過ぎてからITエンジニアとなりました。

# スキルセット
得手不得手はマチマチですが、一応実務で経験してきた技術は以下になります。

C言語 | SQL | Splunk | Domo | Teradata | AppCenter | HTML | CSS | Ruby | Ruby on Rails | PHP | CodeIgniter | JavaScript | jQuery | GitHub | AWS EC2

# 転職活動における優先順位
1. 技術
1. 年収
1. 社風

私はデータ系の案件に参画していることが長く、開発案件よりもデータ系の案件に絞って転職活動をしていました。
その為、開発エンジニアよりは求人数が少なく、転職活動期間も長くなってしまった要因かと思います。

# 活用した媒体
- Green
- Wontedly
- 転職ドラフト
- ビズリーチ
- レバテックダイレクト
- Forkwell
- Findy
- リクルートエージェント
- Paiza
- SNS

と、それはそれは多くの媒体をフル活用しました。笑
ここまで同時に活用すると日程調整などがとても大変なのであまりオススメは出来ませんが、上の3つはエンジニア転職を行う上でマストだと思います。

また、媒体を利用するということは、企業からすると媒体側にも採用報酬を支払わなければならないため、当然その分採用のハードルが上がります。
エージェントなどを利用すると、システムだけでなく人件費も乗るためさらにハードルが上がります。
そのため、自分の手が届かないくらいの企業にエントリーしたい場合は、媒体を使わずに直接企業のコーポレートサイトから応募するのが良いと思います。

あと今の時代はSNSでの状況発信もとても有効だと思います。
（私自身、SNSでDMを頂いた企業に転職を決めました）

# 面接対策
これは多くのノウハウが色々と出回っていると思うのですが、私が独自で行っていたことは**スライド活用**になります。
GoogleでいうGoogleスライド。
Microsoftでいうパワポです。

1次面接は大体オンラインでの面接になると思います。
その際に自己紹介をする時に、
「スライドを準備してきたので画面共有をしてもよろしいでしょうか？」
と許可をもらってから自己紹介をします。

スライドを活用する利点としては、
- 志望度が高いと思われる
- スライドを見ながら自己紹介するので言葉に詰まらない
といったことが挙げられます。

もちろん、全てが全てこれを活用してPassした訳ではないのですが、活用したことで通過率は上がったかと思います。

# 必ず聞かれる質問
多くの企業の面接を受けてきましたが、必ず聞かれる質問がいくつかあるので残しておきます。
中には **「希望年収」「入社時期」** 等、事務的な質問事項もありますが、恐らくですがこれも判断材料だと思います。
- 自己紹介
- 志望動機
- 今の職場で頑張ったこと
- 希望年収
- 入社時期
- キャリアビジョン
これらの質問はどこの企業でも聞かれる項目だと思うので、マストで回答を用意しておきましょう。

# 転職活動の結果
1年間転職活動を続けた大よその結果は下記です。
- 書類応募 200社
- 書類通過 100社
- 最終面接 8社
- 内定 3社

ざっくりとし過ぎですが、1年間続けるとこれくらいはいくものです。笑
自社開発企業、事業会社、高還元SESと内定を頂きましたが、最終的には高還元SESに入社することに決めました。

技術系ではない記事を書くのが初めてなので、なんだか変な感じがしますが、転職活動を行う人の参考になれば幸いです。
raspberry Pi4上のubuntu Server 23.10(64bit)でsamba addc構築作業ログ

すでにubuntuをインストール済みとする

```
ssh hoge@raspberrypi.local
```
https://raspi-school.com/ssh/

GUIインストール
```
sudo apt update
sudo apt install -y ubuntu-desktop
```

初期設定
```
sudo dpkg-reconfigure keyboard-configuration
sudo timedatectl set-timezone Asia/Tokyo
timedatectl
```

これよりsamba addcインストール

2. **必要なパッケージをアップデート**:
   ```shell
   sudo apt-get update
   sudo apt-get upgrade
   ```

3. **Sambaをインストール**:
   Sambaをインストールします。以下のコマンドを実行します。
   ```shell
   sudo apt-get install samba
   ```

   ここで再起動しておいた
   ```
   sudo reboot
   ```

   
4. **Samba AD DCのインストール**:
   Samba AD DCをインストールします。以下のコマンドを実行します。これにより、Samba AD DCの設定ウィザードが開始されます。
   ```shell
   sudo samba-tool domain provision
   ```
   ウィザードの指示に従って、ドメイン名（example.local）、レルム、および管理者パスワードなどを設定します。

   ```
   Realm；EXAMPLE.LOCAL
   Domain[EXAMPLE];←Enter
   Server Role (dc, member, standalone) [dc]:←Enter
   DNS backend (SAMBA_INTERNAL, BIND9_FLATFILE, BIND9_DLZ, NONE) [SAMBA_INTERNAL]:←Enter
   DNS forwarder IP address (write 'none' to disable forwarding) [127.0.0.53]:8.8.8.8
   Administrator password:英数字大文字小文字交える
   ```

5. **Samba AD DCのサービスを開始**:
   インストールと設定が完了したら、Samba AD DCサービスを開始します。
   ```shell
   sudo systemctl start smbd
   ```

6. **起動時に自動的にサービスを開始**:
   システム起動時にSamba AD DCサービスが自動的に開始されるように設定します。
   ```shell
   sudo systemctl enable smbd
   ```

7. **Samba AD DCの状態を確認**:
   サービスが正常に実行されているか確認します。
   ```shell
   sudo systemctl status smbd
   ```
結果
```shell
● smbd.service - Samba SMB Daemon
     Loaded: loaded (/lib/systemd/system/smbd.service; enabled; preset: enabled)
     Active: active (running) since Fri 2024-04-05 14:22:51 JST; 20min ago
       Docs: man:smbd(8)
             man:samba(7)
             man:smb.conf(5)
   Main PID: 1134 (smbd)
     Status: "smbd: ready to serve connections..."
      Tasks: 3 (limit: 4421)
     Memory: 13.4M
        CPU: 580ms
     CGroup: /system.slice/smbd.service
             ├─1134 /usr/sbin/smbd --foreground --no-process-group
             ├─1140 "smbd: notifyd" .
             └─1141 "smbd: cleanupd "

Apr 05 14:22:50 raspberrypi systemd[1]: Starting smbd.service - Samba SMB Daemon...
Apr 05 14:22:51 raspberrypi systemd[1]: Started smbd.service - Samba SMB Daemon.
```

構文チェック
```
sudo testparm
```