OmniAICreator/Qiita-1.07M huggingface dataset:
PG、SEが資格を取得する意義

# はじめに

株式会社OMJテクノソリューションズ Advent Calendar 2023　4日目の記事です。

こんにちは、add2です。
今回は度々議論になる
「プログラマ職（以下、PG）、システムエンジニア職（以下、SE）が資格を取得する意義」
について社内への啓蒙という意味も込めて私なりの意見をまとめます。

資格取得に対するモチベーションを失いかけていた方にぜひ読んでいただければと思います！

# PG、SEに業務を遂行する上で資格は要らない
まず大前提として、
***一般的にPG、SEの業務を行うために免許などの資格は必要ない***
ということを念頭におく必要があるでしょう。

「こんなこと書かれなくてもわかっとるわい！」
というお声も聞こえてくる気がしますが、
「基本情報などの資格はいらない」
とおっしゃる方々の大半はこの前提があるがゆえに
「資格は必要ないでしょ」と潜在的に考えているような気がします。

また、先述した前提とともに「仕事がある」という状態も
相乗作用していると私は考えています。

会社員として働く以上は社内外から「仕事」が降ってくるかと思います。
当たり前に仕事が目の前にある人にとっては
「資格試験に向けて勉強、準備をして試験を受ける」
というプロセス自体が無駄に見えてくるわけです。

ここまで言語化した時点でこの記事としての役目はほぼ終えた気がします。
「結局資格ってなんでとるんだよ！！！」については次の節をご覧ください！

# PG、SEが資格をとる意義
## 主観で重視してほしいこと（技術者としての成長）
### 自分の知識証明、確認
もしあなたが新卒あるいは若手だったり、異業種転職した方（したい方）の場合は、
「自分はこれぐらい知識あります！」「自分をもっと上のポジションにつけてください！」
といったアピールになります。

確かに資格試験はおおよその人はしっかり勉強すれば合格できます。
しかし、実務歴が浅ければ浅いほど
「私は勉強をする人間です」というスタンスの表明や、
「この程度までの知識は持ち合わせています」というレベルの証明
に作用するでしょう。

### 技術への理解、業務の裏付け
こちらは業務歴に関わらないことですが、
みなさんは業務を行う中で
「先人がこうしてるから」「ネット記事にそう書いてあった」
という判断基準でタスクをこなした経験があるのではないでしょうか？

たしかに仕事をする上で「期限内に終わらせる」ということはかなり重要です。
しかし、システム固有の条件や問題が出てきてそれを解決するためにこれまでの手法が使えなかった場合はどうでしょう？
「そもそもどういう概念や思想のもとで構築されている、動作している」がわかっていないと応用のしようがありませんね。

特に基本情報などで問われる内容は、

- 一般的
- 抽象的
- 概念や思想

なものが多いですよね？
私の経験上、これがゆえに「実務で使えない」と感じる方が非常に多いように感じます。
こと基本情報においては、どちらかといえば
「実務で目に見えない」けど「わかっていないと発展させられない」
のではないでしょうか。
超簡単に言えば「基礎がわからないと応用できない」というところですね。
（それがゆえに”基本”情報なんだと認識しています）

また、よほど無計画にコーディングなどの作業を実施していない限りないかもしれませんが
「なんか動くものできちゃった」という場合は
「レビュアーに説明する」という段階で「どういう理屈なのか」「ソフトウェア品質特性は満たせているのか」
といったところで上手く説明できなかったりするわけです。
理屈がわかった上で提案、設計、実装、テスト、運用をしないと何かあった時の対応も大変になります。
（実体験として本当に大変）

以上から、一般的な基礎力を資格試験の学習を通じて習得できる（しなければいけない）という意義があると考えられます。

## 客観的な印象（PL以上の役職の思惑）
### 堅牢なチームづくり
資格はチーム構成にも影響を与えているというお話です。

ある程度組織が大きくなればどこに誰をアサインしようかなと考える必要があります。
5人程度でまわすプロジェクトとなれば「これができる人が欲しい」となるわけですね。
もちろん業務実績がかなり多めに見られるかと思いますが、
「なるほど、こいつはこの資格持ってるなら6人目として入れてみるか」
「実務経験は浅いけど成長のために少しやらせてみよう」
と本人の興味ややる気を評価して、育成目的でアサインすることもあるでしょう。

チームをコントロールする側の人はシステムに触れさせ、慣れさせ、徐々に1人月レベルの人間に育てることも業務のひとつです。
ギャンブル的思想ですが急にエース級に化けることだって（ごく稀に）あるわけです。
こうしてチームは作られ、仕事はまわっていきます。

### 社会的信用
自社サービスなどの社内開発だけで完結している場合は別ですが、社外から仕事をもらってくる場合は実は資格が重要だったりします。
こちらはフリーランスで仕事をしている人にも当てはまるかと思います。

SES的な仕事を受ける時や受託案件を受ける時に
どういったメンバーをアサインするのか示すための「スキルシート（職務経歴書とも言う）」なるものがあります。
それって転職で書くやつじゃないの？というイメージの方もいらっしゃるかもしれませんが、
SES業務をやっていてスキルシートに触れたことがない人は実は渉外担当者が書いてたりするんですよね。

もちろんスキルシートも実務実績重視で見られますが、
資格の取得状況を見て
「経験は浅いですがこういう資格持ってるので知識は問題ない」
「この分野に強そう」
という作用があります。

また、社員の大多数が同じ資格を所持することで
「この会社の知識水準はこの資格レベル以上」
という担保にもなり、仕事を受ける時にスムーズになったりします。

~~「自分の会社の信用のために資格なんかとりたくない」と思うのであれば、そもそも会社とマッチしてないんじゃないかと・・・。~~

このように資格は社会的信用にも働いてきます！

# 最後に

- 自分がやりたい業務をやるため
- 自分が思う快適な業務環境を得るため
- キャリアパスを考えたたどり着きたいポジションのため

にもぜひ資格取得をオススメします！
ただし知識だけの頭でっかちでも困るので、ハンズオンチュートリアルなどで実務イメージを膨らませることもお忘れなく！！！
低スペックPCでQiitaの記事を書くおすすめの方法

本記事は、[めんどい太郎の Advent Calendar 2023](https://qiita.com/advent-calendar/2023/mendoitarou_first_calendar) 4日目の記事です。

# はじめに

この記事は初心者が書いています。

(特に今回は内容が薄いです。)

今回は低スペックなPCでも比較的快適にQiitaの記事を書くおすすめの方法をご紹介します。

# 低スペPCの特徴

低スペPCはブラウザが重いです。

Qiitaを開こうものならカックカクになります。

Qiitaの記事編集ページはブラウザで開くので重いです。

# 方法

簡単です。

ブラウザを開かなければいい。

つまり**QiitaCLI**を使用します。

....もうちょっと続きます。

# QiitaCLI

QiitaCLIはローカル環境でマークダウンファイルを編集し、CLIを用いて記事の投稿などができるツールです。

ブラウザを開く必要がありますが、ローカル内で記事のプレビューも可能です。

プレビューはWeb鯖が起動するので、ポートを開けておけばスマホで確認なんかもできます。

また、マークダウンファイルが保存されたらリロードしなくても即反映されるのがなにげに便利です。

## セットアップ

Qiita公式さんに丸投げします()

https://github.com/increments/qiita-cli

正直公式以上にわかりやすく表現できる気がしません。

おすすめはGitHub連携をすることです。

GitHubにプッシュするだけでQiitaに記事が自動で投稿されます。便利。

CLIのテキストエディターとかを使えばサクサク動作で記事がかけます。

VSCodeが起動して普通に動くならVSCodeを用いることをおすすめします。

設定もそんなに複雑じゃないのでいいですね。

# 終わりに

いちばん重要なところを公式に丸投げしてしまったクソ記事かもしれません。

QiitaCLIの登場で低スペックPCでもQiitaの記事が書きやすくなりました！

最高ですね！

みなさんも良いQiitaライフを！
ブラウザレンダリングについて大雑把に理解する 

### ブラウザレンダリングの仕組みについて

これからウェブページのブラウザレンダリングの仕組みについて解説します。

**□ブラウザレンダリングの仕組みを理解するためのキーワード**
- Parse（パース）
- Style（スタイル）
- Layout（レイアウト）
- Paint（ペイント）
- Composite（コンポジット）

**□大まかにブラウザレンダリングするための手順について一言で理解**
ブラウザレンダリングの仕組みの手順は大きく分けると5つに分解できます。それぞれの役割について一言でまとめると下記のようになります。

1. **Parse（パース）**：コードの構造化とStyle Rulesの作成
2. **Style（スタイル）**：構造体とStyle Rulesの合体
3. **Layout（レイアウト）**：合体された構造体の配置や大きさ決め
4. **Paint（ペイント）**：各レイアウトの描画順序決めや色などの情報定義
5. **Composite（コンポジット）**：上記をウェブブラウザにピクセルとして統合

**□手順について具体的に解説**
1. **Parse（パース）**：コードの構造化とStyle Rulesの作成について詳しく解説すると、この肯定ではHTMLとCSSの解析が並行して行われます。その際にHTMLとCSSがそれぞれDOMツリーとStyle Rulesという構造体に変換されます。parseは解析という意味で使われています。DOMツリー（Document Object Model）の略でHTML文章をツリー状のデータ構造として扱うための仕組みです。Style RulesとはCSSファイル内で定義された具体的なCSSスタイルのことを指します。例えば、`.className { color: red; font-size: 14px; }` のような形式で書かれます。ここで「.className」はセレクタ（適用する要素を指定）、`color: red;` と `font-size: 14px;` はプロパティ（適用するスタイル）です。

2. **Style（スタイル）**：ここでは上記で作成された構造体どうしを紐づけしてあげる作業をしています。どのスタイルがどのHTMLの要素に適応されるのかをマッチングしてあげる作業です。ここでマッチングされた大きなツリーのことを、Render Treeと呼びます。そのTreeの葉っぱの要素のことをRendererと呼びます。

3. **Layout（レイアウト）**：この工程では、それぞれの要素の位置と大きさの計算を行います。生成された構造体をブラウザのどこに配置し、どんな大きさで描画するのかを決定します。そこで生成された構造体のことをLayout Treeと呼びます。

4. **Paint（ペイント）**：この工程では、Layoutで作られたLayout Treeに対して、描画する要素の順番を決めます。ペイントの工程で作られる構造体のことをPaint Recordsと呼びます。

5. **Composite（コンポジット）**：この工程では、レイヤーを一つのビジュアルとして合成する作業を行います。それによって最終的なページが形成されます。これは、ペイントされた各レイヤーを重ね合わせ、最終的にユーザーに表示されるウェブページを作成するプロセスです。

### ◆コラム：レンダリングエンジンの違い
レンダリングエンジンはそれぞれのブラウザごとに異なります。これは、各ブラウザがウェブページを解析し、表示するために使用する独自のソフトウェアコンポーネントです。ブラウザが独自のエンジンを持っているため、同じウェブページでもブラウザによって表示が異なることがあります。

| ブラウザ名 | レンダリングエンジン | URL |
| --- | --- | --- |
| Safari | Webkit | [WebKitの詳細](https://ja.wikipedia.org/wiki/WebKit) |
| Chrome | Blink | [Blinkの詳細](https://ja.wikipedia.org/wiki/Blink_(%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%B3)) |
| Firefox | Gecko | [Geckoの詳細](https://ja.wikipedia.org/wiki/Gecko) |
| Edge | EdgeHTML | [EdgeHTMLの詳細](https://ja.wikipedia.org/wiki/EdgeHTML) |

ブラウザレンダリングの理解がウェブ開発において重要な理由は、特にパフォーマンスとユーザーエクスペリエンスの観点から重要です。以下のようなシナリオでその知識が役立ちます。

- **ウェブゲームの開発**：アプリケーションで開発したゲームをウェブ環境でも適応させる際、ブラウザごとに異なるレンダリングエンジンに対応する必要があります。
- **大規模ウェブサービス**：TwitterやInstagramのようなサービスでは、高速かつヌルヌルな操作性、効率的なリソース使用、バグの最小化など、多くの要素を考慮する必要があり、ブラウザレンダリングの理解が必要です。


各ブラウザの違いを理解し、それぞれに最適な設計や開発を行うことが、ハイパフォーマンスなウェブサービスを作るための鍵になるっぽいです。

ブラウザレンダリングを知ることは、ウェブサービスでハイパフォーマンスを出すことに繋がると思いますので、上記で大雑把に理解できたら、より詳細な記事を参照することをおすすめします。

また理解したことがあればアウトプットします。

### ◆参照URL
[フロントエンジニアなら知っておきたいブラウザレンダリングの仕組みをわかりやすく解説！ | Tech Blog](https://blog.leap-in.com/lets-learn-how-to-browser-works/)

[ブラウザの仕組み  |  Articles  |  web.dev](https://web.dev/articles/howbrowserswork?hl=ja)

[ブラウザのレイアウトとペイントを知る](https://zenn.dev/silverbirder/articles/b58ba3f8666a57)

[ブラウザレンダリングの仕組み](https://zenn.dev/ak/articles/c28fa3a9ba7edb)

[Webページがブラウザに表示されるまでに何が起こるのか？](https://zenn.dev/ak/articles/61d25099295372)

[レンダリングする | ちいさな Web ブラウザを作ってみよう](https://browserbook.shift-js.info/chapters/rendering)
Windowsのソフトから wsl2 のファイルにアクセスする方法

# Windowsソフトのフォルダツリーに WSLが表示されない!!!
WSLに開発環境を移行したのはいいが、Windowsからアクセスする分からなかったので解決策を記録しておきます


## FTPクライアント（WinSCP）からWSL2にアクセス出来ない
＊WinSCPを使用

エクスプローラーであれば表示される LINUX ドライブ？が表示されない


## 解決方法
### パターン１
#### エクスプローラーからパスを取得する方法
エクスプローラーで辿って

![wsl2Drive.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522015/5662d53f-6b46-adc7-fce5-e03910b0d4bd.png)
アドレスバーをクリックすればパスが取得できる
`\\wsl.localhost\Ubuntu`


---
### パターン２
#### WSL から パスを取得する方法
現在のディレクトリのわかるコマンドpwdと
```
pwd
```

* コマンド：wslpath  wslとwindownsのパスを相互変換する
*  -w をつけてパスを直接入力
```bash:wsl shell
# wslpath -w フォルダ名
wslpath -w /home/ユーザー名

# \\wsl.localhost\Ubuntu\home\ユーザー名
```

- またはカレントディレクトリに移動して
```bash:wsl shell
wslpath -w $(pwd)

# \\wsl.localhost\Ubuntu\home\ユーザー名

```
   置換で引数とする（｜パイプラインでは出来ない）

windowsからアクセスできるフォルダが表示される


## WINDWOSソフトでの操作


[**WinSCP**] の
ローカル ⇒ 移動 ⇒ ディレクトリ・お気に入りを開く
ディレクトリを開くに [\\wsl.localhost\Ubuntu\home\ユーザー名] を貼り付ける
- 貼り付けたあとに 追加 もしておくと便利です

## 他のWindowsソフトからは

開く や 保存 時のファイル名を入力する欄に
取得したフルバスとファイル名を入力すれば直接書き込めます。
Railsのバリデーション – presence / allow_nil / allow_blank の違い・役割の整理

# presence

値が空の場合にバリデーションエラーを起こす。

>  presence
> このヘルパーは、指定された属性が空（empty）でないことを確認します。値がnilや空文字でない、つまり空でもなければホワイトスペースでもないことを確認するために、内部でObject#blank?メソッドを使っています。

例:

```rb
validates :foo_column, presence: true,
```

# allow_nil

値がnilの場合にバリデーションをスキップする。

例:

```rb
validates :foo_column, format: { with: /REGEXP/ }, allow_nil: true
```

あくまで役割は「バリデーションのスキップ」なので、これを指定したからと言って値にNULLを許可するわけではない。
バリデーションを何も書かなければ、RailsのバリデーションとしてNULLは最初から許容される。

つまり何もバリデーションを指定せずに `allow_nil: true` を指定しても意味がない。
(エラーが発生する)

例:

```rb
validates :foo_column, allow_nil: true

# raise ArgumentError, "You need to supply at least one validation" if validations.empty?
```

この指定は属性のバリデーション全体ではなく、バリデーション指定の単位で評価される。
たとえば次のように書いた場合、値がNULLであっても、1行目のバリデーションはスキップされるが、2行目のバリデーションには引っかかる。

```rb
validates :foo_column, format: { with: /REG/}, allow_nil: true
validates :foo_column, format: { with: /EXP/ }
```

# allow_blank

allow_nil と同じように動くが、こちらは値がblankの場合にバリデーションをスキップする。

すなわち presence と allow_blank を同時に指定しても意味がない

例:

```rb
validates :foo_column, presence: true, allow_blank: true
```


# ガイド

https://railsguides.jp/active_record_validations.html



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
macでPythonを起動しようとするとコマンドラインツールのインストール要求が繰り返し表示される件の解消

macでPythonを起動しようとすると、以下のエラーが発生した。 コマンドラインツールをインストールしても、再度表示される。

```sh
% python 
xcode-select: Failed to locate 'python', requesting installation of command line developer tools.
```

## 修正方法

コマンドラインツールの`python`コマンドとして、`python３`のシンボリックリンクを置くと直る。

```
sudo ln -s /Library/Developer/CommandLineTools/usr/bin/python3 /Library/Developer/CommandLineTools/usr/bin/python
```

この修正方法は以下でコメントされていた。他にも方法があるようだが、私の環境では上記で修正された。

https://developer.apple.com/forums/thread/704099


以上
label タグでの for の省略

チェックボックスで `<label>` タグを付けないとクリック範囲が狭まって不便です。`<label>` タグでチェックボックスを囲めば記述がすっきりします。

常識なのかもしれませんが、自分はこれを知らなくて `for` は必須だと思い込んでいたので、メモしておきます。

# 概要

チェックボックスの横に文字を書くだけだと、文字をクリックしても反応しません。

```html
<input type="checkbox" />check1
```

※ 一昔前はこのような UI をよく見掛けました。

チェックボックスとラベルを関連付けるには、`<input>` で `id` 属性を指定して、`<label>` で `for` 属性を指定します。

```html
<input type="checkbox" id="check2" /><label for="check2">check2</label>
```

チェックボックスを `<label>` で囲めば、関連付けは明確となるため `id` や `for` 属性は不要となります。

```html
<label><input type="checkbox" />check3</label>
```

※ 一般的な運用（チェックボックスをスクリプトから参照する等）では `id` 属性が必要ですが、ここではクリックの連動だけを問題にしています。

<p class="codepen" data-height="210" data-default-tab="html,result" data-slug-hash="mdvLBwL" data-user="7shi" style="height: 210px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/7shi/pen/mdvLBwL">
  checkbox &amp; label</a> by 七誌 (<a href="https://codepen.io/7shi">@7shi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# 参考

https://developer.mozilla.org/ja/docs/Web/HTML/Element/label

> 他の方法として、 `<input>` を直接 `<label>` の内側に入れることができますが、この場合は関連付けが明確なので、 `for` および `id` 属性は必要ありません。

# 経緯

自分のサイトを Edge の開発者ツールで見ると、アクセシビリティのエラーが出ていました。そこで「さらに読む」のリンクを見ると、例が示されていました。

https://dequeuniversity.com/rules/axe/4.4/select-name?application=axeAPI

> The label can also be implicit by wrapping the <label> element around the select:
> 
> ```html
> <label>State: <select></select></label>
> ```

※ これは `<select>` についての説明ですが、`<input>` でも同様です。
MacでSteamLinkのフルスクリーンモード

# SteamLink上でフルスクリーンのショートカットコマンドを受け付けない。

MacOS Venture 13.6

ショートカットを色々試しましたが効かなかったので、記事にしました。
基本的なMacの操作かもしれませんが、そもそもマウスがロックされてしまう事が問題で、これを解決する方法があれば、またアップデートしたいと思います。

## フルスクリーン化
マウスで緑色の最大化ボタンを押す。
クリック操作でウィンドウをアクティブにしてしまうと、ウィンドウ内にマウスが固定されるので、Cmd+Tabでウィンドウを非アクティブ化して、その状態で最大化をクリック

## フルスクリーン解除
MissionControlを開いて、SteamLinkの左上に見えるアイコンをクリックするとフルスクリーンが解除されます。

![t1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128851/078548e0-e706-bb0d-1e5c-7f1a39320097.png)
Serverpod 使わないの？

## about me
還暦を過ぎて、この先何して暮らそうかなあ、というときに、
そうだ、アプリをつくろう、と思いたち、
でも、アプリってどうやって作るんだ？　というレベルで
いきなりFlutter大学に入って２年半
倦まず、弛まず、じりじりと前進している専業主婦。

え、そういう人が何か書く場所じゃないんだけどな、
って思われるの百も承知で、参加しました。
Flutter界の強々に混じって、何か披瀝しよう、
などという、不遜な意図はありません。
逆に、これぐらいど真ん中に飛び込んで叫んだら、
どなたか助けてくださらないかな、という気持ちです。

## Why Serverpod ?
userが情報を持ちよって作る年表のDatabase、を作っています。
Wikipediaの年表特化版、みたいな感じです。
Flutter初学者の常で、まずはFirebaseを使いましたが
検索に満足できず、MySQLに変えて半年ほど過ごしました。
そこでまた壁に突き当たって、途方に暮れていたときに
Serverpodに出会ったのです。
Supabaseが（私の周りで）話題になるよりちょっと前でした。
タイミングが違ってたら、Supabaseにしてたかもしれません。

https://serverpod.dev

## Why Not Serverpod ?
使い始めたときは、公式しか情報がなくて
ともかく一所懸命、英語を読みました。
そのうち日本語の記事も出るだろう、って期待しながら。
でも、出ないんですね。
仕方ないから、疑問があれば直でSeverpodのissueやdiscussionにお邪魔します。
すごく丁寧に対応してもらえます。
最近は、英語の記事や動画が、公式以外にぼちぼち出てきましたが、
それも、ぼちぼち、ですね。
コミュニティーの人数も少ないし、
日本語記事は皆無です。

人気ないの？　なんで？　なんか問題がある？

もちろん「使ってるけど発信してないよ」という方もいらっしゃるでしょう。
でも、統計的にこの情報の少なさは、利用者の少なさと見てよいと思います。
(FlutterKaigi2023でServerpodに関する発表があったと聞いていますが
詳細を入手できていません･･･）

https://medium.com/search/posts?q=Serverpod

https://www.reddit.com/search/?q=serverpod

https://qiita.com/search?q=serverpod

https://zenn.dev/search?q=serverpod

https://www.youtube.com/results?search_query=serverpod

## How About Serverpod 1.2 ?
実はもう、そろそろuploadしようかな、と思ったりするのですが、
Serverpod 1.2でだいぶん変わりそうなので
それをじっと待っているところです。
待ちながらも、不安なわけです。
ただ単に、

ほかにいっぱい、便利なやつがあるからさ。

ということなら、それでもいいんです。
でも、「ああ、あれは実は問題ありなんだ」ってことになったら
残り人生全振りしている身としては、かなり辛いですから。

## Honestly, what do you think about Serverpod ?
ということで、AdventCalendarに参集の強々の皆さんに質問です。
Serverpodのこと、どう思ってらっしゃいますか。

- バリバリ使ってる（でも発信してない）
- 使ってないけど、使ってる人（製品）を知ってる
- 興味がない
- 興味はあるけど積極的じゃない
- 魅力がない
- 問題ありだから係わらない
- etc

コメントいただけたら、うれしいです。
このまま行くか、Supabaseでやり直すか、
決断の道しるべにしたいです。

## Extra Info
きたる12月9日に行われるFlutter Conf India 2023で、
Serverpodがスポンサーになってます。Viktorが話もするらしい。
インドでは人気なのかな。それとも梃子入れ？

https://flutterconf.in/home

## Happy Flutter ! Merry X'mas !!
つたないながらもServerpodでつくってるProjectは

https://github.com/dongri727/acorn

日々の歩みを支えてくれるのは

https://flutteruniv.com/?invite_id=9hsdZHg0qtaMIr6RPRulAaRJfA83
Google BigQueryを触ってみる（その１）

## 触ってみるために使った本


集中演習 SQL入門 Google BigQueryではじめるビジネスデータ分析 (できるDigital Camp)
<img width="250" src="https://m.media-amazon.com/images/I/81vEaqWTJ5L._SL1500_.jpg">

https://www.amazon.co.jp/%E9%9B%86%E4%B8%AD%E6%BC%94%E7%BF%92-SQL%E5%85%A5%E9%96%80-Google-BigQuery%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90-%E3%81%A7%E3%81%8D%E3%82%8BDigital/dp/429501074X


## BigQueryを無料で使うには
BigQueryを無料で使う方法として２つ選択肢があります。
1. Google Cloud Platfornの無料トライアルを開始する
2. BigQueryサンドボックスを利用する

１でアカウントを開設するのが通常の方法のようですが、欠点としてクレジットカードの登録が必要となります。
たいていの勉強の範囲での利用では無料枠を越えないので、課金される心配はないですが、登録自体がめんどくさいです。

２はBigQueryを無料でお試しできるオプションのような形で、クレジットカードの登録も必要ないので、今回はこちらでアカウント開設しました。

## やってみる

### BigQueryサンドボックスでアカウント開設

この[公式ドキュメント](https://cloud.google.com/bigquery/docs/sandbox?hl=ja)にサンドボックスの説明が載っています。
![キャプチャ3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164069/bdf71e96-e20d-2b7a-4217-5342ec14cdfc.jpeg)

1. BigQueryに移動をクリック
1. Google Cloud Platformのページが表示される
1. 好きなGoogleアカウントでログインする
1. ナビゲーションメニュー（三）からBigQueryをクリック

こんな画面になる
 ![キャプチャ3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164069/de4dd99a-405e-e55c-e580-fe44c7f9c6e3.jpeg)
準備の準備完了！


### プロジェクトを作る
左上の赤枠に記載されているのがプロジェクト名です。
クリックすると複数のプロジェクトから選択できるポップアップが表示されます。
新しいプロジェクトを作るときは右上の「新しいプロジェクト」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164069/4371b72f-190d-c12a-2ab3-f4565bece0c9.png)

今回は本に倣って以下のようにしました。プロジェクトIDの下６桁の数字は自動でつけてくれたのでそのままです。
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164069/4e81fc6c-9b12-7294-e76d-d9322dc00aff.jpeg)

### データセットを作成
テーブル＝表形式のデータを入れるためのデータセットを作ります。

プロジェクトの横にある３点マークをクリックします。
ポップアップが表示されるので、データセットを作成をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164069/059ce52d-57cf-7521-bcd2-b1b7475c40a9.png)

今回も本に倣って以下のようにしました。
リージョンの設定は本になかったので、一旦東京リージョンにしておきました。
![キャプチャ2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164069/04496dec-fbbc-8178-1b62-168cab586b38.jpeg)

準備完了！（まだ）


### スキーマを定義してテーブルを作成する

使っている本ではサンプルデータの配布がされているので、事前にダウンロードしておきます。[ここから](https://dekiru.net/article/21640/)どうぞ。



画面左のデータセットをクリックします。
データセット情報が表示されるので、右上のテーブルを作成をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164069/7cd0c4f2-7ca9-91ef-8d27-dc1a63cb81bc.png)

本に倣ってソースの設定はこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164069/5a016ff8-727a-ab8f-97ae-81f005e18ed2.png)

スキーマの設定は手動でやることをおすすめされています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164069/c0e0536e-4c8e-653d-8e15-bbccb0edfff8.png)

大事なのが、スキップするヘッダー行を１に設定すること。
これで、CSVファイルの１行目のフィールド名は無視されて取り込まれる設定になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164069/aa4af9a0-c629-cfee-c9f4-31e742d912f9.png)

準備完了！
MacにおいてRancher Desktopの容量を減らすにはFactory Resetするしかない

そもそもRncher Desktopとはいう方はこちらの記事などを参考

https://zenn.dev/miyajan/articles/migrate-from-docker-desktop-to-rancher-desktop

## 背景

最近、Macでのストレージ容量が不足していることに気付きました。

原因を調査するためにduコマンドを使用したところ、Rancher Desktopが55GBを占有していることが判明したので、その原因を調査しました。

```sh
# 　5GB以上の大きなファイルやフォルダを検索
$ sudo du -g -x -d 5 / | awk '$1 >= 5{print}'
55	/Users/Library/Application Support/rancher-desktop
```

## 調査結果

Rancher Desktopが起動する仮想マシン(VM)によってディスクスペースが大量に使用されていることが原因でした。

MacでDockerイメージを作成する際、Rancher DesktopのVMは追加のメモリを確保します。このメモリはdiffdisk（永続ディスク）に割り当てられるため、**Dockerイメージやコンテナを削除しても、VMで使用されるdiffdiskの容量は減少しません。**

デフォルト設定では、diffdiskの最大サイズは100GBに設定されています。

現時点でこのVMのディスクサイズを減らす唯一の方法は、Lima VMを削除し、Factory Resetを通じてディスクを再作成することだけみたいです、、、

関連GitHub Issue

https://github.com/rancher-sandbox/rancher-desktop/issues/2285

## Rancher Desktopの仕組み

![公式](https://docs.rancherdesktop.io/assets/images/how-it-works-rancher-desktop-6dab31f26a1cf4a78759201d8c411316.svg)


#### 1. Rancher DesktopでのVMの利用

Rancher Desktopは、VMを使用してKubernetes環境を提供します。これにより、ユーザーのOSに影響を与えずに、安全かつ独立した環境でKubernetesを実行できます。VMはRancher Desktopの核心技術であり、ユーザーが直接操作することは少ないですが、背後で重要な役割を果たしています。

#### 2. Rancher DesktopでのLimaの利用

特にmacOS環境でのRancher Desktopでは、Limaを利用してLinux VMを提供します。これにより、macOSユーザーは手軽にLinuxベースのKubernetes環境を実行し、テストできます。Limaは、macOS上でLinux環境を作成するために特化したVMツールであり、Linuxのコンテナーやアプリケーションの実行を容易にします。

#### 3. Windows/Mac/Linuxでの違い

Windows: Rancher Desktopは通常、Hyper-VまたはWLS2を利用してVMを作成します。
Mac: macOSではLimaを使用し、Linux VMを作成します。
Linux: Linux上では、Rancher DesktopはDockerや他のネイティブツールを直接利用できます。VMは不要です。
まとめ
Factory Reset以外の解決策が提供されることを期待しています。また、永続ディスクの容量を増やすには、一度Factory Resetが必要であることも注目すべき点です。

https://docs.rancherdesktop.io/references/architecture

## 最後に

Factory Reset以外の解決策が提供されればいいなぁ、、、
【フォーマル度別】よく使える日程調整ツール3選

# はじめに
最近**日程調整**をする機会が多くなってきたので、よく使うツールを3つまとめました。

# ★☆☆ / 以下の日程でご都合いかがでしょうかメーカー
気心が知れてる友人達に向けてチャチャっと確認するのに便利です。

https://shirasaka.tv/ikano/

# ★★☆ / 調整さん
言わずもがなの調整さん。これさえ使っておけばとりあえずは問題なさそう。

https://chouseisan.com/

# ★★★ / Attendar

UIもきれいで、よりフォーマルな印象を持たれやすそうです。
調整さんと同じく操作も直感的で使いやすいです。

https://attendar.com/
Rubyで、Gem::FilePermissionErrorが表示された時の対処

久々にRubyを触っていると、gem install minitestで権限エラーになりました。
```
ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.6.0 directory.
```
調べてみると、原因はシステムのRubyが使われているから、
権限エラーになっているとのことでした。
```
% which ruby
/usr/bin/ruby
```
rbenvのRubyが使われる設定になっていません。
.zshrc(bashの人は.bashrc)に、以下の記述を入れました。
```
% vi ~/.zshrc
```
```
[[ -d ~/.rbenv  ]] && \
  export PATH=${HOME}/.rbenv/bin:${PATH} && \
  eval "$(rbenv init -)"
```
自分のユーザのhomeパス + rbenvのRubyパスが出るようにという記載ですね。

シェルの再起動を行います。もしも、エラーがあれば、再起動時にエラーが吐かれるので、修正が必要。
```
exec $SHELL -l
```
```
which ruby    
/Users/yusuke/.rbenv/shims/ruby
```
```
% gem install minitest
Fetching minitest-5.20.0.gem
Successfully installed minitest-5.20.0
```
これで権限エラーが解消されました。
二項分布を例で理解する

# この記事について

2023年11月から、データ分析の学校に通い始めた統計初心者です。

二項分布について、数式とかじゃなく「いつ使うのか」をざっくり理解するためにまとめてみます。

# 二項分布いつ使うのか

## そもそも二項分布とは

結果が２つの試行を何度も繰り返すことによって起きる分布

## 結果が２つとは

たとえばこんなこと

- ひとつのコインを投げて表が出るか裏が出るか
- 一人の社員が一定期間内に会社をやめるかやめないか
- 一人の既存顧客が一定期間内にサブスクを解約するかしないか
- 告白が成功するかしないか
- 一人の顧客がある商品を買うか買わないか
- 一人のユーザーがあるボタンをクリックするかしないか
- 一人の人がバレンタインデーにチョコレートをもらえるかもらえないか

## 二項分布のパラメーター

- 試行回数(n)
- イベントの発生確率(p)

上記のパラメータから導き出せる数値
- 平均(np)
- 分散(np(1-p))

## 二項分布を使って知れること

:::note
結果が２つの事柄（A or not A）について、結果がAとなる確率がpの場合、n回の試行中、x回Aが起こる確率は？
:::

## 具体例① ３年で３割辞める新入社員が、３年でx人辞める確率

二項分布の命題に当てはめると・・・

:::note
新入社員が３年以内に辞める確率が30%の場合、100人の新入社員の中で、３年後に50人が辞める確率は？
:::

ここで、「３年後」はあくまで発生確率と成功確率（ある事柄が起きることを成功というので、ここでは「辞めること」を「成功」と言っている）の条件を揃えるためのもの。

なので「３年後」の「３」という数字はパラメータにはあらわれてこない。

３年後に３割辞める若者が１年で何割辞めるか、という問いになると、発生確率の条件（３年で）と知りたい成功確率の条件（１年で）がずれてしまうので、答えられない。

パラメータは・・・

- ３年以内に辞める可能性が30% - これが発生確率 p
- 100人の新入社員 - これが試行回数 n
- ３年後に50人が辞める確率 - これが成功回数 x

## Excel の数式

上記をExcel で計算すると、こんな感じになる。

```
# 書き方 BINOM.DIST(成功回数x,試行回数n,発生確率p,FALSE)
=BINOM.DIST(50,100,0.3,FALSE)
```

答えは意外にも（？）0.0013%。

新入社員が3年で3割やめる会社でも、３年後に新入社員が半分に減っている確率は0.0013%（1万年に13回）しかないということですね。

## 分布のグラフを作ってみる

これを、50回以外の数にもあてはめて、ざっくり確率の分布を見ていくとこんな感じになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/b0724b69-a728-c5da-0832-57e5b28511d4.png)


横軸＝人数、縦軸＝その人数が３年で辞める確率です。

- ３年で平均３割辞める会社ということで、３０人辞める可能性がいちばん高いというのは直感的にも納得。
- だいたい25〜35人の間に集中していて、20とか45の可能性もゼロではない

ということで、その範囲の数字をもう少し細かく見ていくと・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/ee1643f1-4560-e4f2-3c43-0626584e407a.png)

→ いちばん可能性が高いのは３年で30人辞めていることだけど、32人辞める確率よりは28人しか辞めない確率のほうが低いとか、そんな感じのことがわかる。

## 具体例② ナンパ成功率1%の人が、100人に声をかけてもナンパに一度も成功しない確率

ナンパの成功率が1%というのは、100回ナンパしたら常に1回成功するという意味ではない。

100回中、運良く2回成功することもあれば、一度も成功しないこともあるでしょう。

…運良く2回成功するのと、一度も成功しないのでは、どちらの可能性が高いか？ という問題も、二項分布で解くことができます。

## Excel の数式

ナンパに一度も成功しない確率をExcel で計算すると、こんな感じになる。

```
# 書き方 BINOM.DIST(成功回数x,試行回数n,発生確率p,FALSE)
=BINOM.DIST(0,100,0.01,FALSE)
```

→ 答えは36.6%。つまり100人にナンパするのを100日繰り返したら、そのうち36〜7日くらいは、一度も成功しない日があるということ。

## 分布のグラフを作ってみる

これを、0回以外の数にも当てはめて、グラフを作ってみるとこんな感じになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/f0c2a4c4-92d9-6bbe-1acb-d28501e9f169.png)

運良く2回成功する確率は18.49%で、一度も成功しない確率のおよそ半分でした。

## 変数を変えて分布を比べる

ナンパする人数を増やしていくと、この分布はどう変わるのかを見てみると、こんな感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/9c233fd8-b5ea-8c7c-29b3-91aacf54bdaf.png)

声をかける人数が500人を超えてくると、成果ゼロの日は限りなくゼロに近くなるようです。

人数勝負じゃなく、成功率を上げるのはどうか？ ということで、成功率が1%ずつ上がった場合の分布を見てみると、こんな感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/6bc1c7a0-5bb4-2272-6ef1-d0d511dae7ac.png)

なるほど、成功率が1%→2%に上がるだけで、成果ゼロの日（1日かならず100回ナンパするとして）の発生確率は半分以上に減らせるんですね。

# 以上

記事を書きながら二項分布の理解を深めようという目的で書き始めましたが、書いた本人の理解はだいぶ深まった気がします。

読んでくれた方にも少しはお役に立てれば幸いです。
【CSS】文字の無限スクロールアニメーション

## はじめに

よくある文字が右から左に、左から右に無限スクロールしているアニメーションをつくった

## 参考サイト

以下のサイトの考え方を参考
https://note.com/smatsune/n/n25d5cfb2c42d


## コード
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="VwgxzPv" data-user="cats-park" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/cats-park/pen/VwgxzPv">
  Untitled</a> by MASA (<a href="https://codepen.io/cats-park">@cats-park</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### 注意点

:::note warn
テキストは表示領域より大きくないと、空白ができてしまう
:::

:::note warn
 iPhoneとかだとアニメーションの繰り返し時に一瞬ちらつく
 delayを0.1s入れるとそれが消える。。。
 以下、参考
 https://qiita.com/OnederAppli/items/a69741aa0df3f942dbc3
:::

## おまけ

jsを使用してHTMLに文字をたくさん書かなくていいやりかた

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="qBgYXVE" data-user="cats-park" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/cats-park/pen/qBgYXVE">
  Untitled</a> by MASA (<a href="https://codepen.io/cats-park">@cats-park</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 最後に

無限スクロールを調べるとめっちゃテキストを配置してゆっくりスクロールして実質無限スクロール見たいのが結構多くて嫌だったのでちゃんと無限スクロールできるやつ作った
Rails - マイグレーションで既に作成済みのカラムのNULL制約をつける・外す時は change_column_null 

# NULL制約を付ける場合

```rb
class ExampleMigration < ActiveRecord::Migration[7.1]
  def change
    change_column_null :examples, :foo_column, true
  end
end
```

# NULL制約を外す場合

```rb
class ExampleMigration < ActiveRecord::Migration[7.1]
  def change
    change_column_null :examples, :foo_column, false
  end
end
```

# 注意

change_column だと null 制約以外も色々と書かないといけないのでよろしくなさそう

```rb
change_column :examples, :foo_column, :string, :null => :false
```

# Railsガイド

Railsのマイグレーションは色々な種類があって何が推奨かのか分からなくなりがちだが、Railsガイドの一覧を参考にするとわかりやすそう

<img width="764" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/be4c3820-3708-4b09-a956-1dd24afa7697">


https://railsguides.jp/active_record_migrations.html

# Doc


https://railsdoc.com/page/change_column_null


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
オセロの弱い解決の解説記事を読んで思うこと

オセロAIの開発者が語る記事が興味深かった。

https://qiita.com/Nyanyan_Cube/items/a373da3157cdd117afcc


https://arxiv.org/pdf/2310.19387.pdf


オセロはあまり強くもなく、AIの作り方全く知らないが、オセロはすでに全解析されているのかと思っていた。手数を調べてみると10^60通りとでるが、これは、打てる手場所が平均で10あることと、64-4=60手で終わることから来ているようだ。初手は対称性から1通り、2手目は3通り。10^60よりは少ない気がするが。

# 盤面の状態を保存する方法は?
00000000
00000000
00000000
000WB000
000BW000
00000000
00000000
00000000
こんな文字列だったら、256Byte
4通り=2bit/マスだったら、2*8*8=128bit=16Byte
3通りだったら
3*3*3*3*3*3*3*3=81*81=6561<2^13=13bit
13*8列=104bit=13Byte以下

64マスに手順を数字で保存するなら、白黒を保存する必要ないから、
60<64=6bit/マスだから、
6bit*64マス=384bit=48Byte
1Byte/マスで64Byte

盤面を保存するのではなく、手順のみを保存する場合、a1~h8まで使う方法なら、
2Byte*60手=120Byte
１手は60通り以内だから、6bitで足りるので、
6bit*60手=360bit=45Byte
1Byte使ったとして、
1Byte*60手=60KB

※無駄を０にはしてない。
※更に圧縮したら小さくなる。

# 結論
盤面のみの保存なら、最小で13Byte、実用的なのは16Byte
手順込みなら、48Byte〜実用的なのは64Byte
手順のみなら、45Byte〜実用的なのは60Byte

10^59通り x 16Byte/1024/1024/1024/1024≒16 x 10^47TB
これではすべてを保存しておくことも全く不可能。

平均2通りの手に枝切りできたとして、
2^60=1024^6
16Byte x 1024^6=1024 x 1024*16TB

論文には最終的に1.5*10^9局面を生成とあるので、それを保存するだけでも
16Byte*1.5*10^9=16*1500000000=24000000000Byte≒24GB
ざっくり24GBも必要になることがわかる。

枝切りだけで、場合の数を減らすのが難しいので、
最善を打つという前提、
全体を「前半」「中盤」「後半」に分ける、
ことで、減らしているのかな？？？？

ともかく、シンプルルールのオセロで、こんなに大変だなんて知らなかった。
プロジェクト成功　｜　スキル獲得に関して　大切にしている考え方の1つ


## 全体像

あなたは、何かプロジェクトを取り組もうとしている

そのプロジェクトが成功すれば、あなたはなにかしらのメリットを受け取る

だから、成功させたい

そのプロジェクトは、どうやったらうまくいくか

結論は、`必要なピースを全て揃えること`


## １番最初

相手本位かどうか

これで、そのプロジェクトの成功可否の9.9割が決まる

アイデア５割：技術５割

の

アイデアの部分は、相手本位かどうか

## 時計は200個のパーツでできている

時計は、だいたい200個の部品からできていると言われている

1個でも足りなかったら、時計ではなくなる

ちゃんと動かなくなる

だから、全ての部品を完全にはめていかなければならない

丁寧に作り上げれば、時計は出来上がる

## １個のピースは、40回で仕上げよう

あなたの中に、200個のスキルピース（本当に200個かどうかはわからないから真に受けないように）を作ることで、

プロジェクトがコンスタントにうまくいくんだとすれば、

全部揃えなくてはならない

その時の考え方で重要なことは、目安だ。

ダラダラしないように、モチベーションを継続したい

人間は、馴化する生き物だ

なので、40回、正しいフォームで練習すれば、必ず必要水準以上、習得できる


## 肝心なのは、9つ

1. 鏡を見る
1. 本気でやり始めたら４年で人生変わる
1. フィードバックを受ける
1. ゾーンに入る（デスマーチレベル）
1. TTPする
1. 業界トップの人物に直接会う
1. 24時間意識する
1. 人を信用しない
1. やるべきことを淡々とこなす人間には誰も勝てない
ChatGPTプロンプトの整備過程 - chatGPTと行う水平思考クイズ編 - 

## 本記事の内容

- chatGPTプロンプトを整備する過程で何をやっているのか
    - 具体例の提示
    - どれくらいの時間をかけている？

## プロンプト整備過程

### 例題. 水平思考クイズを行うためのプロンプト
「ウミガメのスープ」とは水平思考クイズの俗称で、出題者から（多くの場合不可解な状況設定の）問題文が与えられ、回答者はその問題に答えるためにイエスかノーで答えられる質問を繰り返して、問題に回答するというクイズです。

このような問い形式はビジネスイシューの掘り下げ、言語化にも使えると思い、このプロンプトを整備しようと考えました。


### まずはストレートに誘ってみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/aefa454d-5745-add0-0f93-dcfc860aa35e.png)
海亀は保護しろと怒られた。。ゲーム名だと認識してもらえませんでした。
ゲームであることを示します。すると、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/1f1c7d2c-3a6f-c496-72d1-7c539216f916.png)

新たなルールを提示してきました。(これはこれで興味深いのです)
ルールを教えてあげる必要がありました。

### ルールとサンプルの提示

ルールと回答のサンプルを提示してみました。
ここでは、サンプルに(架空のストーリーとはいえ)　XXXXな言葉(自○)が混じっているため、OpenAIからwarningが出ています。サンプルは、他のものに変えた方が良さそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/ec4ed104-572c-355f-92e5-1bb41cd745bf.png)


ゲーム自体を開始することはできるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/d3cb6dfb-4b2c-859e-7817-357a1851dcfa.png)

対話が進むにつれ、サンプルのお題と本当のお題との混濁を起こしたため、サンプル自体の提示をなしの方が良さそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/49156019-fee8-6776-71b5-c804723d5649.png)

### ルールの提示(改善後)

テストプレイしながらプロンプトを改善していきます。
途中で勝手に終わったり、1問づつ質問しなかったり、といった挙動をみて、ルールを追加していきました。

v1
```markdown
「ウミガメのスープ」というゲームで遊びましょう。
「ウミガメのスープ」に代表される、水平思考クイズとも呼ばれるこのようなクイズは、
出題者1名と回答者に分かれて遊びます。出題者がクイズを出し、
回答者は「YES」「NO」「関係ありません」のいずれかで答えられる質問を出題者にし、
答えを推理していくというものです。
ルールを理解したら、OKとだけ回答してください。
```

v2
```markdown
水平思考クイズとも呼ばれるこのようなクイズは、出題者1名と回答者に分かれて遊びます。
出題者がクイズを出し、回答者は「YES」「NO」「関係ありません」のいずれかで答えられる質問を出題者にし、
答えを推理していくというものです。ルールを理解したら、OKとだけ回答してください。
```

v3
```markdown
水平思考クイズと呼ばれるクイズ。
出題者がクイズを出し、回答者は「YES」「NO」「関係ありません」のいずれかで答えられる質問を出題者にし、答えを推理していくものです。
最終の「正解」は、出題者が判断します。回答者は「正解」の回答が出るまで質問を続けてください。
ルールを理解したら、OKとだけ回答してください。

出題者は私です。
```

### テストプレイ

テストプレイは以下のような感じです。
https://chat.openai.com/share/8c6e26a1-076c-4227-86a9-e63bfd213130

たまに「正解ではあるが、なんか抽象的だなあ...」と思う場面も出てくるので、「掘り下げて」とか「具体化して」と追加発注をしてあげましょう。

### テストプレイしての感想

- 掘り下げが非常に簡単に始められる
- 最終の回答が　納得いくものがでてくるか　より、途中の対話プロセスでの気づきが大きい
- 掘り下げのプロセスを通しての学習効果が高い。自己内対話でもできるようになる

結論、有用なものになったと感じました。

## プロンプト整備過程でやったことをまとめ
やったことのまとめです。所要時間としては、計30minでした。
- プロンプト試行　(実績:　7スレッド）
- テストプレイ 　(実績:　お題3ケ）
 
汎化性能を求めると、テストのバリエーションは増やした方がよいです。

また、今回の例はプロンプトの階層が1段のシンプルなものです。
より複雑なタスクで多段階層が必要だと、設計の体力、必要なテスト量も増えていきます。
システム設計と同じですね。

## プロンプトの品質評価について

今回の例を基に、以下のような２つのレベルでのしきい値設定が考えられます。

Lv.1: chatGPTと水平思考クイズが個人レベルで実行可能になる（個人的な興味に基づく運用保証）
Lv.2: chatGPTと水平思考クイズが広範囲にわたり実行可能になる（テーマは多岐にわたる）
Lv.1については、個人の主観で一定程度の判断が可能です。
例えば、10名のユーザーが使用した場合、望ましい所感を得ることができるでしょうか。この点に関してはユーザビリティテストが求められます。
ただし、正式に公開しない場合は、運用保証は不要です。

Lv.2の品質を達成するためには、どの程度のテストや品質評価が必要でしょうか。
商用サービスとしてLLMを組み込む場合、どのようなテストプロセスが適切でしょうか。

現時点では、私にも明確な答えはありません。この議論は次回に持ち越しとします。

# まとめ
chatGPTプロンプトを整備する過程を、具体例を用いて紹介しました。
プロンプトの整備後のテスト過程については、現時点では、私にも明確な答えはありません。継続して考えていきます。
wslでnerves その30

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

# 練習問題
geoを使え。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/cc525e68-0b50-7149-69e3-ab91a5e43704.png)


# セットアップ

```
Mix.install([
  {:jason, "~> 1.4"},
  {:geo, "~> 3.4"}
])
```

# サンプルコード

```
geojson
|> Jason.decode!() 
|> then(fn x ->
  x
  |> Map.get("features")
  |> Enum.map(fn i ->
    i
    #|> Map.get("geometry")
    |> Geo.JSON.decode!()
    |> IO.inspect()
  end)
end)

```

# 実行結果

```
%Geo.Point{
  coordinates: {140.151111, 37.929687},
  srid: nil,
  properties: %{"name" => "オートショップユニット"}
}
%Geo.Point{
  coordinates: {140.109344, 37.92922},
  srid: nil,
  properties: %{"name" => "（株）エイジュウプロ"}
}
%Geo.Point{
  coordinates: {140.093108, 37.923453},
  srid: nil,
  properties: %{"name" => "（株）ホンダウイングロードショウ"}
}
%Geo.Point{
  coordinates: {140.112004, 37.911333},
  srid: nil,
  properties: %{"name" => "（有）カーセンター葵商会"}
}
%Geo.Point{
  coordinates: {140.108036, 37.907591},
  srid: nil,
  properties: %{"name" => "塚本サイクル"}
}
%Geo.Point{
  coordinates: {140.114247, 37.928429},
  srid: nil,
  properties: %{"name" => "サイクルショップ川口"}
}
%Geo.Point{
  coordinates: {140.099879, 37.916279},
  srid: nil,
  properties: %{"name" => "サイクルショップ中村"}
}
%Geo.Point{
  coordinates: {140.101416, 37.917854},
  srid: nil,
  properties: %{"name" => "菅原商会"}
}
%Geo.Point{
  coordinates: {140.108688, 37.912485},
  srid: nil,
  properties: %{"name" => "サイクルセンター卯月"}
}
%Geo.Point{
  coordinates: {140.105914, 37.912049},
  srid: nil,
  properties: %{"name" => "ホンダ野村モータース"}
}
%Geo.Point{
  coordinates: {140.103534, 37.869915},
  srid: nil,
  properties: %{"name" => "モーターハウスＫ"}
}
%Geo.Point{
  coordinates: {140.109289, 37.918955},
  srid: nil,
  properties: %{"name" => "ライダースサロン・ヤマカ"}
}
%Geo.Point{
  coordinates: {140.108313, 37.915746},
  srid: nil,
  properties: %{"name" => "中央ホンダ"}
}
%Geo.Point{
  coordinates: {140.107225, 37.905011},
  srid: nil,
  properties: %{"name" => "香澄ホンダ"}
}
%Geo.Point{
  coordinates: {140.123328, 37.912663},
  srid: nil,
  properties: %{"name" => "佐藤オート商会"}
}
%Geo.Point{
  coordinates: {140.121636, 37.910789},
  srid: nil,
  properties: %{"name" => "香坂輪店"}
}
%Geo.Point{
  coordinates: {140.125682, 37.958525},
  srid: nil,
  properties: %{"name" => "斎藤モータース"}
}
%Geo.Point{
  coordinates: {140.11782, 37.956678},
  srid: nil,
  properties: %{"name" => "ニューホンダ石山"}
}
%Geo.Point{
  coordinates: {140.131694, 37.903901},
  srid: nil,
  properties: %{"name" => "二輪屋たかはし"}
}
%Geo.Point{
  coordinates: {140.104554, 37.886019},
  srid: nil,
  properties: %{"name" => "夢工場"}
}
%Geo.Point{
  coordinates: {140.103239, 37.874814},
  srid: nil,
  properties: %{"name" => "あべ輪店"}
}
%Geo.Point{
  coordinates: {140.137379, 37.905055},
  srid: nil,
  properties: %{"name" => "レッドバロン米沢"}
}

```

以上。
プログラミングやる時の極意　CSSがうまくいかない時


# 一言

```
落ち着け
```

## 詳しく

```
うまくいかない全てのことは、知らないからだ。
```

## 例えば、


CSSのデザインでうまくいかないとする

競合が起きているから？

違う

全てのことは、知れば必ずうまくいく

```
アウトプットは、インプット
```

やって、うまくいかなくて、調べて解決

これが、インプット


## なにが言いたいのか

```
もし仮に、CSSの知識を100%持っていたら、ミスすることはあっても、うまくいかないことはない
でも0から始めるときは、知識を100%持っていない
できるようになりたければ、知識を100%にすること
今は、その過程であるということを認識しよう
```

じゃあ、その過程は、どのくらい険しいのか

`まあ、それなりに険しい`

そういう時は、一旦趣味を1時間やって、業務に戻ろう

### そんでもって、

ニュースを仕入れることは大事
Java String型の値の論理否定

# JavaにおけるString型の論理否定

String型は比較演算子を使う事が出来ない
その為一般にequalsメソッドで文字列が同じであるかを判定する

しかし同値であるかを判定するequalsメソッドは存在するが、論理否定は無いらしい

String型の論理否定を実装する場合以下のように書く

```java:String 論理否定
public class Main {
    public static void main(String[] args) throws Exception {
        String str_1 = "ABC";
        String str_2 = "XYZ";
        
        if(!(str_1).equals(str_2)){
            System.out.print("hoge");
        }
    }
}
```
```java:出力結果
hoge
```

```java:A - Signboard.java
import java.util.*;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws Exception {
        Scanner scan = new Scanner(System.in);
        String[] str = {"C","O","D","E","F","E","S","T","I","V","A","L","2","0","1","6"};
        String[] S = scan.next().split("");
        int count = 0;
        
        for(int i = 0; i < str.length; i++){
            if(!(str[i]).equals(S[i])){
                count++;
            }
        }
        System.out.print(count);
    }
}

```

```java:標準入力
C0DEFESTIVAL2O16
```

```java:出力結果
2
```
SREのやり方を間違えていませんか？4つの質問

<font color="Grey">*[Are you doing SRE wrong? 4 questions to ask](https://aiven.io/blog/are-you-doing-sre-wrong-4-questions-to-ask)の翻訳です。*</font>

2022年6月29日

# SREのやり方を間違えていませんか？4つの質問

SREにはチームワークと計画が必要だ。Aivenのように、正しくやりましょう。

SREに正しい方法はないが、間違った方法はある。というのも、安定した環境を維持することは、インフラ・アズ・ア・サービス・プロバイダーにとって極めて重要だからです。だからこそ、私たちはこの良さを広め、迷える友人が再び真の道を見つける手助けをしたいと思ったのです。


以下は、あなたの SRE が正しいかどうかを確認するために、あなた自身やあなたのチームに問いかけることができる質問です。


## 1.SRE の取り組みがサイロ化していないか？


優れた SRE は、開発者と運用の協力関係から生まれます。もし運用部門が何度も同じ問題に対処し続けるのであれば、チーム間のコミュニケーションラインをクリアにして、**解決策をソース**から見つけよう。


## 2.SRE の成功を稼働時間で測っていますか？


SRE の成功を測定することは正しい方向への一歩だ。しかし、稼働時間だけを見ていてはいけません。確かにそれは顧客に約束していることではあるが、それが全てではない。


アップタイムに加えて、**アベイラビリティとレジリエンス**も追跡するようにしてください。結局のところ、あなたの環境は稼働していてもアクセスできないかもしれません。そして、物事がうまくいかなくなり、環境がクラッシュしたとき、優れた弾力性があれば、迅速に復旧することができます。


## 3.SRE は緊急事態への対応に終始していませんか？


検索エンジンで「SREのやり方」と書けば、SREはリアクティブであるべきではなく、プロアクティブであるべきだと教えてくれる。それくらい当たり前のことなのだ。しかし、検索エンジンがそれを知っているのは、多くの企業ではSREがまだ*リアクティブ*だからだ。


あなたのアプローチは、すべて**継続的な改善**である必要があります。一度壊れたものは、二度と壊れないようにする。


SREは救急車でも病院でもない。どちらかというと、産業看護師が提供する控えめで日常的な健康管理サービスのようなものだ。


## 4.SREには多くの資源と労力が必要ですか？


SRE を空費する必要はありませんが、資金を無駄にする必要もありません。自動化と効率化**に投資し、ROIを積み上げてください。


反復的なタスクやモニタリングは自動化が得意とするところなので、それをうまく活用しよう。アラートをセットアップし、既知の脆弱性に対する自動プロセスをセットアップする（もちろん、ただ修正すればいいのであれば話は別だ！）。


## まとめ


安定した環境を運営したいのであれば、SRE を大切に扱い、適切なロードマップを持ち、部門横断的なコミュニケーションを可能にし、すべてを自動化することだ。


--


Aivenと私たちのサービスに関する最新ニュースや、オープンソースに関するちょっとした情報を入手するには、[月刊ニュースレターを購読](https://aiven.io/newsletter)してください！Aivenに関する日々のニュースは、[LinkedIn](https://www.linkedin.com/company/aiven/)と[Twitter](https://twitter.com/aiven_io)のフィードでご覧いただけます。


サービスアップデートの情報を知りたい方は、[変更履歴](https://aiven.io/changelog)をご覧ください。


マネージド・データ・プラットフォームをお探しですか？<https://console.aiven.io/signup>から無料トライアルにお申し込みください！
LeetCode 39. Combination Sum

問題は[こちら](https://leetcode.com/problems/combination-sum/?envType=study-plan-v2&envId=top-100-liked)
難易度はmedium
# 問題概要
異なる整数のcandidateの配列と、対象となる整数の target が与えられたとき、選ばれた数値の合計が target となる候補のすべてのユニークな組み合わせのリストを返します。組み合わせはどのような順番で返してもよい。

候補から同じ数字が選ばれる回数は無制限である。

テストケースは、与えられた入力に対して、合計がターゲットになるユニークな組合せの数が150組合せ未満になるように生成される。

Example 1:
>Input: candidates = [2,3,6,7], target = 7
Output: [[2,2,3],[7]]
Explanation:
2 and 3 are candidates, and 2 + 2 + 3 = 7. Note that 2 can be used multiple times.
7 is a candidate, and 7 = 7.
These are the only two combinations.

Example 2:
>Input: candidates = [2,3,5], target = 8
Output: [[2,2,2,2],[2,3,3],[3,5]]

Example 3:
>Input: candidates = [2], target = 1
Output: []

# 答え
```
class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        def backtrack(start, path, target):
            if target == 0:
                result.append(path)
                return
            
            for i in range(start, len(candidates)):
                if candidates[i] <= target:
                    backtrack(i, path + [candidates[i]], target - candidates[i])
        
        result = []
        candidates.sort()
        backtrack(0, [], target)
        return result
```
backtrack()を再帰で呼び出してます。最初にcandidate.sort()で小さい順にしています。
start: candidate[]の指数になります。もちろん呼び出されるごとに、後ろへ行きます。つまり、candidate[start]から後ろ半分を渡している、と考えても良いかもしれません。
path: 答え候補となります。int[].呼び出される際、candidate[i]を一つ追加。
target: 足して目標となる数字です。呼び出される時target-candidate[i]されているので、その分小さくなります。最終的に０になったところで、その時のpathが答えに追加されます。

イメージとしては、candidate[]とtargetをどんどん小さくして、簡単な問題にしていく感じです。

例１を使います。
最初[2,3,6,7]と７が渡された時、for文の中で
>backtrack([2,3,6,7], [2], 5)
backtrack([3,6,7], [3], 4)
backtrack([6,7], [6], 1)
backtrack([7], [7], 0)

が呼ばれます。

backtrack([2,3,6,7], [2], 5)はさらに
>backtrack([2,3,6,7], [2,2], 3)
backtrack([3,6,7], [2,3], 2)

が呼ばれます。target 5 が candidate[i] 6より小さくなるとそれ以降のfor文では呼ばれません。


# コード改良
今回はなし
```

```
己はフロントエンダーだーー！と言う方は、ATOMを使おう


フロントエンダーは、フロントエンドをやっている人

## ATOMについて説明するよ

タグって、めちゃめちゃたくさんあるじゃん？

覚えられないじゃん？

天才と無限やる気人は、わからないけど

２週間で覚えようのコーナーに参加してる人は、覚える気にならないでしょ？

そしたら、ATOMを使ってみて

と言う話

```
justify-content: flex-end;
```

とかさ、

j
と
F

を入力するだけで、補完されるぜ

やばくねーーーーーーーーーーー





## 追伸

そんなこと言っても、ATOMは重いからやだーーーー

と言う人！

わかりますよ。

いきなりPCが、ブーーーーーーと大声あげるんだもの

なにが起きたの？

恥ずかしい
と言う状態になる

そう言う時は、Disableしてみて

パッケージを

ATOMの画面で、

`command` + `,`

を同時押しよ

そんで、

`パッケージ`というメニューを開いて、

パッケージを、全部、Disable（無効）にしちゃえ〜〜〜〜〜〜〜


音が出なくなるよ


まあ、そこそこ手間がかかるけど、アラームを設定するのと同じようなもんだから


### 必要なパッケージは、消すとまずいことになる



## 追記

Atomは、開発終了してるので、

`SublimeText`

を使おう
html つまづかないために、覚えておけばいいこと　4つ


## 4つだけ、理解すればいい

1. インライン要素
1. ブロック要素
1. 親要素
1. 子要素



## 具体的には、


例えば、

この要素を横並びにしたい

と思うことがあるでしょ？

ない？

あるよね

そう言うとき、そのパーツが

インライン要素なのか？
ブロック要素なのか？

と言う観点と

親要素なの？子要素なの？

と言う観点のみ突き止めれば、必ず横並びにできるぞ


## 他

まあ他にも、

パディングとか、
マージンとか出てくるけど、

そっちは、まだいい
【Ruby】Class&インスタンスの理解と活用方法

# 【Ruby】Classとインスタンスの理解と活用方法

Rubyプログラミングにおいて、クラスとインスタンスは非常に重要な概念です。クラスはオブジェクトの設計図のようなもので、インスタンスはその設計図に基づいて作成された具体的なオブジェクトを指します。この記事では、Rubyにおけるクラスとインスタンスの基本的な使い方を詳しく解説していきます。

## クラスの定義方法

### クラスの基本構造

```ruby
class クラス名
  # クラスの内容
end
```

Rubyでは、クラス名は大文字で始める必要があります。クラス内にはメソッドや変数を定義し、オブジェクトの振る舞いや状態を定義します。

### インスタンス変数とattr_accessor

```ruby
class クラス名
  attr_accessor :インスタンス変数名
end
```

`attr_accessor`は、インスタンス変数のゲッターとセッターを自動的に定義するメソッドです。これにより、インスタンス変数へのアクセスや変更が簡単になります。

### メソッド

```ruby
class クラス名
　　　　def initialize(変数名)
    @変数名 = 変数名
  end

  def インスタンスメソッド名
    # メソッドの処理
  end
  def クラス名.クラスメソッド名
    # クラスメソッドの処理
  end
end
```
### インスタンスメソッド

`インスタンスメソッド`は、クラスのインスタンスに対して実行するメソッドです。これにより、オブジェクトの具体的な振る舞いを定義します。

### initializeメソッド

`initialize`メソッドは、インスタンスが作成されたときに自動的に実行される特別なメソッドです。このメソッドでインスタンス変数を初期化したり、他の初期設定を行うことができます。

### クラスメソッド

`クラス`メソッドは、クラスメソッドは宣言時も呼び出し時もクラス名.クラスメソッド名と記述する。クラスメソッドはインスタンス作成前に呼び出せる。インスタンスメソッド内でも使用できる。

## インスタンスの作成と利用

### インスタンスの作成

```ruby
インスタンス名 = クラス名.new(引数)
```

`new`メソッドを使用してクラスのインスタンスを作成します。必要に応じて引数を`initialize`メソッドに渡すことができます。

### インスタンス変数への代入

```ruby
インスタンス名.変数名 = 値
```

`attr_accessor`で定義したセッターメソッドを使って、インスタンス変数に値を代入することができます。

### メソッドや変数の呼び出し

```ruby
インスタンス名.インスタンスメソッド名
インスタンス名.インスタンス変数名
クラス名.クラスメソッド名
```

インスタンスに対して定義したメソッドを呼び出すことができます。これにより、オブジェクトの振る舞いを制御することが可能です。

## まとめ

Rubyにおけるクラスとインスタンスは、オブジェクト指向プログラミングの基本です。クラスを設計図として、インスタンスを実際のオブジェクトと捉えることで、複雑なプログラムをより管理しやすく、理解しやすい形で構築することが可能になります。この記事で紹介した
基本的な概念とテクニックを理解し、実践してみることで、Rubyプログラミングのスキルを向上させることができます。
html 要素の種類


## 要素の種類


1. インライン要素
1. ブロック要素
1. リスト要素
1. 表関連要素
1. フォーム要素
1. 埋め込み要素がある


## 具体的に



### 1. インライン要素

インラインという名の通り、
行の中の1つのパーツ・テキスト
というイメージ

### 2. ブロック要素

かたまり
のようなイメージ
ブロック要素を挿入すると、横幅を親要素と同じまで広げる性質を持つ


### 3. リスト要素

純粋に、一覧形式のレイアウトを作れる

順序ありリスト　：　olタグ
順序なしリスト　：　ulタグ
定義リスト　：　dlタグ

の３種類があある


### 4. 表関連要素


単純に、表を作れる

というのも、レイアウトとして、表を作る

理解しなければならないのは、
デザインとして、表を作るのであれば、CSSでもいい
ということ


### 5. フォーム要素

Webの世界では、
アプリケーションやサイト自体が、
ユーザーとやり取りすることがある

これを、インタラクティブと言う

どんなやり取りか？

文章でのやり取り。。

それを実現させようという試みの末、おそらく作られた仕組みが、フォーム

ユーザーが、フォームに、テキストを書き込むと、アプリの裏側に、その文章を伝えられる


兎にも角にも、

`情報の入力を受け付けるパーツ`
である

### 6. 埋め込み要素

文字通り、
そのサイトに、何かを埋め込むことができる

`何か`

とは？

・ファイル
・音声や、動画や、他のWebサイト
など


## ポイント

インライン要素とブロック要素だけ、しっかり理解していけばいいと思う
HTML aタグについて　サクッと



## aタグ


`リンク`

を設定できる


```
<a href="tobitaiurl.html"></a>
```

革新的なこと
```
aタグ　：　インライン要素
```


## 詳しい版は、下記から

[これ]()



## HTMLの極め方

20回、部分模写
20回、全体模写

何事も、3週くらい全体を実装経験すること
何だってそう
[TypeScript]Array関連のメソッドの挙動 concat/filter/flat/includes

## concat 
* 2つ以上の配列を結合するために使用
* 既存の配列を変更せず、新しい配列を返す

```typescript
const array1 = ['a', 'b', 'c'];
const array2 = ['d', 'e', 'f'];
const array3 = array1.concat(array2);

console.log(array3);
// => Array ["a", "b", "c", "d", "e", "f"]
```

## filter
* 指定された配列の中から指定された関数で実装されているテストに合格した要素だけを抽出

```typescript
const words = ['spray', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter((word) => word.length > 6);

console.log(result);
// => Array ["exuberant", "destruction", "present"]
```

## flat
* すべてのサブ配列の要素を指定した深さで再帰的に結合した新しい配列を生成

```typescript
const arr1 = [0, 1, 2, [3, 4]];

console.log(arr1.flat());
// => Array [0, 1, 2, 3, 4]

const arr2 = [0, 1, [2, [3, [4, 5]]]];

console.log(arr2.flat());
// => Array [0, 1, 2, Array [3, Array [4, 5]]]

console.log(arr2.flat(2));
// => Array [0, 1, 2, 3, Array [4, 5]]

console.log(arr2.flat(Infinity));
// => Array [0, 1, 2, 3, 4, 5]
```

## includes
* 特定の要素が配列に含まれているかどうかを true または false で返す

```typescript
const array1 = [1, 2, 3];

console.log(array1.includes(2));
// => true

const pets = ['cat', 'dog', 'bat'];

console.log(pets.includes('cat'));
// => true

console.log(pets.includes('at'));
// => false
```
docker で遊ぼう

この記事は [一分で読める小ネタのカレンダー | Advent Calendar 2023 - Qiita](https://qiita.com/advent-calendar/2023/raki) の１４日目

# docker

- 猫も杓子も k8s な時代なので docker を使えるようにしておくのは大事
- インストールは各自環境に合わせて
- やり始めると奥が深いので、初心者のうちは動作するものをコピーしてきて動かせれば十分
- 最初から凝ったものを書こうとしないで、既存のイメージを使って動かせればいいし、気に入ったら深掘りすればいい
- どのみち会社に入って使うようになったら、職場での使い方は教えてもらえる
- それに備えてコマンドや用語を勉強しておくといい

本文はここまで。以下は時間外ｗ

# hello world

- `docker -v` してインストールができているのを確認したら
- `docker run hello-world` して
- 他のコマンドでひとしきり遊ぶ
- サブコマンドが昔と今で違う（検索すると情報の新旧がわかる）ので、そういうものだと納得する（ITあるある）

# ローカルな web server(軽量なnginxのイメージ)

- 最近のプログラミング言語はランタイム中にローカルサーバな機能を持ってるので最近あんまり出番がないけど
- ローカルでとあるディレクトリをドキュメントルートにして nginx が走ると便利なことがある

```bash
alias alpinx='docker container run -itd --rm -v `pwd`:/usr/share/nginx/html -p 8081:80 -e "TZ=Asia/Tokyo" --name alpinx nginx:alpine'
```

- こんな感じの alias を作っておく
- どこか適当なディレクトリに index.html という名前のテキストファイルを作成して、適当に中身を書いて、そのディレクトリで `alpinx` って叩くと、ブラウザで `http://localhost:8081/` を表示するといける（はず）
- 最近は手でゼロから書くようなことはめったにない（と思いたい）けど、それでも HTML, CSS, JavaScript を自分で書いてみて、画面（ブラウザ）に表示させる、index.html を手で編集して変更が反映される、をやってあるのとないのとではだいぶ違う
- 先にも書いたけど、近年の開発でこれを仕事で使うことはないし、もっと便利でスマートなやり方がちゃんとある。その時に、本質的にはこういうことだってことを知っていて欲しい

# いろいろ動かす

- DB の起動とか他にたくさんいい記事があるので、いろいろ動かして遊んで欲しい
- 大きいイメージは初回起動（DL）に時間がかかるし、ディスク容量もだいぶかかるけど、必要経費と割り切って
- DBMSなら、MySQL(MariaDB)やPostgreSQLなど
- キャッシュなら、Redis, Memcached など
- Web サーバは nginx でいいし
- アプリケーションサーバ（Webサーバの後ろで実際にコンテンツを返してくるところ、くらいの理解でおｋ）
- AWS をやりたいなら LocalStack は検討してもいい（実際には無料枠があるので本物を使っていいと思うけどね）
- 業界の進歩は早いので、それぞれもっと新しくて見た目もかっこいいものがあるけど、人知れず消えていく、使われない、もしくは自分は使わないで終わるもの、もたくさんあるので、取捨選択する目を養う練習をするのもいいかもしれない

# my-examples リポジトリ

- my-til や dotfiles と同じように、docker の学習結果を置いておくリポジトリを作るといい
- パブリックに置くなら examples-docker で、プライベートにするなら my-examples-docker のようにするとわかりやすい
- これからもいろんなツールや言語を学んでいく必要があるはずなので、最初は my-til に置いておいて、少しまとまった量ができて、わけたほうがいいなって思ったら分離する、その状況や判断は人それぞれなので、自分で判断がつけられるようにやってみてほしい
- わかるはわけるって言葉もあるくらいなので、わかったらわけるんだと思う

# 改善依頼

- ワンライナーで素のイメージ（buildしない）を使ってこういうのあるぜとか
- 動作する docker-compose.yml のおすすめとか（あくまで初心者向けに）
M5UnitV2 でブラウザからrootのコンソールに入る

## 概要
M5UnitV2 では、SSHなどの接続を行ってシェルに入る他に、ブラウザからroot権限を持つシェルに入ることができます。

## 説明
M5UnitV2 のブラウザにアクセスし、トップページ右側のFUNC PANELから、「Swirch to notebook mode」を押して、Jupyter Notebook に入ります。

![no1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73020/7ee68375-cc5d-a2ad-f1f7-8cfe062db678.jpeg)

Jupyter Notebook の右側の「New」ボタンを押し、「Terminal」を選択します。

![no2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73020/5708e377-4cce-fe99-bbd7-c04f5faa100d.jpeg)

ブラウザからroot権限を持つシェルに入ることができました。

![no3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73020/60af60d2-acc4-be14-d154-2917a599f254.jpeg)


## 参考資料

https://docs.m5stack.com/en/unit/unitv2
モデル駆動型の講義がきっかけで見えてきた先人達の英知

11/11(土)の**気ままに勉強会**(たなさん主催)で、**おうじゃ**さんがモデル駆動型のお話をしてくださいました。

　　おうじゃさんこと Maeda Makoto さん
　　https://twitter.com/bothernpa 

　　気ままに勉強会主催者のたなさん
　　https://twitter.com/dreams_panda

https://kimamani.connpass.com/event/300750/

今回の講義で、私の目からうろこがポロポロ取れていきました。

そのことがうれしかったので、ここで共有します。

受講前
----------------------------------------
お恥ずかしい話ですが、今回の講義を受講するまで、モデル駆動型アプリというものについて、よくわかっていませんでした。

よくわかっていないどころか、モデルってなに？何を駆動するの？というレベルだったのです。

なので、モデル駆動型アプリは Dataverse でしか使えないので、それを※※すると・・・というトピックを聞いても雲をつかむような話だったのです。

そのような私ですが、仕事でノーコードツールを使用して業務アプリを開発したり、ETLツール、RPAを使って業務の自動化に取り組んだりしています。

そこそこ関連する知識を持っているつもりだったのですが、こと Dataverse とモデル駆動型アプリについては理解に苦しんでいました。

まさにそのタイミングでおうじゃさんの講義に出会ったのです。

受講直後
----------------------------------------

私は大きな勘違いをしていました。

Dataverse を高性能で機能豊富なデータベース**単体の**サービスだと思い込んでいたのです。

改めてご教授頂いたのは、Dataverse は「モデル駆動型アプリ」のデータを保持するためだけのテーブルだけではなく、一覧画面（リスト）やレコード編集表示画面（フォーム）を内包したデータ基盤であるということです（あくまで私の理解ですので、間違っていたらご指摘ください）。

また、一覧画面やレコード表示編集画面はキャンパスアプリほど自由度は高くないとのことでしたが、業務で使用するなら Excel のインターフェースに近いほうが受け入れられやすいので加点要因と思いました。

わかる、わかるぞ！
----------------------------------------
その後、ふらりさんがおまとめになった資料があることを、教えていただきました。

　　ふらりさん
　　https://www.twitter.com/flali_world

https://www.docswell.com/s/fworlddocs/K38Y4Y-2023-10-29-222642#p8

「わかる、わかるぞ！」

上記 URL の概観図を見て、Dataverse の占める位置、そして Power Apps やそれ以外のツールとのつながりがわかってきました。

また Shiori Kuramoto さんの Qiita 記事を紹介していただきました。

　　Shiori Kuramoto さん
　　https://twitter.com/_skuramoto

https://qiita.com/skuramoto/items/b51b35ef84c42f71bb20

「おぉ、そうだったのか！」

最後に
----------------------------------------
疑問が一気に氷解する経験は、最近なかなか出来なくなってきています。

しかし、今回はその貴重な経験をさせていただきました。

そして、先人達の英知に触れるという、またとない機会を頂戴しました。

今後は私も情報を提供する側に回れるよう、頑張ります。

皆さん本当にありがとうございました。

以上
SQLのHAVINGとWHEREについて

# はじめに
SQLの勉強をしているときに、
HAVINGとWHEREの使い分けについて疑問を抱き、解消したので備忘録としてまとめる。

# どちらも条件を追加するために使う
HAVINGとWHEREはどちらもSQL文で条件を追加するために使う。
じゃあどっちかでいいじゃん！でも決定的な違いがある。


# HAVINGとWHEREは処理順が違う

```SQL:処理順（重要）
1,FROM
2,WHERE
3,GROUP BY
4,HAVING
5,SELECT
6,ORDER BY
```

例えば、GROUP BYした後の合算値に対して条件を追加したい場合
WHERE文だとGROUP BYより前に読まれてしまうので、使えない。
そういう時にHAVINGが使える。

# SELECTって前に記述するのに意外と読み込まれるの遅い
処理順を見るとSELECTは最後の仕上げみたいな場所にいる。
(ORDER BYはなんとなく最後の仕上げ感はある)

ここで私が学習教材の不正解から抜け出せなかった罠があり...

それは<font color="red">SELECT文でAS句で定義した変数はWHEREでもHAVINGでも使えない</font>ということ。

つまりどういうこと？下記具体例

```SQL:NG例
SELECT class,SUM(name) as total FROM student
GROUP BY class
HAVING total >= 20;

//うまくいきそうだけどこれはNG例
```

```SQL:OK例
SELECT class,SUM(name) as total FROM student
GROUP BY class
HAVING SUM(name) >= 20;
```

よく考えたら当たり前のこと、でも初めは？で頭がいっぱい。
ここで処理順をもう一度復習。

```SQL:処理順
1,FROM
2,WHERE
3,GROUP BY
4,HAVING
5,SELECT
6,ORDER BY
```

そう、HAVINGを実行する際にはまだSELECTが読まれていないので
SELECTで定義した変数は使えないということ。

つまりSELECTで定義した`total`は`HAVING`を実行する際にはまだ生成されていないということ。
なので`SUM(name)`で記述するのが正しい。

# 結論
このあたりの処理について迷ったら処理順を考えてみて記述の内容を考えてみるように。

▼参考にしたサイト

https://www.sejuku.net/blog/73003#index_id3