OmniAICreator/Qiita-1.07M huggingface dataset:
【Udemy】難しいことはわからないけどChatGPT使ってみたい人へおすすめする個人的なラーニングパス

「Udemyおすすめ講座をシェアしよう！ by Udemy Advent Calendar 2023」の12/1担当の記事です。 
今年は子育てもあって時間の確保が難しいので予約投稿を活用します。（なので、12/1までは限定公開です）

# はじめに

最近Udemyを覗く機会があったので、最近流行ってるChatGPTの講座を見てみました。
ぶっちゃけ難しい数式とか理論とかよくわかんないし、AIのモデルを自分で作れるほどコーディングできないけど、それでもAIには興味あるし流行りのChatGPT使ってみたいんだよって人に向けた個人的なラーニングパスを勝手に作ってみました。

紹介するのは4本です。お金も時間も体力も有限なので効率よくいきましょう。
各講座でちょいちょい重複する説明があるとは思います。タイパ良く進めるために知ってる内容はスキップしてもよいと思います。

ローカルに環境を作るとなると、WindowsとかMacとかLinuxとかOSに左右され、環境構築だけでも結構時間取られたりすることもあるので、今回はすべてブラウザで完結する講座にしています。
会社がUdemyと契約してアカウント発行されてる人は、URLが異なるので、組織アカウントでサインインした後、見出しの講座タイトルで検索してください。（ライセンス？によっては出てこない可能性もありますが）
では、上から順にどうぞ。

# ChatGPTの使い方入門-最新AIビジネス活用 プロンプトエンジニアリングでより良い回答を得よう【2023年最新版】
1本目はこれ。
OpenAIの本家のサイトを使ってChatGPTの紹介と、浅く広い様々な活用事例が学べるため、
ChatGPTは名前しか聞いたことないとか、どんなシーンで使えるのかよくわかんないという人におすすめです。
OpenAIのアカウントさえあれば大丈夫ですが、講師の方はGPT4使ってるので、同じものが使いたい場合はChatGPT Plus(有料)のサブスク加入が必要です。無料版でも学習自体は可能です。
ちょっとは触ったことあるよという人はこの講座自体はスキップしてもよいと思います。

https://www.udemy.com/course/how-to-use-chatgpt-for-business/

# 【ChatGPT】講座 システム設計・開発・学習のアシスタントとしてフル活用し業務効率化【エンジニア向け】
二本目はこれ。
開発時に役立つコード生成やエラーの修正などのコーディングのサポートとしての活用や、要件定義や基本設計といったいわゆる上流フェーズの作業に対するサポートを行うような活用事例が学べるため、開発の生産性や品質を向上させたいという人におすすめです。

https://www.udemy.com/course/chatgpt-sw/


# ChatGPT API 新機能「Function Calling」で LINEbot 入門【GPT-3.5/GPT-4】
3本目はこれ
これはOpenAIのAPIを使うため、OpenAIのアカウントにクレジットカードの登録が必要です。単価は非常に安いのでちょっと使うだけなら高額な請求が発生するということはないです（場合によっては1円以下で請求なしとなることもあります）
※ただし、APIのキー情報を第三者に漏れないよう取り扱いには注意しましょう
  
この講座はGoogle Apps ScriptというJavascriptベースの言語を使用してAPIを実行します。
さくっとコード書いてみてAPI試すにはちょうど良いかなと思いますし、後半にはLINEとの連携実装もあり、ステップアップもしやすくて非常におすすめです。
Apps Scriptとか使ったことない場合でも大丈夫です。Apps Scriptの基礎学習も講座の頭に入ってます。（知ってる人は飛ばしてOK）

さらに、この講座では、Function callingという会話しながらChatGPTに実行するAPIを決めてもらって実行するという機能についても学習できます。これは今年の6月くらい出てきた新しい機能です。これを使いこなせると非常に活用の幅が広がるので、ぜひとも押さえておきたい機能の1つです。

https://www.udemy.com/course/chatgpt-line-function-calling-ai/



# ChatGPT APIを使ってチャットボットを作ろう！【GPT-3.5/GPT-4】 -LLMを使うアプリの構築と公開-
最後はこれ。
今度はpythonを使ってGoogleのColaboratoryを使いながらチャットボットを作成します。
アプリとして公開するために、ngrokとstreamlitのアカウント作成も必要ですが、基本的にはブラウザで完結する内容です。(講座の中でアカウント作成のやり方も説明あります)
APIを活用して、オレオレアプリを作って公開するということろまでをサクッと体験できるのでおすすめです

https://www.udemy.com/course/chatgpt-api-bot/

# 番外編:Azure OpenAI Service + Bot Service で作る Teams ChatBot
番外編としてAzure OpenAI Serviceも紹介しておきます。
これだけはローカルに環境を構築するのでそこだけご注意ください。(番外編ということで許して)

実際会社とか仕事で使おうと思った時、「会社のデータ流出が...」とか「データがホスティングされる国が...」といったセキュリティ関連の心配事が切り離せない問題として残りがちです。
そんな問題を解決してくれるのが、Azure OpenAI Serviceです。MicrosoftがOpenAIと一緒に作り上げたものです。OpenAIのAPIと同じような感覚でAPIを発行してアプリ開発に組み込むことが可能なので、仕事で使ってみたいという人はこの講座で学習しながら試してみるのがおすすめです。

https://www.udemy.com/course/aoai-chatbot/

# さいごに
ということで、勝手にまとめた個人的なラーニングパスとしておすすめの講座紹介でした。
気になっている方はぜひ試してみてください。
AWS上にコンテナを置く際のセキュリティグループについて

# はじめに
どうも、ぷっちょボール食べたくてAmazonで12個買ったら2つ目で飽きた男です。
今回は、以前書いたAWSのVPC上にコンテナサービスを置いて、セキュアなアーキテクチャを作成した際に、セキュリティグループの謎についてまとめました。
この謎について詳しく書いていきたいと思います。
お付き合いください。

https://qiita.com/inoshun/items/849a2b8d568844b0f472

https://qiita.com/inoshun/items/d24844c8fcdcd6a884bc

# セキュリティグループとは
まずセキュリティグループについて簡単におさらいしましょう。
セキュリティグループとはVPC内におけるAWSリソースまたはサービス間のトラフィックを制御するためのルールのことです。
たとえば、VPC内の負荷分散のためにロードバランサーを設置したとします。このロードバランサーでECSで実行したタスクにアクセスを分散させる場合、このタスクはロードバランサーからのトラフィックを許可する必要があります。
この許可をプロトコルやポート番号、IPアドレスなどを指定することで、セキュアな設計ができるのです。
社内でWebアプリケーションを展開したいというときも、このセキュリティグループに社内のIPアドレスを指定することで社内の人間しかアクセスできない環境を作ることができます。

# セキュリティグループの設定の仕方
セキュリティグループは基本的にVPC内に1つ以上作成します。
設定の方法としては、TCPやHTTPなどのプロトコルを選択する`タイプ`という欄は最適なものを選んでください。
わたしはすべてのトラフィックを選択しております。
そして、`ソース`の欄で**マイIP**を選択してください。
以前の記事ではマイIPってなんぞや？って感じでしたが、
マイIPとは、現在AWSクラウドにアクセスしているIPアドレスをそのまま指定できるという、大変便利なものとなっております。
つまり、社内のサーバーからAWSコンソールにアクセスし、セキュリティグループの設定でマイIPを選択すると…
**社内IPアドレスが指定できます。**
めちゃくちゃ便利ですね!!!
一瞬でセキュアな制御が可能になります。

続いて、マイIPを指定したら一度セキュリティグループを保存します。
そしてすぐに保存したセキュリティグループのインバウンドルールを編集してください。
ここで、`ソース`の欄でカスタムを選択し、IPアドレス記入欄から**先ほど作成したセキュリティグループを選択してください。**
何やってんの???って感じですよね。
私もそう思います。
しかし、この設定がないとVPC内のリソースが動きません。
はじめにセキュリティグループの説明をした際に、VPC内のAWSリソースまたはサービス間のトラフィックを制御すると言いました。
つまり、このセキュリティグループをアーキテクチャ上ですべて1つに統一した場合、すべてのリソース、サービスにこのセキュリティグループを設定することになるので、**このセキュリティグループ自体を許可する設定をする必要がある**ということです。

もっとわかりやすく説明します。
例えば、タスクAに対してセキュリティグループAを設定し、タスクBに対してセキュリティグループBを設定したとします。そして、このタスクAとタスクBがやり取りを行う際、タスクAからのトラフィックをセキュリティグループBは許可しなければなりません。つまり、セキュリティグループBにセキュリティグループAを設定する必要があるのです。
では、今回のケースを見てみましょう。セキュリティグループは1つですよね?そういうことです。セキュリティグループのインバウンドルールに自身を設定する必要があるということです。
ややこしいですね…

# まとめ
今回はセキュリティグループの設定方法についてご説明しました。
間違えている部分ございましたらご指摘いただけますと幸いです。
まあ、AWSのソリューションアーキテクトの方のお墨付きなんで多分大丈夫です!!!
他にもWAFなどで、さらにセキュアに構築することもできますが、ひとまずはこれでOKだと思います。
AWS関連で有益な情報がありましたら随時共有しようと思いますので、よろしくお願いいたします。
それでは！！！
Pythonで「文字列の中の指定した文字列を別の文字列に置換する(replace)」の動作を確認してみた

# 概要

Pythonで「文字列の中の指定した文字列を別の文字列に置換する(replace)」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/string/index20.html

# 実装

以下のファイルを作成しました。
```sample.py
print("Copyright 2018".replace("2018", "2019"))
print("box width 100, box height 50".replace("box", "div"))
print("Apple".replace("PP", "oo"))
print("")
print("AA BB AA CC AA DD AA EE".replace("AA", "aa"))
print("AA BB AA CC AA DD AA EE".replace("AA", "aa", 2))
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
Copyright 2019
div width 100, div height 50
Apple

aa BB aa CC aa DD aa EE
aa BB aa CC AA DD AA EE
```

# まとめ

何かの役に立てばと。
wslでnerves その20

# 概要
wsl(wsl2じゃない)でnervesやってみる。
qemu(x86_64エミュレータ、ラズパイじゃない)でやってみた。
生成したnerves_livebook.imgを、qemuで起動してみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/5ea5b466-a081-75ab-1f7e-0bdd0c7710b2.png)

# 起動スクリプト

```

"C:\Program Files\qemu\qemu-system-x86_64.exe" -drive file="nerves_livebook.img",if=virtio,format=raw -m 4098 -net nic,model=virtio -net usa,hostfwd=tcp::10022-:22,hostfwd=tcp::80-:80 -serial stdio


```

# ブラウザで、Livebook起動。

# アドレス

```
http://localhost
```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/07fe2dfa-8b7b-9166-c498-302cf11cba86.png)

# パスワード

```
nerves
```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/9aeece2c-ff82-a12c-38e0-e92ae3b08970.png)


以上。
windows 11 23h2 への道

![xeon.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/74b6a903-e643-886b-8f31-235f8803c26b.jpeg)



https://www.youtube.com/watch?v=d5eW7HU1sLg

のとおりです

|上には　以下では触れてない　
|:---
|「rufusを使っての　windows11 インストール用メモリの作り方」　
|も上にあるので　是非ご覧ください
|  |
|  |
|  |
|  |
|ドラゴンへの道

https://www.youtube.com/watch?v=zYsm_z4svhI


---------------
---------------

## 0) 前準備
22h2のアプデートを済ましてなくてもいけるんですけどね


## 1) windows 11 を起動したあと　rufusでつくったUSBメモリを突き刺します

下図にように　E:　がこのUSBメモリです

![PhotoMarker_20231117_050944_copy_874x817.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/d6e24c2f-70bb-6d67-f3b0-15b44b58f10d.jpeg)

## ２)
![PhotoMarker_20231117_051054_copy_889x817.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/e020105f-e670-274a-524c-05d7f08f4260.jpeg)


## ３)
![PhotoMarker_20231117_051012_copy_981x817.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/58090ba9-e27b-de4a-cfff-26e24dbf410d.jpeg)




## ４)


![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/973d37ce-7c42-cca9-d891-bfb9eb58c074.jpeg)



## 5)

![PhotoMarker_20231117_051202_copy_907x817.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/0c5a4c14-6d8d-02f6-7298-2e5eeedd747b.jpeg)

## 6)
![5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/b415b02e-060e-29cd-6eb7-cfd2a146ae9d.jpeg)


## 7)
![PhotoMarker_20231117_051351_copy_944x817.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/71292796-c771-e4ac-8d57-adc937f28e3d.jpeg)


## 8) かくして以下となりぬ
![a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/8cfa60a8-a0e8-72d1-a850-e0f702341b40.jpeg)



## 別の参考１）　ラックサーバー機でも　２３H2
![0s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/f213be6b-af75-c83d-450b-20ebee82e420.jpeg)





## 別の参考２）proからproへ

![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/2883f4f8-30ec-4a4b-d851-43594fd09d4d.jpeg)


## 別の参考3）これも pro

![m.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211097/c41c5862-f123-4002-adf8-33846f5e267e.jpeg)


https://atmarkit.itmedia.co.jp/ait/articles/2311/24/news027.html
をあとからみつけました

## こうして作った　SSDを　『SATA　USB　変換アダプター』で他のパソコンにつけると

何と　windpws11 が起動します
VLIなんならが　『SATA　USB　変換アダプター』です

https://www.youtube.com/watch?v=gUg660prmRo
CIDRの仕組みと表記方法

# CIDRの仕組みと表記方法

インターネットは多くのデバイスが接続され、それぞれに固有のアドレスが割り当てられています。このアドレスを効率的に管理するためにCIDR（Classless Inter-Domain Routing）という技術が用いられています。ここでは、IPアドレスの基本から始め、CIDRの仕組み、そしてその表記方法について初心者にも分かりやすく解説します。

## IPアドレスの概要

### インターネット上の住所

IPアドレスは、インターネット上のデバイスを識別するための数値のラベルです。IPv4とIPv6の二種類が存在し、それぞれに異なるフォーマットがあります。IPv4は32ビットの数値で構成され、一般的に8桁ごとに.で区切り「192.168.0.1」のような形式で表現されます。

## CIDRの基本

### ネットワーク管理の効率化

CIDRは、IPアドレスをより柔軟に割り当てるための方法です。従来のクラスフルネットワーキングでは、IPアドレスの範囲が固定的でしたが、CIDRではこの制限をなくし、ネットワークのサイズを必要に応じて調整できます。

### ネットワークアドレス部とホストアドレス部

IPアドレスは、ネットワークアドレス部とホストアドレス部の二部分に分割されます。CIDRでは、この分割の境界を柔軟に設定でき、異なるサイズのネットワークを効率的に作成できます。

## CIDRの表記方法

### 例とともに解説

CIDR表記では、「IPアドレス/プレフィックス長」というフォーマットを使用します。プレフィックス長は、ネットワークアドレス部を表すビットの数を示しています。

#### 具体例

例えば、「192.168.0.0/24」という表記があります。ここで、「192.168.0.0」はネットワークアドレスを示し、「/24」は最初の24ビットがネットワークアドレス部であることを意味しています。つまり、このネットワークは「192.168.0.0」から「192.168.0.255」までの256個のIPアドレスを持つことになります。

### プレフィックス長の違い

プレフィックス長が異なると、ネットワークのサイズも変わります。例えば、「192.168.0.0/16」は、「192.168.0.0」から「192.168.255.255」までの65,536個のIPアドレスを含むことになります。

## まとめ

CIDRは、IPアドレスをより柔軟に効率的に管理するための重要な技術です。ネットワークアドレス部とホストアドレス部を明確に区別し、必要なサイズのネットワークを作成することが可能です。CIDR表記を理解し、適切に使用することで、ネットワーク管理者はリソースを最大限に活用し、効率的なネットワーク設計を行うことがで

きます。
AWS LambdaでRubyのGemをレイヤーを使って利用する方法

# 概要
```ruby:lambda_function.rb
def lambda_handler(event:, context:)
  p "".blank?
end
```
AWS Lambdaで上記の関数を実行しようとすると、active_supportのGemがないので、undefined method blank?と怒られてしまいます。
上記のような関数も実行できるように、AWS LambdaでGemを使う方法をまとめてみました。

# ローカル環境での準備
Gemfileに `gem 'activesupport'` を追加し `bundle install` します。
`bundle install`によってインストールしたファイルはこの後レイヤーにアップロードするので
`--path .` のオプションをつけてカレントディレクトリにインストールされるようにします。
```
touch Gemfile
```
```:Gemfile
source 'https://rubygems.org'
gem 'activesupport'
```
```
bundle i --path .
```
すると `ruby/3.2.0` フォルダが作成され、その中にインストールされます。
`bundle install` 後のディレクトリ構成は下記のようになると思います。
```
.
├── .bundle
│   └── config
├── Gemfile
├── Gemfile.lock
└── ruby
    └── 3.2.0
```
rubyフォルダ以下をzipにするために下記のコマンドを実行て `layer.zip` を作成します。
```
zip -r layer.zip ruby/
```

# Lambda関数の作成
ランタイムをRubyにしてLambda関数を作成します。
![スクリーンショット 2023-11-17 3.43.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736970/1ec28213-bfe6-e6aa-0709-3c66ac71beab.png)

# コードの編集
Lambda関数のコードを下記に変更します。
```ruby:lambda_function.rb
require 'active_support/all'

def lambda_handler(event:, context:)
  p "".blank?
end
```
まだ、active_supportのGemを使えるようにしていないので、
関数を更新した後にテスト実行すると `cannot load such file -- active_support/all` の
エラーとなることが確認できると思います。

![スクリーンショット 2023-11-17 4.31.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736970/2fb4be2b-d83f-637a-fa74-7d08f4f552c9.png)


# レイヤーの作成
レイヤーを作成します。
ローカル環境での準備のところで作成しておいた `layer.zip` をアップロードします。
![スクリーンショット 2023-11-17 4.51.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736970/d8857242-3475-f152-1495-890534cb4f99.png)

# レイヤーの追加
Lambda関数のメニューに戻ってレイヤーの追加から作成したレイヤーを追加します。
![スクリーンショット 2023-11-17 4.56.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736970/24ca81ae-027b-79c6-a2ec-d9750b157ef7.png)
![スクリーンショット 2023-11-17 4.56.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736970/cb9d7681-4682-b5f1-722f-03a65974044b.png)


# 環境変数の追加
Layers に配置したファイルは `/opt` 配下に置かれるため、このパスからGemを読み込む設定が必要になります。
環境変数GEM_HOMEにパスを設定することで参照できるようになるため、
環境変数にGEM_HOMEを追加し、値は `/opt/ruby/3.2.0` とします。
![スクリーンショット 2023-12-01 1.54.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736970/8feff70d-fb55-fd73-c155-f0a56ae4d331.png)

※ 似たような環境変数としてGEM_PATHがあり、GEM_PATHにパスを指定することでもGemを参照することができます。
ただし、GEM_PATHには複数のパスが最初から設定されており、GEM_PATHを上書きしてしまうと
Lambda関数がデフォルトで使えるGemも使えなくなってしまうのでGEM_HOMEで設定する方がいいです

# テスト実行
以上の手順でGemが使えるようになりました。
テストを実行すると成功することが確認できると思います。
![スクリーンショット 2023-11-17 4.57.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736970/44c67bc5-1a31-ba6b-119b-620a088e3e7f.png)
CDNの通信が高速な理由とクラウドフロント

# CDNの通信が高速な理由とクラウドフロント

CDN（Content Delivery Network）サービスは、ウェブコンテンツの配信速度を向上させるために広く利用されています。CDNがなぜ通信を高速化できるのか、そのメカニズムには主にエッジロケーションとキャッシングの2つの重要な要素が関わっています。ここでは、CDNサービスの基本的な概念から始めて、AWSのクラウドフロントについても詳しく解説します。

## CDNサービスとは

### グローバルなコンテンツ配信ネットワーク

CDNは、ウェブページやビデオ、画像などの静的コンテンツを、世界中のユーザーに迅速に配信するためのシステムです。これにより、ウェブサイトのロード時間が短縮され、ユーザー体験が向上します。

## エッジロケーションとは

### コンテンツの地理的な最適化

CDNのネットワークは、世界中に分散配置されたエッジロケーション（サーバー）から構成されます。これらのエッジサーバーは、ユーザーに最も近い場所にコンテンツを保存し、配信します。結果として、データが長距離を移動する時間が削減され、配信速度が向上します。

### キャッシュの役割

#### 効率的なコンテンツ配信

CDNサービスでは、エッジサーバーにコンテンツをキャッシュ（一時保存）します。ユーザーからのリクエストがあると、CDNは最も近いエッジサーバーのキャッシュからコンテンツを取得し、迅速に配信します。これにより、オリジンサーバーへのアクセス頻度が減り、全体の応答時間が短縮されます。

## AWSクラウドフロント

### AWSのCDNサービス

AWSクラウドフロントは、Amazon Web Servicesが提供するCDNサービスです。このサービスを利用することで、静的コンテンツだけでなく、動的コンテンツやAPIの呼び出しも高速化することが可能です。

#### 特徴とメリット

- **広範囲なグローバルネットワーク**: AWSクラウドフロントは、世界中に広がるエッジロケーションを持っており、多くの地域で低遅延のコンテンツ配信が可能です。
- **統合性**: Amazon S3、EC2、Elastic Load Balancingなど、他のAWSサービスと簡単に統合できます。
- **セキュリティ**: AWSの堅牢なセキュリティと連携し、データの安全な配信が保証されます。
- **カスタマイズ性**: 詳細なアクセス制御や配信ルールのカスタマイズが可能です。

## まとめ

CDNサービスは、エッジロケーションによる地理的な最適化とコンテンツのキャッシングにより、ウェブコンテンツの配信速度を大幅に向上させます。AWSクラウドフロントは、

そのグローバルなネットワークと高度なカスタマイズ性により、多くの企業にとって魅力的なCDNソリューションを提供しています。これにより、ユーザーは世界中どこからでも迅速なアクセスを享受でき、企業は優れた顧客体験を提供することができます。
Java｜Stringクラスのメソッドの使い方（Ⅱ）

# 文字列を扱うメソッド
### valueOf()
- 書き方：String.valueOf(boolean b / char c / char[] c / int i / long l / float f / double b / Object o)
- 戻り値：String

　value Ofメソッドは、様々なタイプの値をString型に変換してくれます。データ型が厳しく分かれているJavaでその値を扱うためにデータ型を統一することも重要なことです。このメソッドを利用すると、どのデータ型でもString型に変え、値を扱うことができるようになります。
 　int型の場合はStringに変換して文字列として「+」演算をしたり、オブジェクトのインスタンスの場合はStringに変換してそのインスタントのアドレス値を返すこともできます。
```
public class Main{
	public static void main(String[] args){
        int intValue=30;  
        char chrArrayValue[]={'H','e','l','l', 'o'};  
        StringValueOfExample5 objValue=new StringValueOfExample5();  
		
        String s1=String.valueOf(value);  
        String s2=String.valueOf(chrArrayValue);
        String s3=String.valueOf(objValue);
		
        System.out.println(s1+10); // 3010
        System.out.println(s2);    // Hello
        System.out.println(s3);    // StringValueOfExample5@2a139a55
	}
}
```

### concat()
- 書き方：str1.concat(String str2)
- 戻り値：String

　concat()メソッドは、文字列(str1)の後に引数で指定した文字列(str2)を繋げます。単語「concatenate」が「連結、連続、連鎖」という意味であることで、メソッドの役割を簡単に思いつけると思います。
```
public class Main{
	public static void main(String[] args){
		String firstName = "Happy ";
		String lastName = "Birthday";
        
		System.out.println(firstName.concat(lastName)); // Happy Birthday
	}
}
```

### contains()
- 書き方：str.contains(Char chars)
- 戻り値：boolean

containsメソッドは、引数で指定する文字が文字列に含まれるかどうかをチェックします。含まれる場合はtrueを、含まれない場合はfalseを返す単純なメソッドです。

```
public class Main{
	public static void main(String[] args){
		String myStr = "Hello";
		System.out.println(myStr.contains("Hel"));  // true
		System.out.println(myStr.contains("e"));    // true
		System.out.println(myStr.contains("Hi"));   // false
	}
}
```

### equals()
- 書き方：str1.equals(str2)
- 戻り値：boolean

　equalsメソッドは2つの文字列を比較し、2つの値が一致すればtrueを、一致しなければfalseを返します。 if節を使って`if(str1===str2){~~}`と書くことがありましたが、「文字列」の一致/不一致を比較する場合はequals()メソッドを使うのが正確だそうです。

```
public class Main{
	public static void main(String[] args){
		String myStr1 = "Hello";
		String myStr2 = "Hello";
		String myStr3 = "World";
		
		System.out.println(myStr1.equals(myStr2)); // true
		System.out.println(myStr1.equals(myStr3)); // false
	}
}
```

### reverse()
- 書き方：str.reverse()
- 戻り値：StringBuilder object

　reverseメソッドは、文字列の順番を逆さまにした値を返します。これはインスタンス値を変更できない(immutable)Stringクラスではなく、インスタンス値を変更できる(mutable)StringBuilderクラスが持っているメソッドです。String型として返却したい場合は、toString()メソッドを使用します。
```
public class Main{
	public static void main(String[] args){
		String input = "Have a nice day";
		StringBuilder myStr = new StringBuilder();
 
		myStr.append(input);
 
		myStr.reverse();
 
		System.out.println(myStr.toString()); // yad ecin a evaH
    }
}
```

# まとめ
- valueOf() - 任意のデータ型をString型に変換
- concat() - 文字列と文字列を接続
- contains() - 文字列に含まれる文字か判断
- equals() - 文字列値の一致/不一致判断
- reverse() - 文字列の順番を逆さまにして返却
Java｜Stringクラスのメソッドの使い方（Ⅰ）

# はじめに
JavaのStringクラスには文字列を扱うためのメソッドが入っています。今回はそのメソッドについて紹介しようと思います。

# 文字列を扱うメソッド
### replace()
- 書き方：str.replace(char searchChar, char newChar)
- 戻り値：String

　replaceメソッドは、文字列を別の文字または文字列に置き換えるために使われます。最初の引数に置き換え元の文字を指定し、2番目の引数に置き換える文字を指定します。
```
public class Main{
	public static void main(String[] args){
		String myStr = "aaaa";
		System.out.println(myStr.replace("aa", "b")); // bb
	}
}
```

### charAt()
- 書き方：str.charAt(int index)
- 戻り値：char

　charAtメソッドは、文字列から引数で指定された位置(index)にある文字を抽出して返します。引数に指定する値は、抽出する位置(index)の値で0から始まります。もし5番目の文字を抽出したい場合は、引数に「4」を指定します。

　文字列範囲外の引数を指定すると、java.lang.StringIndexOutOfBoundsException例外が発生します。

```
public class Main{
	public static void main(String[] args){
		String myStr = "abcde";
		System.out.println(myStr.charAt(4)); // e
	}
}
```

### indexOf()
- 書き方：str.indexOf(String str)
- 戻り値：int

　indexOfメソッドは、引数に指定された文字または文字列の位置(index)を返します。引数に指定する値は、文字または文字列で0から始まります。抽出しようとする値が存在しない場合は「-1」を返します。
```
public class Main{
	public static void main(String[] args){
		String myStr = "Hello, world!";
		
		String myFirValue = "world";
		String mySndValue = "word";
        
		int indexOfFirValue = myStr.indexOf(myFirValue);
		int indexOfSndValue = myStr.indexOf(mySndValue);
		
		System.out.println("Index of " + myFirValue +": " + indexOfFirValue); // Index of world: 7
		System.out.println("Index of " + mySndValue +": " + indexOfSndValue); // Index of word: -1
	}
}
```

### substring()
- 書き方：str.substring(int startIndex) または str.substring(int startIndex, int endIndex)
- 戻り値：String

　subStringメソッドは文字列を部分切り取り、必要な部分の文字列を返します。最初の引数に抽出しようとする文字列の開始位置(index)を指定し、0から始まります。2番目の引数は任意値で、抽出しようとする文字列の最後の位置(index)を指定します。その位置の文字は返されません。
```
public class Main{
	public static void main(String[] args){
		String myStr = "Hello, world!";
		
		String myFirValue = myStr.substring(3);
		String mySndValue = myStr.substring(7, 12);
		
		System.out.println(myFirValue); // "lo, world"
		System.out.println(mySndValue); // "world"
	}
}
```

### startsWith() / endsWith()
- 書き方：str.startsWith(String chars) / str.endsWith(String chars)
- 戻り値：boolean

　startsWithメソッドは、提示された文字列が引数に指定した文字で始まるかどうかをチェックします。一方、endsWithメソッドは、提示された文字列が引数に指定した文字で終わるかどうかをチェックします。

```
public class Main{
	public static void main(String[] args){
		String myStr = "Happy Birthday";
		
		System.out.println(myStr.startsWith("Hap"));   // true
		System.out.println(myStr.startsWith("app"));   // false
		
		System.out.println(myStr.endsWith("day"));     // true
		System.out.println(myStr.endsWith("t"));       // false 
	}
}
```

# まとめ
- replace() - 文字列置換
- charAt() - 指定した位置の文字抽出
- indexOf() - 指定した文字の位置(index)抽出
- substring() - 必要な部分の文字列抽出
- startsWith() / endsWith() - 指定文字で始まるか/終わるか判断
paizaの問題を丁寧にTSで解きたい人向けテンプレート

型定義に時間かかってもいいから型補完の利く環境で解きたい人向けのテンプレートです。ただしpaizaの回答提出はTSに対応していないため、JSDocをフル活用して同様の環境を作ります。
またVSCodeでコーディングするものとし（流石に普通の開発みたくeslintとprittier入りディレクトリ作るのはやりすぎ感あるので、自分はlintをVSCode付属のTSパーサーに任せる形でやってます）、動作確認だけ回答欄なりpaiza.ioに張り付ける形で解いています。

# テンプレート全文
```js
// @ts-check

/**
 * @typedef {unknown} Info
 */

/**
 *
 * @param {ReadonlyArray<String>} inputs
 * @returns {Info}
 */
const getInfo = (inputs) => {
  const lines = inputs.filter((line) => line !== "") //最後に空文字が飛んでくるのでフィルターしておく
  const deliminator = " "
  const getNumber = (numberText) => parseInt(numberText)

  // @type {Info}
  const info = {
  };
  return info;
};

/**
 *
 * @param {Info} info
 * @returns {unknown}
 */
const getAnswer = (info) => {
  const answer = info
  
  return answer;
};

// @ts-ignore
const inputs = require("fs").readFileSync("/dev/stdin", "utf8").split("\n");
const info = getInfo(inputs);
const answer = getAnswer(info);
console.log(answer);

```

# 解説および使い方
標準入力を`getInfo`関数で解析し、各パラメーターをinfoにまとめて返し、（あくまで標準入力をバラして各パラメータをオブジェクトにまとめるまでを責務とするのがおすすめ）、そのinfoを`getAnswer`関数で解いて最後はconsole.logで出力するというフローです。getInfoから順を追って進めやすいよう、初期状態はinfo自体を出力するようにしてあります。

## getInfo
まず最初に`info`を組み立てますが、初期は`unknown`に指定してあるので好きなようにまとめて、完成間近で`@typedef unknown`を書き換えて渡したい形に直す感じですね。
またオブジェクトの組み立て中に変数に型指定したい場面もあるかと思いますが、以下のように定義します。

```js
/**
* @typedef {{x:number, y:number}} Point
* @typedef {Point} Info
*
*/

const header = lines[0]
const [x,y] = header.split(deliminator).map(getNumber)
/**
* @type Point
* 
*/
const point = {x,y}
const Info = {point}
```

みたいな感じでやってますね。別に下の所で`@typedef`してもいいんですが、paizaの問題レベルのコード量だと頭に固めた方がやりやすい気がします。どうせInfoの中でも型定義使うことになりますし。

## getAnswer
読んで字のごとくinfoを受けてanswerを返す関数です。ここにだら書きして肥大化 or 最初から明確に切り出した方がいいと検討ついたら、`getAnswer`と`getInfo`の間のスペースに関数として切り出す感じですね。A~Bランクだと大体2個ぐらい切り出してますね。
あと直接console.logに出力してるので、回答データから特定の書式への変換（配列から半角スペース区切りの文字列化等）が必要な場合もこの関数の責務になります。
Splunkチートシート

# はじめに

今回は、Splunkユーザのために頻出コマンドを中心にチートシートを作成しようと思います。

# 頻出サーチコマンド集
■　inputlookup
ルックアップテーブルの内容を読み込む。
```構文
| inputlookup ルックアップテーブル名
```

■outputlookup
サーチ結果をルックアップテーブルに書き込む。
```構文
| outputlookup ルックアップテーブル名
```

■eval
計算結果をフィールドに書き込む。
```構文
| eval フィールド名　= 計算式
```

evalコマンドでは、計算式に様々な関数を利用する。
※頻出の関数に関しては、次項目で紹介するので、そちらを参照する。

■addtotals
列ごとの数字のフィールド値を合計する。
```構文
| addtotals
```

■append
サブサーチの結果をメインサーチの下に行追加(縦結合)する。
```構文
メインサーチ
| append[
  サブサーチ
  ]
```

■chart
チャートグラフを作成する。
フィールドAの値とフィールドB毎の関数結果をチャート表示する。
```構文
| chart 関数 over フィールドA by フィールドB
```

■dedup
サーチ結果において、特定のフィールドに関する重複を削除する。
```構文
| dedup フィールド名
```

■delta
特定のフィールド値の各行で差分計算。
```構文
| delta フィールド名
```

■evenstats
全サーチ結果において、計算結果をフィールドに追加する。
```構文
| evenstats 関数　by フィールド名
```

■fillnull
NULL値を特定の値に変換する。
```構文
| fillnull value="ｘｘｘｘｘ"
```

■head
サーチ結果を先頭から指定した行のみ表示する。
```構文
| head ｘｘｘ
```

■lookup
フィールドAを基にルックアップテーブルを参照し、特定のフィールドBのみを読み込む。
```
| lookup ルックアップテーブル名 フィールド名A OUTPUT フィールド名B
```

■rename
フィールド名の名前を変更する。
```
| rename 変更前フィールド名 as 変更後フィールド名
```

■rex
正規表現によるフィールド抽出を実施する。
```
| rex field=ｘｘｘｘｘｘｘｘ
```

■search
indexからイベントサーチを実施する。
```
| search ｘｘｘｘ
```

■sort
フィールド内でソートする。
```
| sort フィールド名
```
■stats

統計的な計算を実施する。
```
| stats 関数
```

■streamstats
全ての結果に対して、累積演算を実施する。
```
| streamstats 関数
```


■table
フィールドをテーブル表示する。
```
| table 表示させたいフィールドをカンマ区切りで実施する。
```

■timechart
テーブルの行と列を入れ替える。
```
| timechart span=ｘｘｘ 
```

■where
サーチ結果を条件で検索する。
```
| where 条件文
```

# evalで利用できる関数集
■絶対値を返す。
```
| eval abs(ｘｘｘｘ)
```

■フィールド値を場合分け
【集中力】TOEICの試験時におすすめの超集中マインドテクニック！〜切らさずに最後まで！

以下のやり方で`TOEIC800`行きました。
直前に読むだけでもOK！

# 集中力を保つ
- マークシートはまとめて塗りつぶして、その間に集中力を充電
- ガムを食べる（食べていいんだっけ？）
- 集中力が切れる前に休む
- キーワードのみに集中、すべて理解しようとしないこと
- 問題をビジュアル化して頭で常にイメージする
- 脳みそを騙して、問題に飽きてこないようにする
- 前半は「もうX問も終わった」、後半は「あとX問で終わる」という姿勢
- 体を動かす
    - 設問毎(音声が終わる度)に顔を上げる
    - 肩の力を抜く
    - 深呼吸
    - 両手を使って解く
    - ストレッチ
    - 体を動かす
    - 5秒目を閉じる

## Part2 にて集中力を保つ
- Part1の簡単さを引きずらない
- 単調な問題でぼーっとしない
- マークシート記入後、次の問題まで、数字を数える

## Part3 にて集中力を保つ
- 設問数が多いので、途中で面倒にならないようにする
- ワンテンポ置いたり半分の地点で深呼吸

## Part4 にて集中力を保つ
- Part3で低下した集中力を引きずらない

## Part5 にて集中力を保つ
- Part4で低下した集中力を引きずらない

## Part6 にて集中力を保つ
- 肉体的・精神的にもっとも辛い箇所
- 残り時間を常にたしかめ、文章毎に気持ちをリセット
- 最大の難所だと思って挑む、「あと少し」と言い聞かせる

## Part7 にて集中力を保つ
- 細かいゴールを設定して、それを達成する喜びを得ながら進む

![Part7-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1900756/32c379d4-ff39-8fd0-04b3-828e35370f66.png)
SpringBootプロジェクトでテスト実行時にUnsatisfiedDependencyException

## 最初に結論
適切に`@ComponentScan`しよう。

## 前提
以下のように3階層のモジュールがあり、
main-module -> sub-module -> util-module という依存関係であるとする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541075/41302ebc-bd7f-7848-7d8b-fca258769a23.png)

このような構成で、sub-module内の`@SpringBootTest`が付与されたテストを実行した際
`org.springframework.beans.factory.UnsatisfiedDependencyException`が発生してハマったので備忘でメモ。

## 原因
sub-module内の特定の`@Bean`がutil-module内の特定の`@Bean`に依存していたが、
コンポーネントスキャンの設定がデフォルトのままとなっており、
util-module内までスキャンしにいかなかったことが原因。

sub-moduleのエントリーポイント(`@SpringBootApplication`が付与されたクラス)に
`@ComponentScan`のアノテーションを付与し、スキャン対象のパッケージを指定することで解決する。

```java:before
@SpringBootApplication
public class BootBaseApplication {
  public static void main(String[] args) {
    SpringApplication.run(BootBaseApplication.class, args);
  }
}
```

```java:after
@SpringBootApplication
// @ComponentScan("foo.bar.util") sub-module自身のパッケージ内を見に行かなくなるので、これはダメ
@ComponentScan({"foo.bar.sub", "foo.bar.util"})
public class BootBaseApplication {
  public static void main(String[] args) {
    SpringApplication.run(BootBaseApplication.class, args);
  }
}
```

設定を書かないデフォルト状態ではsub-module内のクラスを自動的にスキャンしてくれるが、
明示的に指定する場合はsub-module自身のパッケージも書かないと、指定したパッケージ(今回はutil-module内)のみしかスキャンしないため注意されたし。

## ハマった理由
* subは単品で動作するものではなく、常にmainを起点として動作する構造だったこと
  * subを単品で起動することがなかったため、subの`@SpringBootTest`実行まで検知の契機がなかった
  * mainの起動はできんのになんで？なんかテストユニークの話？という具合でハマった
* mainへのsub追加時に同様の事象が発生しなかったこと
  * utilだけパッケージが異なり、mainとsubのパッケージは同じだったため、sub追加時には`@ComponentScan`の設定変更が不要だった
  * main/subのパッケージ構成が異なっていれば、sub導入時にmainの`@SpringBootTest`実行でも同様の事象が起きていたはず
  * mainにsub入れるときは起きなかったのに、util入れるときだけ起きたことでまあ混乱
* 元々はmain -> subという二階層の依存関係だったところに、別チームが開発したutilを後から追加するという流れだったこと
  * 何か特別な設定が必要なのか？前提が違うのか？等々、別チーム成果物に対して若干の不信感があったことも否定できないのでそれは土下座
* 夜遅かったこと
  * 疲れが溜まってると些細な不具合にも簡単にハマるという説が有力です

## 先行研究
同様のエラーの他原因が解説されているので、解決しなかった方はこちら。

Spring BootでNo qualifying bean of typeが出た時の原因と対応
https://qiita.com/NagaokaKenichi/items/058a7243bd2948de7553
【Git】Git初期設定 for Mac OS

## はじめに
MacOSでGit初期設定をする方法についてのメモとなります。
(何回やっても忘れてるので。。😭)

## 環境
■ MacOS
14.0
■ チップ
Apple M2

## 1.Homebrewをインストール
HomebrewはmacOS上で動作するパッケージ管理ツールのひとつとなります。
Homebrewを用いて様々なパッケージをインストールすることができます。

■ Homebrew
https://brew.sh

以下のコマンドでインストールできます。
コマンドが変わる可能性があるので、ホームページで確認するのをお勧めします！

```terminal:Terminal
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
　
Homebrewをインストールしたものの、以下のエラーが発生していました。
パスが通ってないことが原因となるため、Homebrewのパスを通すことにより、解決できます。

```terminal:Terminal
# 出力
Warning: /opt/homebrew/bin is not in your PATH.
  Instructions on how to configure your shell for Homebrew
  can be found in the 'Next steps' section below.
==> Installation successful!

中略

==> Next steps:
- Run these two commands in your terminal to add Homebrew to your PATH:
    (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/{UserName}/.zprofile
    eval "$(/opt/homebrew/bin/brew shellenv)"
- Run brew help to get started
- Further documentation:
    https://docs.brew.sh
```

　
下記のコマンドを実行します。
```terminal:Terminal
$ echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/{UserName}/.zprofile
$ eval "$(/opt/homebrew/bin/brew shellenv)"
```

　
Homebrewのバージョンを確認します！
```terminal:Terminal
$ brew -v
# 出力
Homebrew 4.1.15
```

## 2.HomebrewでGitをインストール
brewでGitをインストールするため、以下のコマンドを実行します。
```terminal:Terminal
$ brew install git
```

　
インストールが完了したら、Gitのバージョンを確認してみましょう！
```terminal:Terminal
$ git --version
# 出力
git version 2.39.3 (Apple Git-145)
```

## 3.Gitアカウントの設定（git config）
これを設定していないと、ローカルリポジトリからリモートリポジトリにpushする度に、
アカウントの情報を入力する必要があります。

最初に設定しておくと便利です！

gitのユーザー名、メールアドレスを以下のコマンドで設定します。

```terminal:Terminal
$ git config --global user.name "{GitUserName}"
$ git config --global user.email {GitUserEmail}
```

　
登録内容を確認したい場合は、以下のコマンドを実行してください。
```terminal:Terminal
$ git config --list
```

## 4.GitのSSH接続を設定
自分のパソコンからサーバーに接続しているよー！と安全に通信をおこなう一つの手段として、
SSH公開鍵による認証をする必要があります。

まず、SSHキーが存在するのかを確認します。
```terminal:Terminal
$ cat ~/.ssh/id_rsa.pub
# 出力
cat: /Users/xxxx/.ssh/id_rsa.pub: No such file or directory
```

　
ディレクトリが存在しない場合、SSH公開鍵を作成します。

```terminal:Terminal
$ ssh-keygen
```

　
生成されたSSH公開鍵をコピーします。
以下のコマンドを実行すると、SSH公開鍵をクリップボードにコピーしてくれるので便利です。
```terminal:Terminal
$ cat ~/.ssh/id_rsa.pub | pbcopy
```

　
コピーした公開鍵をGithubに登録します。

登録方法は以下となります。
1.「自分のGithubプロフィール」>「Settings」>「SSH and GPG keys」で「New SSH key」に移動
<img width="640" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469200/e5f3ee9a-e204-f081-bf8a-7383a4cc0454.png" alt="Github PageImg">

2.コピーした公開鍵を登録
<img width="640" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469200/b36c80fb-b9dc-0f3c-1011-a933e8e29159.png" alt="Github PageImg">

## 最後に
ここまですれば、Git初期設定は一通り完了だと思います。
リモートリポジトリの作成やGitHubへのpushなどの作業に関してはまた機会があれば、、、😣
次世代コミュニケーションツール「CoScrean」を使ってみよう

# はじめに
本投稿は、[Datadog アドベントカレンダー 2023](https://qiita.com/advent-calendar/2023/datadog)の12/1の記事になります。

[昨年のアドベントカレンダーでもCoScrean](https://qiita.com/taiponrock/items/aa582c64740150d541bf)について書きました。
今回は、新しく追加されたCoScreanの機能について書いてみたいと思います。

# Blur（背景のぼかし機能）
こちらは、V6.0でリリースされた新機能になります。
ZoomやTeamsなどのWeb Meetingツールではすでに当たり前の機能ですが、CoScreanは今まで実装されてませんでした。
実は、突発的に必要になる障害対応時のコミュニケーションツールにこそ、背景のぼかし機能は必要かもしれませんね。

![Screenshot 2023-11-16 at 12.47.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81226/75aa2dc2-41a2-c0bc-4cf0-701f37ca44b0.png)

V6.0ではMacのみの対応でしたが、V6.1でWindowsにも対応しました。

# CoTerm（ターミナルのダイレクト共有機能）
こちらのV6.0でリリースされた新機能ですが、まだベータ版になります。
最大10人のユーザーが、ターミナルを共有し、同じセッションで共同作業が可能です。

パフォーマンスですが、CoTermが端末コンテンツをPTY/text dataとして送信するため、従来の画面共有では100ミリ秒を超える遅延があったのですが、約20ミリ秒で体感はゼロのリモートコントロールになりました。

セキュリティ面ですが、RegExおよびエントロピーベースのシークレットスキャンとフィルタリングにより、端末の共有をより安全に行います。

CoTermのベータ版ではデフォルトのログインシェルが使用されます。ターミナルアプリの代替にはなりません。そして、現状はまだプロファイルを設定することはできません。
また、シークレットフィルタリングは初期バージョンであるため、まだ無効にすることはできません。

V6.0では、CoTermの共有を解除すると、セッションはすぐに終了してたのですが、V6.1のアップデートで、セッションを終了せずにCoTermウィンドウの共有を解除して再共有できるようになったため、共有せずにターミナルで作業を続けることができます。

そして、これもV6.1のアップデートですが、複数のCoTermウィンドウを並行して起動して共有し、同時端末セッションで共同作業できるようになりました。

![CoTeam.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81226/dd23146b-0ccb-6d17-e13c-f0435282f254.png)

# CoScrean開発者からみんなへコメント
CoScreanを開発している、Datadog Senior Software Engineerのジェームスから日本のみんなへコメントをもらいました🙌
<iframe width="560" height="315" src="https://www.youtube.com/embed/EGbhY3zcbJ4?si=3P20spIMEsr5UrfL" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

# モバイル対応は？
基本的には画面共有での共同作業を見据えたツールではあるので、現状はモバイルはブラウザからのみ（機能限定で）利用が可能です。
ですが、ジェームスからは、現在モバイルアプリ開発も進めてるので近いうちに使えるようになるよ、とのことでした！
普通に、ミーティングツールとして使ってみても良いと思います。

# さいごに
いかがでしたか？徐々にですが成長しているCoScrean、今後の各種機能拡張も期待できそうです。
ジェームスからのコメントにもありましたが、ぜひ使ってみてフィードバックしてみてはいかがでしょうか？
日本語でフィードバックしたい場合は、日本語で入力した最後に、「Please translate it by Taiji」と一言入れておいて貰えればOKです！

![Screenshot 2023-11-16 at 11.13.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81226/f6997a96-1a98-71b3-dee2-e24283fc30df.png)

[無料プラン](https://www.coscreen.co/pricing)では以下の範囲で利用可能です。
- 参加人数、最大10人
- デスクトップアプリケーションの同時共有
- 共有ウィンドウを複数人で編集
- オーディオ＆ビデオチャット
- メール、Google、SSO でログイン

ダウンロードは[こちらから](https://www.coscreen.co/)可能です。ぜひ、使ってみてくださいね 👋
[Python] 関数のデフォルト引数の挙動メモ

# はじめに

Pythonで関数のデフォルト引数にリストなどのミュータブルな物は渡してはいけない事は、リンターが警告を出してくれていたので知っていました。
しかし、関数を実行する事でデフォルト値を渡す事がトラブルの元になる事は知りませんでした。
備忘録として記事にします。

リンタの設定を見直すべきですね。

# 環境

```:py -VV
Python 3.11.4 (tags/v3.11.4:d2340ef, Jun  7 2023, 05:45:37) [MSC v.1934 64 bit (AMD64)]
```

# コード

```python
import time
from datetime import datetime


def now():
  print("now")
  return datetime.now()


def test1(l=[]):
  l.append("hage")
  print(l)


def test2(t=now()):
  print(t)


test1()
test1()

test2()
time.sleep(10)
test2()
```

# 実行結果例

```:実行結果
now
['hage']
['hage', 'hage']
2023-11-17 01:08:56.144717
2023-11-17 01:08:56.144717
```


# 解説

`test1()`は、ミュータブルなリストを渡しているので、呼び出す毎に"hage"が増えてしまいます。(ｵｿﾛｼｲ)

`test2()`は、関数呼び出し時の時間を出力して欲しい所ですが、関数定義時に一度だけ実行された`now()`によって出力が決まってしまいます。
定義時に実行されてしまう事も知りませんでしたし、呼び出し時に値を渡してくれるものだと思っていました。
カーディナリティについて

### カーディナリティの定義
テーブルのカーディナリティは、テーブル内のユニークな行の数、つまりレコードの数を指す。これはテーブルが持つデータの量を表す指標。

### 低カーディナリティと高カーディナリティ:

低カーディナリティ: 限られた数の独自の値を持つ。例えば、性別や国籍のようなフィールド。
高カーディナリティ: 多くのユニークな値を持つ。例えば、顧客IDやトランザクション番号のようなフィールド。

### カーディナリティの重要性

インデックス効率: 低カーディナリティのフィールドはインデックスとしてあまり効率的ではない場合がある。逆に、高カーディナリティのフィールドはより効率的なインデックスを提供する。
クエリパフォーマンス: カーディナリティは検索クエリのパフォーマンスに大きく影響する。高カーディナリティのフィールドは、より効率的な検索を可能にする。

### カーディナリティの評価

データベースのパフォーマンスを最適化するためには、テーブルのカーディナリティを適切に評価し、管理することが重要。
インデックス戦略の計画時にはカーディナリティを考慮する必要がある。

### カーディナリティとデータの品質

データの品質にも影響する。例えば、高カーディナリティのフィールドに予期せぬ重複がある場合、これはデータの整合性の問題を示唆している可能性がある。
データベースを検索した結果の件数でHTMLを切り替える方法

# はじめに
データベースの検索結果がある場合と無い場合（0件）でHTMLを切り替えたいなーと思い、
検索結果の件数によってHTMLを切り替える方法を調べました。

# HTMLを切り替える方法
JAVA Spring BootとThymeleafを使用してpageableから要素数を取得することでHTMLタグを切り替えられそう。
という事で、.getNumberOfElements() メソッドを使用して検索結果の件数を取得してHTMLタグを切り替えてみました。

# コード抜粋


```html:index.html
<div th:if="${pageable.getNumberOfElements()}>0">
    <P>要素あり</p>
</div>

<div th:if="${pageable.getNumberOfElements()}==0">
    <P>要素なし</p>
</div>                                                     
```

```java:Controller.java
package com.example.demo;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

@Controller
public class DemoController {

    @GetMapping("/")
    public String index(Model model) {
        // 例としてPageableオブジェクトを作成
        int pageSize = 10;
        int currentPage = 0;

        // ページ数を取得するためにPageableを使用
        PageRequest pageRequest = PageRequest.of(currentPage, pageSize);

        // ページングされたデータ（ダミーデータを使用）
        List<String> data = List.of("Item 1", "Item 2", "Item 3", "Item 4", "Item 5");

        // ページングのためのPageオブジェクトを作成
        Page<String> page = new PageImpl<>(data, pageRequest, data.size());

        // Pageableとページ内データのサイズをテンプレートに渡す
        model.addAttribute("pageable", page);

        return "index";
    }
}
```

# 結果
検索結果の件数が0件の場合と、1件でもある場合で切り替える事が出来ます。
AWS EC2 インスタンスにログインできなくなったときの対処記録

まずは公式ドキュメント案内。記事は陳腐化するが公式ドキュメントはメンテナンスされることを期待する。

https://repost.aws/ja/knowledge-center/ec2-linux-fix-permission-denied-errors

# 記事概要

EC2 インスタンスを立てて ssh でログインして操作することが多い。

実験的に ssh とかファイアウォールとかの設定を変えているとうっかり ssh で入れなくしてしまうことがある。

対処して ssh ログインできるようになったので、対処した方法を記録する。

# 対処

以下の流れで記録する

- 問題
- 対処方法調査
- 実際の対処
- 感想など

## 問題

グループ設定がちがう xxx さんをマシンにアクセスできるようにするために、 `/etc/ssh/sshd_config` に以下のような変更をしてしまった。

```
AllowGroups ssh-users
↓
AllowUsers xxx
AllowGroups ssh-users
```

変更前はグループが ssh-users の人のアクセスを許可するもの。
変更後は xxx さん**でかつ** グループが ssh-users の人のアクセスを許可するもの。OR 条件だと思って設定したら AND 条件だった。

https://man.freebsd.org/cgi/man.cgi?query=sshd_config&sektion=5

https://serverfault.com/questions/617081/how-to-use-both-allowgroups-and-allowusers-in-sshd-config/990838#990838

xxx さんでかつ グループが ssh-users の人はいないのでだれもログインできなくなってしまった。


## 対処方法調査

公式ドキュメントで具体的な案内がいくつかある。

https://repost.aws/ja/knowledge-center/ec2-linux-fix-permission-denied-errors

この中の「方法 4: ユーザーデータスクリプトを使用して SSH アクセス許可を修復し、正しい SSH パブリックキーを authorized_keys ファイルに追加する」を参考にしました。

ユーザーデータスクリプトとは、インスタンスの起動/再起動時に任意のスクリプトを走らせることができるものです。スクリプトは強力な権限を持つユーザで実行されます。

今回は SSH アクセス許可をミスしてしまっただけなので「ユーザーデータスクリプトを使用して SSH アクセス許可を修復する」部分だけを利用します。

## 実際の対処

ユーザーデータスクリプトの設定方法は公式ドキュメントを参照してください。

今回のケースである「SSH アクセス許可を修復する」スクリプト部分は1行でした。
sshd_config から `AllowUsers` を含む行を削除するのみです。

```sh
sed '/^AllowUsers/d' -i /etc/ssh/sshd_config
```

停止->再起動したら元の通りグループが ssh-users の人のアクセスができるようになりました。

ユーザーデータスクリプトは、インスタンスを再起動するたびに実行されるように設定されています。インスタンスにアクセスできるようになったので、ユーザーデータスクリプトを削除した。

## 感想など

ユーザデータスクリプト、トラブルシューティングに利用できること経験になりました。

この方法はインスタンスの再起動をしています。再起動によってサービスの停止やIPアドレス変更が発生することは考慮する必要があります。
闘魂Elixir ── Phoenixの作者Chris McCordさんがツイートしたカッコいいロゴの正体は一体！？

<b><font color="red">$\huge{元氣ですかーーーーッ！！！}$</font></b>
<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>

<b><font color="red">$\huge{闘魂とは己に打ち克つこと。}$</font></b>
<b><font color="red">$\huge{そして闘いを通じて己の魂を磨いていく}$</font></b>
<b><font color="red">$\huge{ことだと思います}$</font></b>



# はじめに

[Elixir](https://elixir-lang.org/)界隈でざわついているツイートがあります。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">SOON™ <a href="https://t.co/dPrqpa5nN1">pic.twitter.com/dPrqpa5nN1</a></p>&mdash; Chris McCord (@chris_mccord) <a href="https://twitter.com/chris_mccord/status/1724861258548052109?ref_src=twsrc%5Etfw">November 15, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

12月01日にはその正体が判明しているかもしれません。
2023/11/17書いておくことに意義がある記事だとおもっています。
[Elixir](https://elixir-lang.org/)製のWebアプリケーションフレームワーク[Phoenix](https://www.phoenixframework.org/)の作者[Chris McCord](https://twitter.com/chris_mccord)さんのツイートです。

果たして！？

# What is [Elixir](https://elixir-lang.org/) ?

[Elixir](https://elixir-lang.org/)という素敵なプログラミング言語があってがですね。
その素敵具合は「[Elixir Saves Pinterest $2 Million a Year In Server Costs](https://paraxial.io/blog/elixir-savings)」によく現れています。開発者も経営者もこの事実に瞠目することでしょう。 **$2 Million/年の節約ですってよ！、奥さん。**

https://paraxial.io/blog/elixir-savings

# 一体何でしょうか！？

改めてツイートを貼っておきます。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">SOON™ <a href="https://t.co/dPrqpa5nN1">pic.twitter.com/dPrqpa5nN1</a></p>&mdash; Chris McCord (@chris_mccord) <a href="https://twitter.com/chris_mccord/status/1724861258548052109?ref_src=twsrc%5Etfw">November 15, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

[Elixir](https://elixir-lang.org/)の形が[Phoenix](https://www.phoenixframework.org/)色?、Firefox色? でカラーリングされているように見えます。
メタリックな感じ（猪木寛至さん）です。
**燃える闘魂**にも見えてきます。 :fire: 

いまわかっていることです。

- LiveView 1.0ではないとのことです
- DX(※ おそらくdeveloper experienceの方)を改善するものとのことです

いろいろとみなさんが予想を返信されています。
その正体は果たしていかに！？



# さいごに

[Chris McCord](https://twitter.com/chris_mccord)さんがツイートされたかっこいいロゴの話を書きました。
この記事を書いた2023/11/17時点では不明です。

人類は不老不死の霊薬を意味する素敵なプログラミング言語[Elixir](https://elixir-lang.org/)を手に入れました。並行処理を他のプログラミング言語よりも比較的容易に書くことができます。それはきっとコンピュータ資源を有効活用できることにつながるでしょう。巡り巡って本当の世界平和を必ず実現します。世界文化の進展に寄与できます。

さあ、そこのあなたも[Elixir](https://elixir-lang.org/)の世界へようこそ。
_手始めに[エリクサーチ](https://elixir-lang.info/)なんていかがでしょうか。私のオススメです。_

---

**闘魂**とは、  **「己に打ち克つこと。そして闘いを通じて己の魂を磨いていくことである」** との猪木さんの言葉をそのまま胸に刻み込んでいます。
知っているだけで終わらせることなく、実行する、断行する、一歩を踏み出すことを自らの行動で示していきたいとおもいます。
**アントニオ猪木さんのメッセージから元氣をもらったものとして、それを次代に語り継ぎ、自分自身が「闘魂」を体現するものでありたいとおもいます。**

---

<b><font color="red">$\huge{元氣ですかーーーーッ！！！}$</font></b>
<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>
<b><font color="red">$\huge{１、２、３ ぁっダァー！}$</font></b>
GitHub Pagesでサイトを公開する

# はじめに
GitHub Pagesを使ってのサイト公開をする機会があったので
手順をまとめます。

# 準備
GitHub Pagesでのサイト公開に向けてGitHubのアカウントと
公開するサイト用のリポジトリを準備してください。
無料で公開するためにはリポジトリをpublicに設定しなければなりませんので
リポジトリ作成の際にはpublicで作成してください。

# サイト公開までの流れ
ここからサイトの公開の手順の説明です。
まずSettingsページへ移動してください。

移動しましたらSettingsページのサイドバーにあるPagesをクリックしてください。
移動さきのページには色々記載されていますがいじるのはBranchと表示されている
箇所のみです。
公開用のブランチをmainに設定しましたらSaveボタンをクリックして設定を保存してください。
公開が完了しましたら画像のようにURLが表示されます。
![スクリーンショット 2023-11-16 23.55.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3568141/f5ab91b1-0c10-02e8-7628-bee237c075f0.png)

# 最後に
以上がGitHub Pagesを使用したサイト公開までの手順になります。
設定が簡単にできて全世界に自作のサイトを公開できるのでみなさんも
積極的に活用してみてください。
抽象化って抽象化しているのか？っていう話

プログラミングの話によく出てくる抽象化
---

**抽象化**（ちゅうしょうか、英: Abstraction、独: Abstraktion）とは、思考における手法のひとつで、対象から注目すべき要素を重点的に抜き出して他は捨て去る方法である[1]。反対に、ある要素を特に抜き出して、これを切り捨てる意味もあり、この用法については捨象（しゃしょう）という[1]。従って、抽象と捨象は盾の両面といえる。

引用元：[Wikipedia](https://ja.wikipedia.org/wiki/%E6%8A%BD%E8%B1%A1%E5%8C%96 )

---
説明終わり。つまり、モノやコトに対して如何に重要な部分だけを抜き出すことができるか、それが**プログラマーの力量**であると言えるわけです。

いや、、、重要な要素って何？
---
プログラミングとは、システムを**具体化**してアプリケーションを構築することです。そのために用意しているものなんだから**全部重要**です。勝手に捨てないでください。

抽象化って言ってますが、実際には

**分割と共通の発見**

それだけです。

ここからはいつものカレー話
---
抽象化していない、カレーのレシピを考えてみます。

~~~:抽象化してないカレーのレシピ
ジャガイモの皮をむいて乱切りにして、ニンジンの皮をむいて乱切りにして、
タマネギの皮をむいて乱切りにして、肉をぶつ切りにして、
すべての具材とカレールーを鍋で煮込む。
~~~

まずは、これを抽象化の第一歩である分割をしましょう。

~~~:分割したカレーのレシピ
1.ジャガイモの皮をむいて乱切りにする。
2.ニンジンの皮をむいて乱切りにする。
3.タマネギの皮をむいて乱切りにする。
4.肉をぶつ切りにする。
5.すべての具材とカレールーを鍋で煮込む。
~~~

これだけでは、抽象化という感じがしないのでここでもう一つのレシピを用意したいと思います。
ほぼ一緒ですので、そのまま分割版のレシピにしたいと思います。

~~~:分割したシチューのレシピ
1.ジャガイモの皮をむいて乱切りにする。
2.ニンジンの皮をむいて乱切りにしする。
3.タマネギの皮をむいて乱切りにしする。
4.肉をぶつ切りにする。
5.すべての具材とシチュールーを鍋で煮込む。
~~~

この２つのレシピが抽象化されたことで、共通となるレシピが見つかりました。

~~~:下ごしらえのレシピ
1.ジャガイモの皮をむいて乱切りにする。
2.ニンジンの皮をむいて乱切りにする。
3.タマネギの皮をむいて乱切りにする。
4.肉をぶつ切りにする。
~~~

~~~:分割したカレーのレシピ
1.下ごしらえのレシピで具材を準備する。
2.すべての具材とカレールーを鍋で煮込む。
~~~

~~~:分割したシチューのレシピ
1.下ごしらえのレシピで具材を準備する。
2.すべての具材とシチュールーを鍋で煮込む。
~~~
これで、重要な部分を取り出して抽象化することができました。
と言いたいところですが、なぜか抽象化されたのは下ごしらえでありカレーとは関係ないものでした。でもこれが抽象化です。重要なことではなく共通な部分を見出すための考え方でしかないのです。

ドライカレーを作ろう
---
ここで、シチューをやめドライカレーのレシピを考えてみます。

~~~:分割したドライカレーのレシピ
1.ジャガイモの皮をむいてみじん切りにする。
2.ニンジンの皮をむいてみじん切りにする。
3.タマネギの皮をむいてみじん切りにする。
4.肉をミンチにする。
5.すべての具材とカレールーを鍋で煮込む。
~~~
これを先ほどのカレーのレシピと一緒にして抽象化を見出していきましょう。

~~~:分割したカレーのレシピ
1.ジャガイモの皮をむいて乱切りにする。
2.ニンジンの皮をむいて乱切りにする。
3.タマネギの皮をむいて乱切りにする。
4.肉をぶつ切りにする。
5.仕上げレシピで具材を調理する
~~~

~~~:分割したドライカレーのレシピ
1.ジャガイモの皮をむいてみじん切りにする。
2.ニンジンの皮をむいてみじん切りにする。
3.タマネギの皮をむいてみじん切りにする。
4.肉をミンチにする。
5.仕上げレシピで具材を調理する
~~~

~~~:仕上げレシピ
1.すべての具材とカレールーを鍋で煮込む。
~~~

今度は、鍋で煮込む部分だけが抽象化されました。このように抽象化とは常に同じとは限りません。2つ以上の物事に対しての状況により変化していきます。

最後に
---
ちなみに、インターフェースや継承もこれの発展した話でしかありません。重要なものでなく必要だったら使うものという風に意識をすると使いやすくなると思います。
AWS AI Week for Developers を見てみた感想 ~生成AIについて~

# 生成AIとAWSの融合
生成AIはデジタルコンテンツの自動生成に革命をもたらし、AWSはこの分野で重要なプレーヤーとなっているようです。
Amazon SageMaker、Amazon CodeWhispererなどのAWSサービスは、ビジネスにおいて多様な応用が可能です。
これらのサービスを利用することで、業務の効率化、コード生成、コンテンツ作成の自動化などが実現可能となり、ビジネスの可能性を広げています。

# 生成AIの基本
生成AIは、テキスト、画像、音声などのデジタルコンテンツを自動生成する技術です。
この技術は、大量のデータから複雑なパターンを学習し、新しいコンテンツを生み出します。
例えば、GPT-3のようなモデルは、人間のようなテキストを生成し、クリエイティブな文章やプログラミングコードの自動生成に利用されています。
これらの応用は、カスタマーサービスの自動化、芸術作品の創出、教育コンテンツの開発など、さまざまな分野に及んでいます。

<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/354817af-28c0-00b9-63d6-449e39009335.png">

###### 生成系 AI のファインチューニングと Amazon SageMaker JumpStart | AWS AI Week For Developers (アドバンストトラック)の図を基に一部改変

# AWSにおける生成AIサービス
AWSは、生成AI技術を活用して、様々なサービスを提供しています。

<img width="180" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/4bcb3b1e-95d8-9d18-7805-7aa57a5c8a9d.png">
<img width="180" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/3a72a66c-0cbb-1a62-77d2-0b504f9c03e2.png">
<img width="180" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/0ffd14fb-61c1-fe84-a3b1-ea0d9d0d9349.png">
<img width="180" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/0cc4d6f0-3a21-0121-b0c1-6e40a23f9699.png">

* Amazon SageMaker：機械学習モデルの開発とデプロイを簡素化するサービスで、データサイエンティストや開発者が簡単に利用できます。Amazon SageMaker JumpStartというサービスについて、詳細な説明がされました。
    * Amazon SageMaker JumpStart：事前学習されたモデルを簡単に立ち上げ、操作を開始するためのサービス。
* Amazon CodeWhisperer：コード生成を支援するAIツールで、開発者がより迅速かつエラーの少ないコードを書くのを助けます。
* Amazon Polly：テキストを自然な発話に変換するサービスで、オーディオコンテンツの生成を容易にします。これらのサービスは、業務の効率化と品質向上に大きく貢献しています。
* Amazon Bedrock：様々な基盤モデルを簡単に利用できるサービス。APIリクエストによる基盤モデルの利用、データセキュリティの保証、複雑なタスクの実行支援などを提供します。

# 技術的深堀り
RAG（Retrieval-Augmented Generation）は、特定の情報を取得し、生成プロセスに組み込む技術です。
これに対してファインチューニングは、特定のタスクやデータセットに合わせて既存のAIモデルを調整するプロセスです。
AWSでは、これらの技術を利用して、カスタマイズされた、精度の高い生成AIソリューションを提供しています。これにより、特定のビジネスニーズやデータ特性に合わせたAIモデルを構築することが可能になります。


<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620022/0d146a99-2fa6-bc12-d705-8b5903099c51.png">

###### 生成系 AI のファインチューニングと Amazon SageMaker JumpStart | AWS AI Week For Developers (アドバンストトラック)の図を基に一部改変


# 導入背景とビジネスへの影響
生成AIの導入は、ビジネスに多大な影響を与えます。自動化により、時間とコストを節約し、効率を大幅に向上させることが可能です。たとえば、顧客サポートにAIを導入することで、24/7の対応が可能になり、顧客満足度が向上します。
また、コンテンツ生成やデータ分析では、AIによる迅速かつ高精度な処理がビジネスの洞察と意思決定を加速します。
AWSのサービスを活用することで、これらのメリットを手軽に実現できます。

# 未来への展望
生成AIとAWSの組み合わせは、今後もビジネスの変革を加速させるでしょう。
AI技術の進化に伴い、より精密で高度なアプリケーションが可能になります。
また、クラウドテクノロジーの普及とともに、AIの導入ハードルはさらに低下します。これにより、あらゆる規模の企業がAIを活用し、イノベーションを推進する機会を得ることが期待されます。
生成AIの今後の発展に注目し、その可能性を最大限に活用しましょう！
適切な変数名について考える

# はじめに
プログラミングを書く上で変数をどういう名前にするか決める作業は避けることができない。最近だと、「codic」や「ChatGPT」を使えば、代わりに考えてくれるが、改めて初心に戻って、どういう変数名が適切なのかまとめてみる。

# 適切な変数名とは何か
* 初見で見てもどういう変数か分かる
* 読みにくさがない
* プロジェクト、ソースコード内で命名の仕方が統一されている

以上の3点が適切な変数名と考える。

# 可読性の高い変数名
どんな変数か分かるように具体的な名前をつける。
その際、複数の単語を組み合わせて、変数の意味が一意になるように命名する。
```java
// 悪い例：userだけだと意味が広すぎる
// userの何の情報を表しているのかが分からない
String user;

// 良い例：一目でuserの名前を表しているのが分かる
String userName;
```

変数の型を暗示させる名前をつける。変数名だけから型が分かれば、変数の型を確認する手間が省ける。
```java
// 回数や数字を表すcnt(count)やnum(number)を付けることでint型を表す
int retryCnt;
int totalNum;

// Boolean型はisを先頭につけることが多い
// 他にもやhasやcanなどを先頭につけてBoolean型を表す
Boolean isEmpty;
Boolean hasToken;
Boolean canRead;
```

# 読みやすい名前
キャメルケースを使用する。言語によって様々だが、例えば、Javaの場合だと、最初の単語は小文字で始まり、それに続く単語の最初の文字は大文字にする。

```java
// 単語の切れ目が分かりやすくて読みやすい
int studentAge;
```
適切な長さの変数名をつける。意味を分かりやすくしようとしすぎて、名前が長くなることがある。返って、読みにくくなるので、そのバランスは大事である。
```java
// 適切な長さの例
int numberOfStudents;
```



# 統一された名前

略語には気をつけないといけない。人によって略仕方が違う可能性があるからである。
```java
// 最大値を表す変数
// 最大、値のそれぞれの略仕方が異なる 
int maximumValue;
int maxVal;
```
プロジェクト内でコードを書く際は、略語については共有しておく必要がある。

# まとめ
一般的な変数名の命名の仕方についてまとめた。
まだまだ、細かい命名ルールはたくさんあるので、もう少し変数名の命名規則について勉強する。
【42 Tokyo】Linux環境でminilibxを使用する

校舎PCなら下記コマンドで簡単にminilibxが使えます。
```
cc  main.c -Imlx -lmlx -framework OpenGL -framework AppKit
```
一方で私用PCだと色々と準備が必要でした。
手順をまとめたので、ご参考になれば幸いです。

:::note info
実行環境
･ VirtualBox 7.0
･ CentOS 7
:::

### 1. 関連パッケージ のインストール
```ruby:RedHat系
sudo yum install -y gcc make xorg-x11-server-devel libXext-devel libbsd-devel
```
```ruby:Debian系
sudo apt install -y gcc make xorg libxext-dev libbsd-dev
```

### 2. minilibx のインストール
intraの課題ページから”minilibx-linux.tgz”をインストールして展開する
minilibxをmakeしてアーカイブを作成する
※"libmlx_linux.a"が作成される

### 3. ファイルの格納
minilibxのヘッダーとアーカイブを下記ディレクトリに格納する
/usr/local/include/mlx.h
※mlx.hをincludeディレクトリに格納
/usr/local/lib/libmlx_linux.a
※libmlx_linux.aをlibディレクトリに格納

### 4. main関数の実装
```ruby:main.c
#include <stdio.h>
#include <X11/X.h>
#include <X11/keysym.h>
#include "mlx.h"

int event_handler(int key, void *mlx)
{
 printf("called\n");
 return (0);
}

int main(void)
{
 void *mlx;
 void *mlx_win;

 mlx = mlx_init();
 mlx_win = mlx_new_window(mlx, 300, 300, "Hello World");
 mlx_hook(mlx_win, KeyPress, KeyPressMask, event_handler, mlx);
 mlx_loop(mlx);
}
```

### 5. makefileの作成
```ruby:makefile
# minilibx_test
NAME		=	minilibx_test
SRCS		=	main.c
OBJS 		=	$(SRCS:.c=.o)
# Compiler
CC			=	cc
LIBX_FLAGS	=	-lmlx_Linux -lXext -lX11

# Rules
all:		$(NAME)

$(NAME):	$(OBJS)
			$(CC) $(OBJS) $(LIBX_FLAGS) -o $(NAME)

clean:
			$(RM) $(OBJS)

fclean:		clean
			$(RM) $(NAME)

re:			fclean all

.PHONY:		all clean fclean re
```

### 6. 動作確認
makeして実行ファイルを起動するとウィンドウが表示されます。
キーボードを叩く度に”called”とメッセージがターミナルに表示されれば、
minilibxの初期設定は成功です。お疲れ様でした。

![minilibx_start.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255462/d5420706-d779-f5c1-0e6c-a0fcba96e71f.gif)

### 7. 参考サイト
https://reactive.so/post/42-a-comprehensive-guide-to-so_long
https://harm-smits.github.io/42docs/libs/minilibx/getting_started.html
ゼロトラストネットワークとは？

サービス提供する側からはなんちゃら色々あるけど
ファイルアクセスの旅に認証が走るサービスということで
・VPNで１度認証すればあとは認証なしのザル　　＞　ゼロトラストではない
・Googleドライブのファイル　＞　ファイルアクセスの度に認可（アクセス可能か）処理が判別されて可否が判別される

ということで、各企業のネットワーク（ネットワーク境界）を経ずにアクセスされ認証されるサービスと思えばOKなのかね