OmniAICreator/Qiita-1.07M huggingface dataset:
自衛官からエンジニアへ Elixirから始める Web開発 Part22

この記事は「Elixir Advent Calendar 2023」22日目の記事です
東京にいるけどfukuokaexのYOSUKEです。

普段は 合同会社TheWaggle で教材開発・システム開発・研修講師などマルチに活動してます。

このシリーズでは、文系ですらない、体育会系でも始められるプログラミング学習　というテーマで元自衛官だった僕が
自衛官からエンジニアになってもらいたいという気持ちを込めて、普段は大人しいですが、このコラムシリーズでは、あえて、体育会系のノリで、貴様ら理屈で覚えるなら体で覚えろ！というノリで書いてみたいと思います。

なので、初学者向けですが、理論は後回し、まずは動かして体感しろってノリの第22回目です。

それでは、いくぞ！

## 多目的ナイフと正規表現

よーし、貴様ら！ 今日は前回に伝えたコードの中から、貴様らが最も気になっているであろう、```~r/[gml]/```この部分について説明してやろう！

```elixir
defmodule TNT do
  def create_c4({"RDX", rdx}, {"ポリイソブチレン", polyisobutylene}, {"モーターオイル", motorOil}, {"セバシン酸ジオクチル", dioctylSebacate}, {"ガソリン", gasoline}) do
    materials = [rdx, polyisobutylene, motorOil, dioctylSebacate, gasoline]

    Enum.map(materials, &convert_material_to_numeric/1)
  end

  defp convert_material_to_numeric(material) do
    numeric_part = String.replace(material, ~r/[gml]/, "")
    
    convert_to_numeric(numeric_part)
  end

  defp convert_to_numeric(numeric_part) do
    if String.contains?(numeric_part, ".") do
      String.to_float(numeric_part)
    else
      String.to_integer(numeric_part)
    end
  end
end
```

このコードの ```~r/[gml]/``` は、`正規表現`というものを使っている。これは「g」、「m」、または「l」のいずれかの文字を探す命令だ。まるで、偵察隊が特定の目標を探しているようなものだ。敵の隊列を探すのと同じく、この命令は特定のパターンを見つけ出す。

次に、String.replace(material, ~r/[gml]/, "") だ。これは、見つけた「g」、「m」、または「l」を除去する。敵の通信を妨害するように、ここでは無用な文字を排除している。

このように、正規表現は特定のパターンを見つけ、それに基づいてアクションを起こす。それは戦闘での戦術と同じだ。目標を特定し、命令に従って行動する。この技術をマスターすれば、コードの中でより効率的に操作ができるようになる。

### 正規表現

正規表現とは、いわば「多目的ナイフ」や「十徳ナイフ」のようなものだ。なぜなら、正規表現は一つのツールで多くの異なるタスクをこなすことができ、非常に汎用性が高いからだ。

考えてみろ、多目的ナイフは一つの道具で、刃物、はさみ、ノコギリ、栓抜きなど、様々な機能を持っている。これと同じように、正規表現も一つの「パターン」や「式」で、文字列の検索、置換、データの抽出といった多くの操作を行うことができる。

戦場での状況は常に変わる。敵の配置、地形、天候など、戦闘に影響を与える要素は数え切れない。これに対応するためには、柔軟で汎用的なツールが必要だ。正規表現も同様で、さまざまな文字列処理の問題に対して、一つの強力なツールとして機能する。

そんな多目的ナイフの使い方を今から教えてやるから覚えておけ！

正規表現（Regular Expression）とは、文字列の中から特定のパターンを見つけ出し、操作するための強力なツールだ。複雑で多様な状況に対応できる。正規表現は、文字列の検索、置換、データの抽出に使用される。

基本的な構成要素を見ていくぞ

1. リテラル文字: 通常の文字（例：a、B、1）は、それ自体が検索対象となる。

2. ドット `.`: 任意の一文字にマッチする。例えば、`a.b` は `acb`、`aab`、`axb` などにマッチする。

3. 文字クラス `[]`: 括弧内の任意の一文字にマッチする。例：`[abc]` は `a`、`b`、`c` のいずれかにマッチする。

4. 繰り返し `*` と `+`: `*` は直前の要素が0回以上の繰り返しにマッチし、`+` は1回以上の繰り返しにマッチする。例：`a*b` は `b`、`ab`、`aab` などにマッチする。

5. エスケープ `\`: 特殊文字を普通の文字として扱うために使う。例：`.` は任意の文字にマッチするが、`\.` はピリオド自体にマッチする。

6. 開始 `^` と終了 `$`: `^` は文字列の開始部分、`$` は終了部分にマッチする。例：`^abc` は「`abc`」で始まる任意の文字列にマッチする。

これらは基本的な要素だ。しかし正規表現にはもっと多くの機能がある。より複雑なパターンを作成できるように、これらの要素を組み合わせて使う。

例えば、`~r/[gml]/` は「`g`」、「`m`」、または「`l`」のいずれか一文字にマッチする。これを使えば、文字列から特定の文字を見つけ出し、操作できる。

分かったか、貴様ら！これはただの基本だ。正規表現は、様々な状況に応じて変化する戦術のようなもの。これをマスターするには、実践が必要だ。訓練を重ね、この知識を武器に変えろ！

今日はここまで、それでは次回 Part23でまた会おう！
aria-labelの適切な利用について調べてみた

## これはなに？

`aria-label` の使い方についてMDNを読んでいると下記のように記載がありました。

>Don't "overuse" aria-label

(訳: `aria-label` を使いすぎないで)

この記事では `aria-label` の適切な利用をするために、 `aria-label` を使う前に取るべき選択肢がなにかを調べてまとめました。

## `aria-label` とは

`aria-label` とはWAI-ARIAのNameプロパティに属します。
`aria-label` はインタラクティブな要素にオブジェクトの名前（アクセシブルな名前ともいう）を与えることができます。

`aria-label` で付与されたアクセシブルな名前は不可視で、スクリーンリーダーなどで読み上げられます。

よく使われる例としてアイコンがあります。

例えばX（旧Twitter）へのリンクが、Font Awsomeのアイコンフォントで配置されている場合があります。

```html
<a href="">
    <i class="fa-brands fa-x-twitter"></i>
</a>
```

このとき、スクリーンリーダーで認知しているユーザーになにが表示されているのかわかりません。
下記のように `aria-label` を追加すると、アクセシブルな名前を与えることができます。

```html
<a href="" aria-label="X(Twitter)">
    <i class="fa-brands fa-x-twitter"></i>
</a>
```

## `aria-label` を使う前に取るべき選択肢

`aria-label` は不可視です。
基本的にスクリーンリーダーの利用者にのみ意味があります。
WAI-ARIAはどんなユーザーにも同じ情報を提供することが目的です。
スクリーンリーダーの利用者だけに伝わる状況も、それは意に反していると言えます。

情報が可視化されていれば、視覚で情報を拾い上げることができるユーザーにも同じ内容を伝えることができます。
そのためにできることを調べてみました。

### 選択肢1:テキストで表現する

まずは、テキスト情報を追加できるか検討すべきです。
先程のX（旧Twitter）へのリンクも下記のようにテキストがあれば、幅広いユーザーになんのリンクなのか伝えることができます。

```html
<a href="">
    <i class="fa-brands fa-x-twitter">公式X（旧Twitter）はこちら</i>
</a>
```

他にもテキストのメリットがあります。

- テキストは検索できる
- テキストはコピーできる
- テキストは翻訳できる
    - `aria-label`が翻訳されないブラウザもあります

そもそもHTMLとは `HyperText Markup Language` です。
テキストはWebの基本と言えるのではないでしょうか。

### 選択肢2:セマンティックなHTMLで実装する

WAI-ARIAよりもHTMLネイティブセマンティックは優れています。
セマンティックなHTMLは適切な `role` を持っています。
読み上げだけでなく、キー操作なども適切に付与してくれます。

また、セマンティックなHTMLの実装をした上で、テキストを可視化できるか検討してみてください。
下記のHTML要素ではアクセシブルな名前を与える方法があります。

HTML|アクセシブルな名前を与える方法
---|---
`href` を持つ `<a>` | `<a>` の中にテキストを入れる
`<button>` | `<button>` の中にテキストを入れる
`<fieldset>` | `<legend>` を追加する
`<figure>` | `<figcaption>` を追加する
`<img>` | `alt` を追加する
`<input>` | `<label>` を追加する
`<select>` | `<label>` を追加する
`<textarea>` | `<label>` を追加する
`<table>` | `<caption>` を追加する

### 選択肢3: `aria-labelledby`でアクセシブルな名前を参照する

例えば `<daialog>` （`role=daialog` も同様）は、アクセシブルな名前を持つことが求められます。
複数のダイアログが存在する場合、ユーザーが現在どのダイアログを操作しているか伝えるために、アクセシブルな名前が必要になります。

```HTML
<dialog aria-labelledby="daialogTitle">
  <h1 id="daialogTitle">モーダルダイアログ</h1>
  ...
```

このように参照できるテキストが存在する場合は、`aria-labelledby` を使うことで、スクリーンリーダーの利用者と視覚で情報を拾い上げることができるユーザーも同じ情報を得ることができます。

## それでもだめなら `aria-label` を使う

以上の選択肢を検討した上で、UIやデザイン上制限が出てしまうなら、 `aria-label` を使いましょう!


---
この記事が誰かのお役に立てると幸いです。

## 参考

- [aria-label - Accessibility | MDN](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label)
- 伊原力也、小林大輔、桝田草一、山本伶. Webアプリケーションアクセシビリティ 今日から始める現場からの改善. 技術評論社
- [aria-label を使いすぎない](https://azukiazusa.dev/blog/do-not-use-aria-label-too-much/)
FOSS4G 2023 Japan@FUKUIハンズオン資料

# FPSS4G@FUKUI ハンズオン資料
![playground-easy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216230/1804bdad-0c88-7935-f663-01579070c3d2.png)
## 概要
* 2023年9月17日に開催した[FOSS4G 2023 Japan@FUKUI ハンズオン](https://www.osgeo.jp/events/foss4g-2023/foss4g-2023-japan-at-fukui/foss4g-handson#PM2)で「MapLibre GL JSとOverpass APIでWebアプリを作る」のハンズオン資料です。
* 単にGeoJsonなどをMapLibreでアイコン表示させるのではなく、生きているデータベースこと「OpenStreetMap」からリアルタイムで取得していきます。
* どんなデータをOpenStreetMapから取得するのか、どう見せるのか、そのアイデアを考えて実際に実装していくハンズオンとなります。

## 進め方
* [ハンズオン資料](https://speakerdeck.com/barsaka2/create-a-web-application-with-maplibre-gl-js-and-overpass-api)を読みながらハンズオンを進めていきます。
* ベースアプリ「[Playgrounds-Easy](
https://github.com/K-Sakanoshita/Playgrounds-Easy)」をカスタマイズして開発していきます。
* ベースアプリの設定ファイルを編集して、タイトルなどを設定します。
* 基本設定後、取得する情報（OpenStreetMapのタグ）を設定していきます。
  * https://wiki.openstreetmap.org/wiki/JA:Map_Features
* 下記jsonの「overpass」にあるnode(点)、way(線)とタグが合致したものを取得します。
* 取得後のデータから、「tags」内に指定したタグだけに絞り込む動きをします。
  * 「=」が付いていないものは「=*」と同じ意味となります（全て）。
* 他、expressionはway(線)を表示する時の色や太さ指定となります。
```JavaScript:overpass.json
{
    "OverPassServer": "https://maps.mail.ru/osm/tools/overpass/api/interpreter",
    "osm": {
        "overpass": [
            "node[\"leisure\"=\"park\"]",
            "way[\"leisure\"=\"park\"]",
            "node[\"leisure\"=\"playground\"]",
            "way[\"leisure\"=\"playground\"]",
            "way[\"landuse\"=\"recreation_ground\"]",
            "relation[\"leisure\"=\"park\"]",
            "relation[\"leisure\"=\"playground\"]",
            "relation[\"landuse\"=\"recreation_ground\"]",
            "node[\"playground\"]",
            "way[\"playground\"]"
        ],
        "tags": [
            "leisure=park",
            "leisure=playground",
            "landuse=recreation_ground",
            "playground"
        ],
        "expression": {
            "stroke": "#409040",
            "stroke-width": 2
        }
    }
}
```
* 取得したデータを表示するアイコンは「marker.json」で指定します。

```JavaScript:marker.json
{
    "marker": {
        "path": "maki-icon",
        "tag": {
            "*": {
                "*": "marker-stroked.svg"
            },
            "amenity": {
                "arts_centre": "arts_centre.svg",
                "bar": "bar.svg",
                "bbq": "bbq.svg",
                "bench": "bench.svg",
                "bicycle_parking": "parking-bicycle.svg",
            (以下略)
```
* tag内を見て貰うと、OSMのタグと一致した時のファイル名が書いていることが分かります。
* pathが「maki-icon」とあるので、そこにアイコンファイルを置けば利用出来ます。
* 一般的なアイコンはあるので、特別なタグを使うときに編集すれば良いと思います。

![playground-easy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216230/1804bdad-0c88-7935-f663-01579070c3d2.png)

## ここまで出来たら
* 色んなマップを作ることが出来ます。例えば、自販機マップとかトイレマップとか。
* タグを組み合わせて複雑な条件も指定出来ます（例えばコカ・コーラ自販機とか）。
* 他にも一覧表を表示させても良いと思います（poiCont.makeListが役立つ）
* それでは、開発を楽しんでください！

## 参考サイト
* [遊具のある公園マップ](https://github.com/armd-02/Playgrounds)。こっちは色んな機能があります。
* [Community Map Maker](https://github.com/K-Sakanoshita/community_mapmaker)。更新が間に合ってない本家
[Rails]enumについて改めて整理

## モデルのenumについて
:::note
そもそも**enum**とは

**enumとは、１つのカラムに指定した複数個の定数を保存できる様にする為のモノ**
:::

- 指定した複数個の定数以外の値は保存できない
- カラムに指定した定数が入っているレコードを取り出すのが容易に
- データベースには整数値として保存
- アプリケーション内ではシンボルや文字列として扱われる
- 状態に応じたメソッドを自動生成してくれる

### enumを使用すると嬉しいこと
##### コードの可読性と意図の明確化
enumを使うことで、状態やオプションを整数値ではなく、意味のある名前（シンボルや文字列）で表現できます。これにより、コードの可読性が向上し、他のエンジニアがコードを理解しやすくなります。

##### エラーの減少
整数値を直接使用する代わりにenumを使うことで、誤った値を割り当てるリスクを減らすことができます。これにより、データの整合性を維持しやすくなります。

##### メソッドの自動生成
Railsのenumは、状態に応じたメソッド（login?, logout!など）を自動的に生成します。これにより、状態のチェックや更新を簡単かつ一貫性のある方法で行うことができます。

##### スコープの自動生成
enumは各値に対してスコープを自動的に生成します。これにより、特定の状態のレコードを簡単にクエリできます（例：User.login）。

##### 保守性の向上
状態の追加や変更が必要になった場合、enumを使用すると、一箇所の変更で済みます。これにより、将来の変更や拡張が容易になります。

##### バグの早期発見
enumは存在しない値を設定しようとするとエラーを発生させるため、誤った値の使用を早期に検出することができます。


### 確認メソッド `インスタンス.定数名?`
- 今enumカラムに入っている定数が何なのか確認できる

```ruby
user.status
=> login

user.logout?
=> false

user.login?
=> true
```

### 更新メソッド `インスタンス.定数名!`
- 今enumカラムに入ってある定数を別の定数に更新するメソッド
```ruby
user.status
=> login

user.logout!
=> logout
```

### 検索メソッド `モデルクラス.定数名`
- データを検索するメソッド
- 下記の場合、login状態のユーザーをすべて取得している
```ruby
a_type_users = User.login

SELECT `users`.* FROM `users` WHERE `users`.`status` = 0
```
New Relic PHPアプリケーションでエラーを無視したかったので設定を調べた

## はじめに
座喜味です。株式会社じげんで、リフォームマッチングサイトをはじめとした、リフォーム関連のサービス開発を担当しているエンジニアマネージャーです。
New Relicは前年度に導入して、主にPHP Laravelのアプリケーションで活用しています。
ひとつのアプリケーションにAPM Agentを入れたところ、Errors Inboxで無視したいエラーが大量に出ていてノイズになっていていらない通知が大量に出ていました。
アプリケーションのソースコードに手を入れずに、New Relicで無視する設定がないか調べてみたので記したいと思います。

## Errors Inboxの公式ドキュメントを見る
まずはErrors Inboxの公式ドキュメントを確認しました。
https://docs.newrelic.com/jp/docs/apm/agents/manage-apm-agents/agent-data/manage-errors-apm-collect-ignore-or-mark-expected/#expected

![スクリーンショット 2023-12-16 13.51.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554264/0545c170-5b65-8298-1619-545f6e528ecd.png)

!? Java、Node.js、Python、Ruby、Go、.NETのみと書かれています..!
うーむ。。ないはずはないだろうと思ったのでPHP Agentの設定のドキュメントを見てみることにしました。

## PHP Agentのドキュメントを見る
PHP Agentのドキュメントを見たところそれらしき設定がありました。
https://docs.newrelic.com/docs/apm/agents/php-agent/configuration/php-agent-configuration/#inivar-err-ignore-exceptions

![スクリーンショット 2023-12-16 13.54.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554264/cf28b115-854e-88d3-b7f9-c16700f63575.png)

newrelic.iniファイルの`newrelic.error_collector.ignore_exceptions` を設定することで無視設定ができるようです。複数指定したい場合はcomma区切りで指定してくれとのことです。
agentのソースコードを見る限りでもcommaで分けて処理していそうでした。
https://github.com/newrelic/newrelic-php-agent/blob/1563e8045968fe0c6ee228c566ca080afceba6c1/agent/php_error.c#L214C27-L214C62

newrelic.iniに無視したい例外を指定してテスト環境でデプロイしてみたところ、該当の例外がErrors Inboxに通知されなくなったことが確認できました。

## 最後に
New Relicの公式ドキュメントだとPHPのリンクがないことが多い気がするのですが、設定に詰まった際には今後はPHP Agentのドキュメントを確認するようにしたいと思います。
google colabでKaggleのデータセットを保存する

google colabのノートブックを使って、Kaggleのコンテストの分析を行う時がある。
その第一歩、データの保存手順を記入しておく。
参考になれば幸いです。
#
### 1. Kaggle API Tokenの取得
[Kaggle]
Kaggleマイアカウントページ　→　「your account」 →  「Create New API Token」をクリック
すると、「kaggle.json」のファイルがダウンロードされる。

※以前API Tokenを使った場合、一度「Expire API Token」をクリックし、以前のTokenを失効させた方がトラブルが減るかも
#
### 2. Google Colabの準備
ノートブック開き（または作成し）、以下を記入し、実行させる
1) ! pip install -q kaggle
2) from google.colab import files
3) files.upload()--------ダウンロードされたkaggle.jsonを選択し、アップロードする。
4) ! mkdir ~/.kaggle
5) ! cp kaggle.json ~/.kaggle/
6) ! chmod 600 ~/.kaggle/kaggle.json
7) ! kaggle datasets list ------現在kaggle持ちのデータセットのリストが表示される
#
### 3.コンペのデータをダウンロード
1) ! kaggle competitions download -c '「コンペ名」' -----データのzipファイルがダウンロードされる
※https://kaggle.com/competitions/「コンペ名」

zipファイルを「example_dir」フォルダに解凍する
2) ! mkdir example_dir ------ 
3) ! unzip 「コンペ名.zip」 -d example_dir
#
参照文章：
https://www.kaggle.com/discussions/general/74235
プロジェクトマネージャ試験　午後Ⅱ論文Bランクで落ちた反省と考察

# はじめに

　本日、IPA（情報処理推進機構）の秋季情報処理技術者試験の合格発表でした。

 私はプロジェクトマネージャ試験を受験したのですが、結果は不合格…。
 
 ただ、**実務経験未経験・初受験**から、
 
 * 午後Ⅱの論文試験まで採点が進んだ
 * 午後Ⅱの論文の評価がBランク（合格まであと一歩）レベルをとれた

ので、そこに至るまでにやったことと、次回Aランク＝合格を勝ち取るための対策を書きたいと思います。

# 今回実際にやった勉強

## 午前Ⅰ（免除）

 今回は、応用情報技術者試験を合格した際の免除が使えたので、特に勉強はしていません。

 ↓応用情報レベルの問題はこちらで演習が◎

https://www.ap-siken.com/apkakomon.php

## 午前Ⅱ

　４択なので、過去問演習を中心に進めました。

　詳しくは、↓の記事にまとめています。

https://qiita.com/awonohata/items/b1c54dffffc0e989588e

↓過去問演習オススメサイト

https://www.pm-siken.com/pmkakomon.php

## 午後Ⅰ

### 問題の傾向

　　応用情報技術者試験の午後問題に似ています。ともかく、**文章読解のような問題**です。
　プロジェクトマネジメントの知識が必要かと言われると「うーん？」ですが、プロジェクトを円滑に進めるテクニック・考え方が重視されていそうです。

　問題が与えられたその場の思考力が試されるところかなと思います。（実務経験があれば実経験と照らし合わせたりできそうですが。）

### 使用したテキスト

* 2023-2024　プロジェクトマネージャ「専門知識＋午後問題」の重点対策

https://www.itec.co.jp/store/products/detail.php?product_id=3839

* 2023年度版 プロジェクトマネージャ 午後Ⅰ 最速の記述対策

https://tacpub.jp/list/detail.php?bc=110551

### 良かったこと

* **『重点対策』**
 解説がしっかりしていて、一通り過去問を解くのに向いています。特に午後Ⅱの問題も一緒に収録されているのがポイント。午後Ⅱの内容も触れてあったと思いますが、私は特には使いませんでした。

* **『最速の記述対策』**
　解き方のコツをざっくり知ることができるテクニック本。『重点対策』でダレてしまった時に買い足したのですが、本当に買って良かったです。「文章読解過ぎてどうやって解けばいいか迷子になる」方が多いと思いますが、回答の道標になるようなヒントが詰まっています。

### 改善点

 『重点対策』→『最速の記述対策』の順で勉強しましたが、反対に『最速の記述対策』から読んでざっくり解答の傾向を掴み、『重点対策』で過去問を実際に解いてみる、という順が効率が良いのではないかと思いました。

## 午後Ⅱ

### 問題の傾向

### 使用したテキスト

* 2023年度版 プロジェクトマネージャ 午後Ⅱ 最速の論述対策

https://tacpub.jp/list/detail.php?bc=110552

* プロジェクトマネージャ 合格論文の書き方・事例集 第6版

https://www.itec.co.jp/store/products/detail.php?product_id=3751

### 良かったこと

 『最速の記述対策』で、まず論文試験で何をやればいいのか大まかに掴めたこと。

 * いくつかのパターンに合わせて、あらかじめ解答モジュールを作る
 　→実際に解く場合は、要求された条件に合わせてモジュールを組み替える
 * 解答の際は、章立て・節立てを行う（可読性）
 * 要求された項目（聞かれていること）を主語にして記述する
 * 文字数は規定以上にする

### 改善点

 圧倒的な演習不足。
 モジュールを作るところ、解き方までは準備できたのですが、そこでタイムオーバーでした。
 
 せっかく作例が読めるのに、『合格論文の書き方・事例集』を、「第1章　本書を手にしたら読んでみる」を読んだ後に「本編は後で読めばいっか」とズルズル先延ばししてしまいました。結局試験日になっても一度も開きませんでした…。

 来年の試験に向けては、下記を視野に入れて勉強したいと思います。

 * 実際に書いてみること
 * 論文添削サービスを利用する

# まとめ

　結果を見た時、「悔しい」という感情よりも、「そうだよな」と腑に落ちる気持ちの方が強かったので、追い込みきれていなかったのは明白でした。そこは反省ではあるのですが、当日、最後まで諦めずに解答用紙を埋めた自分もそれはそれで偉かったので、褒めてあげたいと思います。（マークシートかCBT試験ばっかり最近受けていたので、本当に筆記試験が大人になってこんなに辛いものだとは思いもよりませんでした。）

 今回で知識の下地はできたと思うので、来年頑張って、合格記事を書きたいです！
早々の消費税対応

**「Z世代、お前の前にいるのは、三十年以上生きたエンジニアだ」**

タイトル回収は以上です。

---

メリークリスマス🎄
この記事は、本番環境などでやらかしちゃった人 Advent Calendar 2023の25日目、最終日の記事です。

https://qiita.com/advent-calendar/2023/yarakashi

# 消費税対応

業務系のシステムやECをやってた人なら聞き覚えがあるかもしれません。
人によってはトラウマワードかもしれません。

消費税は平成元年に導入されこれまで３回引き上げられています。

| 日付 | 税率 |
| --- | --- | 
| 1989年（平成元年）4月1日 | 3％ |
| 1997年（平成9年）4月1日 | 5％ |
| 2014年（平成26年）4月1日 | 8％ |
| 2019年（令和元年）10月1日 | 標準税率10%<br>軽減税率8％ |

販売などの要素があるシステムでは消費税をプログラムで計算することになります。

私が観測したのは8%以降なので、エルフ（先輩おじさんSE）からの伝え聞きですが、3%や5%のころはまだ設計が未熟でマジックナンバーやグローバル定数で消費税率を定義して、消費税額を求めているプログラムがよくあったそうです。

マジックナンバーで定義してしまうと消費税率が変更になったときすべてのプログラムを洗い出して変更しなければいけません。
グローバル定数で定義した場合も新しい消費税率の適用開始日を考慮して変更をかける必要があります。
未来の注文には未来の消費税率を適用しなければいけないからです。

8%の時代はそういった設計を見直し、適用日を持った消費税率テーブルなどを設けて、そこを参照して税率適用を行うような改修をほとんどのシステムが行ったと思います。

それも束の間、今度は軽減税率対応が必要になり適用日だけでは管理できなくなるという辛い仕打ちを受けるのですが…。

消費税対応は多かれ少なかれシステムに改修がかかるのと、対象となるシステムも多いためベンダーによっては特需のような扱いになるとともに、しわ寄せでデスマーチになる案件が多かったと聞いています。

そんな消費税対応に関するやらかしを…。

# 消費税対応完了
消費税対応が終わり無事リリースできました。
テストも問題なく完了し**設定した日に応じて新税率が適用されること**をしっかり確認できました。

後は新税率の適用日をドキドキしながら待つのみで、しばらく何事もなく運用を続けていましたがある日…。

# あれ、金額がおかしい…？
請求書を仮発行したら金額がおかしいとの問合せを受けました。
確認するとまだ適用日前なのに、新しい税率で消費税計算がされてしまっています。

まずはプログラムのバグを疑いますがおかしいところは見当たりません。

# どうしてこうなった
その原因は消費税率テーブルにありました。

リリース時に初期セットした税率テーブルが、あろうことか適用日が仮データのままセットされていました。
開発当初は税率適用日がまだ確定していなかったので、仮値で入れたものをそのまま本番に持ってきてしまったのです。

そして、そのまま**本当の適用日より早い状態で新税率が適用**されてしまいました。
皮肉にもプログラムには何の問題もないことが本番環境で証明されたのです。

請求書発行前に確認するプロセスがあったので気づけたのは不幸中の幸いですが、もし請求書が送付されたり口座から引き落とされていたら大変なことになっていたでしょう。

# まとめと教訓
:::note info
* 本番環境の初期データや移行データはその対象や中身をしっかり確認する
* プログラムが正しくてもデータが狂うと結果も狂う
* [ゾルトラーク](https://dic.nicovideo.jp/a/%E3%82%BE%E3%83%AB%E3%83%88%E3%83%A9%E3%83%BC%E3%82%AF)のように歴史の中で設計やプログラミング手法は一般化していく
:::

# おまけ
関連記事として、拙作のこちらの記事もよければどうぞ。

https://qiita.com/danishi/items/f65e2d80d48588aff764
Advent Calendar 2023完走した所感

# はじめに
初めてAdvent Calendarに参加して、連日記事を作成することは非常に大変でしたが、本記事を最後になんとか完走することができました。Advent Calendar完走した所感をまとめていきます。

# 所感
Advent Calendar完走して感じたことは沢山ありますが、自分の中で特に強く感じことは3つあります。

### 1. 常に記事になるネタはないかアンテナを張る癖がついた
私は個別カレンダーを作成し記事投稿を行っていました。記事内容に関しては、カレンダー作成後に中盤までに作成する記事の内容を大体決めていたものの何個か没になったりして25個のネタが準備できるかプレッシャーがかかっていました。そんな状況下で業務や資格取得を通して、何かネタはないのかとアンテナを張る生活が約1か月続いたことで、アンテナを張る癖がつきました。

### 2. 記事に言語化することで自分の思考を整理できること
前々から頭の中にある情報や新規で仕入れた情報を頭の中に入れておくのではなく、記事に言語化することで散らかっていた思考を整理することができていると感じました。思考を整理することで、モヤモヤがなくなり次の情報を頭の中にインプットしやすくなった気がしています。

### 3. 継続の鍵は一人ではなくみんなで挑戦すること
今回のAdvent Calendarは、一人ではなく開発チームのメンバーと一緒に挑戦していました。[こちら](https://qiita.com/Takaharu_01/items/6affd6446cfaf625ecee)の記事の内容と重複している部分はありますが、一人で挑戦していたら途中で辛くなった時期に止めていたと思います。最後まで完走できたのは、開発チームのメンバーからリアクションいただきモチベーション維持できたことが非常に大きいと感じています。また、開発チームのメンバーも頑張って記事投稿されているから自分も頑張らないという思いで必死に記事投稿に励むことができました。
Advent Calendarに限らず何か新しいものに挑戦する時は、一人ではなく誰かと一緒に挑戦することで長く継続することができるのではないかと感じました。

# おわりに
今回Advent Calendar完走できて本当に嬉しいです！完走賞のグッズ非常に楽しみです！来年も一人でなく誰かと一緒に完走目指して挑戦していこうと思います！
データ品質: 完全性の実装

こんにちは、株式会社タイミー データエンジニアの土川です。
この記事は[datatech-jpアドベントカレンダー](https://qiita.com/advent-calendar/2023/datatech-jp)21日目の記事になります。

以前登壇させていただいた「データマネジメントチームのマネジメントの方が難しかった話」のイベントでDMBOKを元にしたデータ品質と、タイミーでの取り組みについてお話しさせていただきました。
登壇では話せなかった実際に運用している品質定義について紹介できたらと思います。

これからデータ品質を実装しようとしている方々の参考になれば嬉しいです。

## イベント概要とスライド
https://timeedev.connpass.com/event/299088/

https://speakerdeck.com/ttccddtoki/dmbokwocan-kao-nisitadetamanezimentonoqu-rizu-mi

## データ品質

イベントの中では以下のような6種類のデータ品質について紹介させていただきました。

![DMBOKを参考にしたデータマネジメントの取り組み.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212172/d658d9b1-2843-9177-9aac-d7094f4ad038.png)

タイミーでは 適時性、一意性、完全性の3つのデータ品質の定義、監視をしていて、それぞれ以下のような定義になります。
特に完全性に関しては、欠損に対して色々な解釈ができると思っており、タイミーでの解釈について紹介したいと思います。

![データ品質を重視したデータ基盤プロダクト開発 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212172/c6ccdc96-3e09-328d-0fa2-76a369e78067.png)

## 完全性について
DMBOKの中でも紹介されているDAMA UKの完全性の定義は
> 完全な状態である 100%に対する保存されたデータの割合。

と定義されています。つまり、転送元データを真とした場合に、転送先DWHに対して欠損なくデータが転送できていると完全性は100%となります。

ただ、完全な状態のということは、最低限すべてのデータの中身が一致していることが必要なので、単純に完全性を比較しようとすると、
データ転送元がA行×B列のデータ量とした場合、転送先のA行×B列と1セルごとの比較を行い、一致している数を数えれば良いことになります。
式にすると以下のようになるかと思います。
```math
完全性[％] = (一致しているセル数) / A×B × 100
```

これを実現しようと思うと、A×Bの計算をすることになります。
これらを各テーブル、データセットで行う必要があることになります。
日々膨大な量のデータを転送している中で、この比較のための計算量はあまり現実的ではなく、タイミーでは完全性を抽象化して捉えることで、代替しようとしました。

## タイミーでの完全性定義について

タイミーでは、以下の3つの条件を満たすことで、あるデータセットに対する完全性を満たしていると定義しました。

    1. レコード数が一致している。
    2. レコードの中身があっている
    3. テーブル数が一致している

1のレコード数に対しては、転送元と転送先の同期間 (created_atを参照する) を比較し、一致しているレコード数を計測します。
物理削除とかが入ってくる転送元データセットに関しては、転送元のcreated_atと転送先のupdated_atなどを組み合わせてうまく比較する必要があります。

2のレコードの中身に関しては、先ほど説明した通り、転送元、転送先の2つの全データを比較する必要があるため、計算速度やコストの観点から現実的ではないです。
そこで、全レコードが一致しているかを __近似的に__ 判定するため、列ごとの統計量を比較することにしました。
統計量としては、とりあえず null_count を利用しました。
採用理由としては、
- データの中身が欠落することは考えられるが、nullではない値が変わってしまう事象は今まで観測されていないため、nullの数を数えれば十分
- string, integer問わず判定可能

となっていますが、ここは会社ごとに変わるかなと思っています。
こちらも同じように物理削除や、差分更新などのデータベースのCRUDや転送手段によって、単純なcreated_atをもとにした比較をするとidの数などがズレることがあるので、updated_atなどを使って、うまく同じ期間のidを引っ張ってくる必要があります。

3は単純なので、説明を省きます。

## 振り返りと今後
完全性の定義の抽象化により、現実的な計算量で完全性を保守できるようになりました。
完全性は1年くらいこの運用を続けているんですが、とりあえずデータの障害への素早い対応や、利用ユーザーへの品質担保はできるようになっています。
ただ、最近またデータ品質周りでの技術アップデートも多いので、データオブザーバビリティツール、dbtのテストなどを含めて品質監視周りのアップデートの改善をしていきたいと思っています。

最後まで読んでいただきありがとうございました。

## 終わりに
タイミーのデータ基盤はまだまだ課題も多く、一緒に開発してくださる方を募集しています!
やりたいこと・やるべきことに対して全く人が足りないのでご興味ある方はぜひお話できると嬉しいです！
X(Twitter)のDMなどでカジュアルにお話しすることもできるので連絡お待ちしております。

https://hrmos.co/pages/timee/jobs/1682251404118319115
軽量かつ高機能なHAVIT Blazorを使ったBlazor開発

## はじめに
エンハンスド株式会社の@KennethEHDと申します。
弊社ではBlazorを活用した業務システムやERPの開発を行っております。
今回はすでに業務システムやERPとしてクライアント様に提供しているBlazorのデザインコンポーネントをご紹介いたします。

## HAVIT Blazorとは
皆様はHAVIT Blazorをご存じでしょうか？
Blazorのデザインコンポーネントとしては、
##### 【OSS】
- MatBlazor
    - https://github.com/SamProf/MatBlazor
- Radzen Blazor
    - https://github.com/radzenhq/radzen-blazor
- MudBlazor
    - https://github.com/MudBlazor/MudBlazor
- Ant Design Blazor
    - https://github.com/ant-design-blazor/ant-design-blazor
- Blazorise
    - https://github.com/Megabit/Blazorise
##### 【商用（無償利用あり）】
- Infragistics
    - https://www.infragistics.com/products/ignite-ui-blazor
- Syncfusion
    - https://www.syncfusion.com/blazor-components
- Telerik
    - https://www.telerik.com/blazor-ui

などが有名だと思います。

上記はBlazor開発をする方は一度目にしたことがあるかもしれないですが、今回ご紹介する**HAVIT Blazor**はご存知でしょうか。

HAVIT Blazorは、チェコにあるHAVIT社が開発しているBlazor用のデザインコンポーネントです。
HAVIT社は、1997年創業で***Microsoft MVP: Development Technologies***である**Robert Haken**氏（[@RobertHaken](https://twitter.com/RobertHaken)）が代表を務めるシステム開発会社で近年はBlazorによる多くのシステム開発を行っております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659026/6d1528cf-cb18-9a44-0515-4ba8b8baf6cd.png)

https://www.havit.eu/

## HAVIT Blazorの特徴
こちらが[デモ](https://havit.blazor.eu/)のページになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659026/d81ff553-feb4-c6e2-e11c-6304bcc30848.png)

こちらのデモを見てわかるように非常にデザイン性が高い多種多様なコンポーネントが用意されておりRazor Pageからも呼び出しやすく軽量な作りとなっています。

特に弊社では業務システムとしてシステムを提供することが多いためテーブルビューを多用しております。

下記の画像のように　モデル化されたデータを渡すだけでテーブル表示が出来てインタラクティブなページングはもちろん各項目のソートを標準でつけることも可能です。

![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659026/f2384405-78a0-0868-d17b-3b935294794d.gif)

その他にもナビゲーションバーからモーダルやトーストなどデザインに必要なコンポーネントが豊富に用意されているので標準的なUI実装では困ることがないと思います。

![Animation2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659026/d6e4e9b1-db0e-9511-4c26-767ebb7bc16c.gif)

またダークモードの実装など細かな気配りは長年C#を活用したシステム開発を行い、多くのWebシステムを提供するHavit社ならではだと特徴だと思います。

## 最後に
弊社ではHAVIT Blazorをすでに複数のプロジェクトで活用し日本のクライアント様にも大変満足頂いております。ぜひ皆様も他のデザインコンポーネントに加え一度HAVIT Blazorを試してみてはいかがでしょうか？
この記事が皆様のBlazor開発の一助になれれば幸いです:tada:

## お知らせ
エンハンスド株式会社では、Blazorを用いた業務システムやERPによるクライアント様のDXを行っております。

グローバルでフルリモートな開発組織を構築しており日本のみならずシリコンバレーやその他の国にも開発メンバーがおります。

ぜひ一緒にC#/Blazor/ML.NETを活用し世の中に革新を起こしていきましょう！
C#を中心とした開発に興味がある方はお気軽にご連絡ください。
X（Twitter）にお気軽にフォローください！お気軽にリプやDMでご連絡お待ちしております！

https://twitter.com/KennethEHD

エンハンスド株式会社
https://enhanced.co.jp/
ChatGPTに入力した内容を学習させないように設定してみた


「エンジニアのためのChatGPT活用入門 AIで作業負担を減らすためのアイデア集 」を現在読み進めているのですが、その中で「ChatGPTに入力した内容を学習させない」ということが紹介されていたので、自分用に記事にしました。

また、今回の記事ではブラウザ版ChatGPTを前提に説明していきます。

### この記事でわかること
- ChatGPTに入力した内容を学習しないように設定する方法（オプトアウト）
- OpenAIはオプトアウトした情報をどう扱うとしているか？

### ChatGPTに入力した内容を学習されると恥ずかしい

```
あなた
まいっちんぐマチコ先生はどういうときにまいっちんぐというか教えてよ
デュフフ

ChatGPT
「まいっちんぐマチコ先生」は、日本の漫画およびアニメ作品です。
この作品における「まいっちんぐ」というフレーズは、主人公であるマチコ先生が
服の破れやスカートがめくれるなどのハプニングで露出してしまうシーンが発生した際に、
登場人物が驚いたり、冗談めかして使用するセリフです。
このフレーズは、作品のコミカルな要素を強調するためのもので、
作品全体の軽快な雰囲気を作り出しています。
```

これを学習されるのはまさに「いやん、まいっちんぐ」でしょう。
すみません。言いたかっただけです。

（まいっちんぐマチコ先生はさておき）
ChatGPTは精度を上げるために私たちとの会話からも学習を行っています。

それの何がまずいのでしょうか？
例えば案件でChatGPTを利用する際、誤って入力した機密情報をChatGPTの学習に使われてしまうと意図しない情報漏洩を起こしてしまいます。

それを避けるために「ChatGPTに入力した内容を学習させないように設定」する必要があり、それを「オプトアウト」といいます。

この後「オプトアウト」の設定をこの記事では行っていきます。

### オプトアウトの設定方法

①ブラウザ版ChatGPTの左下をつつき「プラス設定＆ベータ」を押します。
![s-CB_0003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/851d97b5-b6f5-3af4-db50-025d7873152e.jpeg)

②「データ制御」タブの「チャット履歴とトレーニング」をオフにします。
![s-CB_0004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/9a96ddb5-53b0-48e6-d01f-bc90ccb87b40.jpeg)

これでChatGPTはあなたの会話を学習データとして使わなくなりました。

私は自分の個人PCには絶対に業務情報を撃ち込まない主義なので利便性のためにオンにしています。

### OpenAIのドキュメントでは「オプトアウト」はどのような扱いか？

英語の翻訳結果を引用しています。

モデルのパフォーマンスを向上させるためにデータがどのように使用されるか
https://help.openai.com/en/articles/5722486-how-your-data-is-used-to-improve-model-performance

>お客様が当社の非 API コンシューマ サービス ChatGPT または DALL-E を使用する場合、当社はモデルを改善するためにお客様から提供されたデータを使用することがあります。ChatGPT 設定 (データ コントロールの下) でトレーニングをオフにして、トレーニングが無効になっている間に作成された会話のトレーニングをオフにするか、このフォームを送信することができます。**オプトアウトすると、新しい会話はモデルのトレーニングに使用されなくなります。**

本に書かれていた通り、オプトアウトすれば会話はもうモデルのトレーニングには使用されないことが確認できました。

ChatGPTを利用することで間接的に情報漏洩をした場合、間違いなく派遣なら一発退場、損害賠償の可能性などもありますので気を付けて使用しましょう。
Reactで扱うkeyについて2つのパターンで解説する

## はじめに
Reactではコンポーネントに対して`key`を付与できます。
```tsx
<Component key={key} />
```
`key`の型は`string | number | bigint | null | undefined`です。`key`はコンポーネントがUIツリーを構築する際の識別子として役立ちます。
この記事では`key`がどのように使われてどのような役割を持つかについて解説します。

## コンポーネントを繰り返し描画するために使う
`key`はコンポーネント内での繰り返し処理を記述する際に使われます。
```tsx
const Sample: FC = () => {
  const users = useUsers();

  return (
    <div>
      {users.map((user) => (
        <User
          key={user.id}
          name={user.name}
          mailaddress={user.mailaddress}
        />
      )}
    </div>
  );
};
```
`key`は`users`によって展開された複数の`User`コンポーネント同士を区別するために使われます。
これによって、異なるレンダー間で展開されるコンポーネントの増減や入れ替えをReactが賢く検知して最適なDOMの更新を行うことが可能になります。

繰り返し処理で生成した複数のコンポーネントに`key`がない場合や、`key`が重複している場合はコンソール上でエラーが発生します。一見問題なく動いて見えることが多いですが、思わぬバグに繋がったり、Reactが行う最適化の恩恵を受けられないので、コンポーネントにそれぞれ異なる`key`を渡すようにしましょう。
また、レンダー間で同一のコンポーネントには同じ`key`を付与してください。以下のように繰り返しのインデックスを元にした値を付与したり、ランダムな値を付与したりするとReactが最適化のための行動を起こせないです。
```tsx
// インデックス
{users.map((user, idx) => (
  <User
    key={idx}
    name={user.name}
    mailaddress={user.mailaddress}
  />
)}
// ランダム
{users.map((user) => (
  <User
    key={randomUUID()}
    name={user.name}
    mailaddress={user.mailaddress}
  />
)}
```
`key`を渡すためにコンポーネントの外部で一意の値を生成するか、外部から渡って来た時に持つ位置の値(DBのプライマリーキーなど)を元に作成してください。

## コンポーネントをリセットするために使う
レンダー間で異なる`key`をコンポーネントに付与することで、Reactがレンダー前後のコンポーネントを異なるものと判断し、コンポーネントのマウントをやり直します(再レンダリングではないです)。
これによって、対象のコンポーネントの状態をリセットできます。
以下はチェックボックスを切り替えると同時にコンポーネントの`key`を変更するテキストエリアと、`key`を付与しないテキストエリアを表示しています。

https://codesandbox.io/embed/rstm68?view=Editor+%2B+Preview&module=%2Fsrc%2FApp.tsx

両方のテキストエリアに文字を入力したのちに、チェックボックスを切り替えると、上のコンポーネントは状態がリセットされて何も入力されていないようになるのに対して下コンポーネントは状態の変化が起きていません。
下のコンポーネントで変化が起きていないのは、ReactはUIツリーにおいて同じ位置で同じコンポーネントがレンダーされるときに状態を引き継いてしまうからです(これは通常自然な挙動で悪い挙動では全くないです)。

このように、`key`を変更することでコンポーネントの初期化を行えます。上位のコンポーネントのある状態に依存して、コンポーネントを新しく生成したい場合は状態を初期化する関数を使って手動で行うのではなく、`key`を用いて行うことがおすすめです。これによって状態数が変更されることによって生じる初期化の漏れや、実質的に異なるコンポーネントであることを明確にReactに伝えられます。
【Go言語】アプリケーションドメインに特化した定義型の作成

Go言語での**定義型の作成**は、アプリケーション固有の**ドメインロジックを効率的に扱うための重要な技術**である。
関心事を分離し、コードの凝集度を高めることができる。

### スライスへの型定義
スライスに対する型定義は、コードの見通しを良くし、ユニットテストを容易にするという利点がある。
例えば、特定の条件を満たす要素のみを抽出するメソッドを定義型に追加することができる。

```go
package main

import (
	"fmt"
)

// Consumer 型の定義
type Consumer struct {
	Name      string
	ActiveFlg bool
}

// Consumers 型の定義
type Consumers []Consumer

// ActiveConsumer メソッドの定義
func (c Consumers) ActiveConsumer() Consumers {
	var resp Consumers
	for _, v := range c {
		if v.ActiveFlg {
			resp = append(resp, v)
		}
	}
	return resp
}

func main() {
	consumers := Consumers{
		{Name: "Alice", ActiveFlg: true},
		{Name: "Bob", ActiveFlg: false},
		{Name: "Charlie", ActiveFlg: true},
	}

	activeConsumers := consumers.ActiveConsumer()
	fmt.Println("Active Consumers:", activeConsumers)
}

```

### 値への型定義

個々のデータ要素に対して型定義を行うこともできる。
これにより、特定の値に特有のロジックを組み込むことが可能になり、バリューオブジェクトのような実装が可能になる。

```go
package main

import (
	"fmt"
)

// SKUCode 型の定義
type SKUCode string

// SKUCode 型のメソッド定義
func (c SKUCode) ItemCD() string {
	return string(c)[0:5]
}

func main() {
	var sku SKUCode = "T0123010102"
	itemCD := sku.ItemCD()
	fmt.Println("Item Code:", itemCD)
}

```

### 列挙への型定義
列挙型のようなデータに対しても、Goでは特定の処理をレシーバーとして追加することができる。
これにより、特定の条件に基づく複雑なロジックを効率的に処理できるようになります。

```go
package main

import (
	"fmt"
)

// Season 型の定義
type Season int

const (
	Peak Season = iota + 1
	Normal
	Off
)

// Season 型のメソッド定義
func (s Season) Price(price float64) float64 {
	if s == Peak {
		return price + 200
	}
	return price
}

func main() {
	var currentSeason Season = Peak
	price := currentSeason.Price(1000)
	fmt.Println("Price:", price)
}

```

### 構造体への型定義
構造体に対して型定義を行うことも一般的。
構造体のフィールドやメソッドを通じて、より洗練されたデータ操作を実現することができる。

```go
package main

import (
	"fmt"
)

// SensorData 型の定義
type SensorData struct {
	SensorType string
	Value      float32
}

// SensorData 型のメソッド定義
func (r SensorData) ReadValue() float32 {
	if r.SensorType == "Fahrenheit" {
		return (r.Value - 32) * 5 / 9 // 華氏を摂氏に変換
	}
	return r.Value
}

func main() {
	sensor := SensorData{SensorType: "Fahrenheit", Value: 86}
	value := sensor.ReadValue()
	fmt.Println("Temperature:", value, "°C")
}

```


## 参考
https://www.oreilly.co.jp/books/9784873119694/
Promiseが難しすぎるから少しだけ整理してみた

## はじめに
この記事は以下の記事の続きです。
非同期処理についてまとめてあるので、先にこちらをご覧ください。

https://qiita.com/odendayoko/items/db811001573055da12f0

簡単にまとめておきます。

:::note warn
- JavaScriptでは、プログラムの実行はシングルスレッドで行われる
- 非同期処理はAPIコールなどの時間がかかる処理で使われる
- ひとつの非同期処理が終わるのを待たずに次の処理を進める
- 非同期処理はイベントループという仕組みによって、同時に複数の処理を実行することができる
- 非同期処理の中で例外が発生しても、非同期処理の外ではそれを感知できない
:::

今回は非同期処理が完了した後にどうするか？を書くための方法について考えます。
非同期処理でエラーが起きた時、成功した時、どちらも書く方法があります。
それが`Promise`、`aysnc/await`です。

## Promise
>PromiseはES2015で導入された非同期処理の状態や結果を表現するビルトインオブジェクトです。

**ビルドインオブジェクト**とはJavaSctiptに最初から組み込まれているオブジェクトです。自前で定義しなくても勝手に使えます。

JavaScript Primerを読んでも言葉が難しくてよくわからなかったので重要そうなところだけまとめます。

:::note warn
- 非同期処理はPromiseインスタンスを返す
- Promiseインスタンスは非同期処理が成功(resolve) / 失敗(reject)した時にどうするかを`then/catchメソッド`に書いておける
    - 成功した時=>thenの第一引数に書く
    - 失敗した時=>thenの第二引数、catchに書く
- Promiseのthen/catchメソッドは、メソッドチェーンで繋げて書ける（**Promiseチェーン**）
:::

```javascript
// 非同期処理をする部分
// asyncPromiseTask関数は、Promiseインスタンスを返す
const asyncPromiseTask = () => {
    return new Promise((resolve, reject) => {
        // 非同期処理に成功した場合は、resolveを呼ぶ
        // 非同期処理に失敗した場合は、rejectを呼ぶ
    });
}

// 非同期処理の結果を扱う部分
// asyncPromiseTask関数の非同期処理が成功した時、失敗した時に呼ばれる処理をコールバック関数として登録する
asyncPromiseTask().then(()=> {
    // 非同期処理が成功したときの処理
}).catch(() => {
    // 非同期処理が失敗したときの処理
});
```

Promiseについてはこれで十分ではないでしょうか。というよりも難しくてわかりませんでした😭
とりあえず今はこの理解だけで逃げます！！！！

### Promiseの問題点
Promiseのthen/catchメソッドによって、非同期処理が完了したらその結果を感知して何をするか？を簡単に書くことができます。
ただし、Promiseにはいくつか問題点があります。
- 次の非同期処理をしたい、非同期処理を実行して返ったきた結果を使いたい時
    - ⇒非同期処理間で連携するためにはPromiseチェーンを繋げないといけない
- 条件分岐したい時
    - ⇒ネストが深くなる
- 書いた順に実行されない可能性がある
    - =>ソースコードが読みにくい

```javascript
const exampleProblem = () => {
  fetchData()
    .then((data) => {
      console.log("Data:", data);

      if (shouldProcessData(data)) {
        // ネストが深くなる
        return processValidData(data);
      } else {
        return processInvalidData(data);
      }
    })
    .then((result) => {
      // チェーンが長くなる
      console.log("Result:", result);
    })
    .catch((error) => {
      console.error("Error:", error);
    });
}
```
わーなんて読みにくいんでしょう😇
タイマーとかセットされていたら、実行される順番もぐちゃぐちゃになってしまいます。
これがPromiseの問題点です。

せっかくthenとcatchという便利メソッドが使えるのに、それが返ってコードの読みにくさを生んでしまっています。
これを改善するために生まれたのが、`async/await`です。

ES2017では、Async Functionという非同期処理を行う関数を定義する構文が導入されました。
Async Functionは必ずPromiseインスタンスを返すので、そもそもPromiseがわかっていないと話になりません。


非同期処理難しすぎませんかね？
ちっともわからない😭
明日はAsync Functionについてまとめます。

### 参考
https://jsprimer.net/basic/async/#promise
アプリケーションロジックでtime型を扱う際のTips

この記事は、[Go 言語 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/go) の21日目の記事です。

Go言語で時間を扱う際の実装のTipsを2つ紹介します。これらは筆者の個人的な経験に基づくものであり、必ずしもすべてのケースに当てはまるわけではありません。

それでは、本題に入っていきましょう

### Tips1 引数名
time.Time 型の値を引数として受け取る関数を作成する際の引数名について考えます。
```go
func funcA(now time.Time){
    return
}
```

関数の呼び出しを考えると、以下のように処理が始まるタイミングで`time.Time`型の変数を初期化、`funcA`に渡すと思います。
```go
now := time.Now()
funcA(now)
```

`now`という引数名にも違和感がないですね

その際に1点考えて欲しいことが「`funcA`が受け取る`time.Time`は、必ずしも現在時刻を期待するのか？ 」ということです。

現在時刻を渡すような使用しかしていない場合でも、`funcA`の処理自体は現在時刻をマストとして期待していない（指定された日時をもとに処理を実行するだけ）という意味合いであれば、引数名は`now`ではなく、`t`が適切なのかもしれません。

### Tips2 タイムゾーン
アプリケーションでの時間比較処理におけるタイムゾーンの扱いについて考察します。

時間比較処理には以下のようなシーンが考えられます。
- アプリケーションコードにハードコーディングされている日時との比較
- DBから取得したレコードの時刻型との比較
- などなど

時間比較処理において、time.Time と string を変換する際、time.Time はタイムゾーンを自動的に扱いますが、string への変換ではタイムゾーン情報が失われてしまうことです。

つまり`time.Time`同士で比較をする場合、タイムゾーンは開発者が意識しなくてもうまく変換してくれます。
しかし、`time.Time`と`String`の変換を介している場合、タイムゾーン情報は保持されません。

例えば、日付をプレフィックスとして持つID（例：2023-12-01-Xxxxx）を現在時刻と比較するシーンがあります。
（マスターデータのIDにプレフィックスとして日付を持たせるケースはよく目にします）

そんなときに[cloud.google.com/go/civil](https://pkg.go.dev/cloud.google.com/go/civil#pkg-types)パッケージが有用です。提供される時間型（`civil.Date` や `civil.Time`）はタイムゾーン情報を持たないため、日付のみを扱う場合の比較が容易になります。

そのため、例に挙げたようなマスターデータのプレフィックスを時刻型としてパースする場合は、`civil.Date`に変換し、変換対象の`time.Time`型の値も`civil.Date`に変換し、比較することができます。

しかし以下の点に注意する必要があります
- time から civil への変換時にどのタイムゾーンを使用するか
- string で持たせる日時データがどのタイムゾーンを前提としているか

これらのルールをプロジェクト内で定めることで、時間比較を正確に行うことが可能になります。
エンジニアみんなで「ムービング・モチベーターズ」やってみた

# はじめに
本記事は[QualiArts Advent Calendar 2023](https://qiita.com/advent-calendar/2023/qualiarts)の22日目の記事です。

QualiArtsの[開発ディレクター](https://technote.qualiarts.jp/article/44/)をしている川下です。
その傍ら[QUBE](https://qiita.com/asakuranobuharu/items/15a82ea0017358207f37)という組織に所属し、QualiArtsのエンジニア組織の育成や成長について戦略を練ったりしています。

本記事では、そのQUBEの活動の一環で開催したエンジニアワークショップについて紹介したいと思います。

# ワークショップの目的
**「エンジニアの成長が加速し、継続的に事業成果があげられるエンジニア組織」**
こちらがQUBEのテーマです。この組織をめざすうえで必要なことについて、メンバーでブレストをしました。
その中で、「セルフマネジメント」「モチベーション維持」といったワードが出てきました。
そこで、自分のモチベーションを理解することと、チームメンバーにも知ってもらうことを目的として、**ムービング・モチベーターズ**を用いたワークショップを開催することになりました。


# ムービング・モチベーターズとは
自分の価値観と他人の価値観の違いを理解するための、Management3.0のゲームです。
「**10の本質的なモチベーション**」が描かれたカードを用います。
このゲームを通して、自分と他人のやる気スイッチを理解することで、お互いの気持ちを尊重し合ったり、新たなコミュニケーションが生まれたり、トラブルを避けるきっかけになるかもしれないというものです。


# ルール
今回のルールを紹介します。
### ベーステーマ
モチベーションというのは、状況によって変化するものです。
そのため、まずはどんなことに対するモチベーションについて考えるのか定めます。
今回のワークショップでは、「仕事あるいは会社に対するモチベーション」というテーマにしました。

### 10枚のカード
「10の本質的なモチベーション」が用意されています。
カードは購入することもできますが、PDFでも配布されています。
[NuWorks](https://nuworks.jp/ja/company/)の[こちら](https://nuworks.jp/ja/2016/10/26/moving-motivators/)にダウンロードリンクがあります。ムービング・モチベーターズの詳しい説明も載っています。
* 受容
「私の周りの人が、私がやっていることや私らしさを認めてくれる」
* 好奇心
「調査したり、考えたりしたいことがたくさんある」
* 自由
「私は自分自身の仕事と責任で他人から独立している」
* 地位
「私の職位は優れていて、いっしょに働いている人たちから認められている」
* ゴール
「私の人生の目的が、私がしている仕事に反映されている」
* 名誉
「私個人の価値が私の働き方に反映されていることを誇りに思う」
* 熟達
「私の仕事は難しいが、まだ能力の範囲内にある」
※*この認識が人によって曖昧になりそうだったので、今回のワークショップでは「挑戦」という意味合いで捉えてもらいました*
* 秩序
「安定した環境のための十分な規則と方針がある」
* 権力
「私の周りに起きることを自分で左右できる裁量がある」
* 関係性
「私は仕事でかかわる人々と良好な社会的つながりを持っている」

### グループに分かれる
今回のワークショップには40名以上のエンジニアが参加してくれました。
ひとつの広い空間に集まって、所属しているプロジェクト単位で3~6名一組のチームを作り、テーブルで分かれてワークを行いました。

### カードを並び替える
自分にとって大切だと思う順にカードを並び替えてもらいました。
５分程度で直感的に考えます。

### 発表する
並び替えたTOP3とWORST1のカードを、グループのメンバーに共有をしてもらいました。
なぜその順番にしたのか理由を説明をしながら紹介します。

### 感想を共有する
全員一周した後、歓談の時間を設けてメンバーの発表について感じたことを自由に話し合ってもらいました。
他の順位についても見せ合いながら話すチームが多かったです。

# 当日の雰囲気
ワークショップを始める前に、ルール説明と合わせて
「ぜひ楽しんで、ワイワイガヤガヤしながら参加してください！」と伝えていたおかげか、非常に和やかな雰囲気でみんな楽しんでくれていたように思います。

![IMG_8970.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208477/fc9cf132-7962-e029-3f0e-c86b6da01dc9.jpeg)

コロナ禍が続いていたため、久しぶりに大勢で顔を合わせてのイベントとなりました。
リモートで参加しているメンバーにはあらかじめPDFを配布し、グループ全員の発表がしっかり聞こえるように各テーブル工夫して共有してくれていました。


# 最後に
これまで自分の仕事に対するモチベーションをなんとなくでしか考えていなかった人も、これをきっかけにして自己理解を深めてくれていたように思います。
（お金は？という声もちらほらありましたが、選択肢にお金がないことについてはManagement3.0を調べてみてください）
また、同じプロジェクトのメンバーのモチベーションを知り、知ってもらうことで、心理的安全性も高まったと思います。
久しぶりのオフラインイベントということもあり、雑談にも花が咲いていたように感じました。

今後も定期的にワークショップを開催していくつもりですので、そのときにはまた紹介していきたいと思います。
【React】Suspenseを使ってLoadingを表示する

## 目次
- Suspenseとは？
- Suspenseのインポート
- Suspenseの使い方
- Loading部分を作ってみよう

## Suspenseとは？

ReactのSuspense機能を使うと、`ローディング中`と`ローディング後`に表示したいものを簡単に管理することができます。

Suspenseとはサスペンスドラマのサスペンスと同じ意味で、「これから何か起きる！ドキドキハラハラ」と同じ状況を作り出します。

何かが起きるまで待っている間＝ローディング中、
何かが起きた＝ローディング後
のようなイメージです。

なのでSuspenseを使うことでローディング中はローディングの表示をして、ローディングが完了したら表示したかったものを表示するといったシンプルな仕組みです。

## Suspenseのインポート

こんな感じでimportします。

```react
import { Suspense } from `react`;
```

## Suspenseの使い方

Suspenseは以下のように使います。

```jsx
<Suspense fallback={<Loader />}>
  <SomeComponent />
</Suspense>
```

ローディング中に表示したいコンポーネントは`fallback`で設定します。ローディングが完了した時に表示されるのは`<Suspense></Suspense>`で囲ったコンポーネントになります。つまりローディング中はLoadingというコンポーネントが表示されて、ローディングが終わったらSomeComponentというコンポーネントが表示されます。

Suspense機能のロジックは、Promiseをthrowすることによって「ローディング中なのでレンダリングできない」という状態を作っています。

## Loading部分を作ってみよう

Loadingコンポーネントも作ってみましょう。

ローディング中の数値を取得するには`useProgress`をインポートします。HTMLとして記述できるように`Html`もインポートします。インポート先は`react-three/drei`です。これは`react-three/fiber`用のヘルパー関数などを提供してくれるライブラリです。

```react
import { Html, useProgress } from '@react-three/drei'

const Loader = () => {
  const { progress } = useProgress()
  return <Html>{progress} % loaded</Html>
}
```

## まとめ

Suspenseの使い方はシンプルでした。ローディング中とローディング後に表示したいものがあっさり書けちゃいました。

```react
<Suspense fallback={<ローディング中のコンポーネント />}>
  <ローディング完了後のコンポーネント />
</Suspense>
```

ローディング中に表示するコンポーネントでは`useProgress`を使用することで、数値を表示することができました。

これでSuspenseを使ったローディング中の表示はバッチリですね！
ViteでReactの開発環境を構築してみた

## はじめに
Reactの環境構築でよく使われる`create-react-app`。
Reactの公式ドキュメントを拝見すると、フレームワークなしのReact環境はあまり推奨されていないようでした。

以下、[公式ドキュメント](https://react.dev/learn/start-a-new-react-project) 抜粋。
> フレームワークなしで React を使用することは間違いなく可能です。それが、ページの一部に React を使用する方法です。 ただし、React を完全に使用して新しいアプリまたはサイトを構築する場合は、フレームワークを使用することをお勧めします。

それでいて、`create-react-app`の最新バージョンのリリース日は2022年4月。
バージョンアップがここ1年ほどされておらず、少し不安がある。

そうはいってもフレームワークに依存しない純正なReactの学習をしたい場合などにどうしてもReactの環境構築をしなければいけないときがあると思います。
そんなときに私がおすすめするのがViteでReactの開発環境を構築することです。

## Vite環境構築
nodejsはインストール済みとします。今回のnodeバージョンは v20.10.0です。
voltaでバージョン管理する記事を書いたのでこちらも参考にしてください。

[【Volta】node.jsバージョン管理ツールをVoltaに乗り換える【設定手順】](https://qiita.com/futaro0405/items/24676747296e057354bb?utm_campaign=post_article&utm_medium=twitter&utm_source=twitter_share)

まずはこのコマンドでプロジェクトを作成します。
```
npm create vite
```

プロジェクト名を入力します。

```
? Project name: » vite-project
```

使用するフレームワークを選択します。今回はReactを選択します。

```
? Select a framework: » - Use arrow-keys. Return to submit.
    Vanilla
    Vue
>   React
    Preact
    Lit
    Svelte
    Solid
    Qwik
    Others
```

今回は「JavaScript + SWC」を選択します。
SWCはVercel社が開発しているBabelに代わる新しいコンパイラーです。
Babelより相当早いコンパイラーなので使ってみてください。

```
? Select a variant: » - Use arrow-keys. Return to submit.
>   TypeScript
    TypeScript + SWC
    JavaScript
    JavaScript + SWC
```

これでプロジェクトの作成は終わりです。
`package.json`が作成されていることを確認したらディレクトリを移動してパッケージのインストールを行ってください。

```
cd vite-project
npm i
```

問題なくプロジェクトの構築ができたか確認します。
開発サーバーを起動してみましょう。

```
npm run dev
```

起動出来たらプロジェクトの環境構築は完了です。
Happy hacking!
【Next.js】サーバー側で使用できない関数を使用した際にエラーが発生するようにする方法

`server-only`をインストールします。

```terminal
npm i server-only
```

サーバー側で使用できない関数を記述したファイルに以下のように`import "client-only"`を記述することでサーバーサイドで実行された際にエラーが発生するようにできます。

```
import "client-only"
```
学園祭の企画管理システム(一部)と認証システムを作った話

この記事は、[木更津高専 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/nit_kisarazu) 22日目の記事です。
←前 [AtCoder入緑記事](https://qiita.com/toma09to/items/08438b8f92f6b4d21707) by @toma09to 
→次 祇園祭WebサイトのDBについて by @NXVZBGBFBEN 

# はじめに
プログラミング研究同好会(プロ研)のnaotikiです

今年度、プロ研は木更津高専の学園祭「祗園祭(ぎおんさい)」のホームページ(+システム)を作りました！

今回は私が主に担当した認証関連について書きたいと思います。

:::note warn
本記事は私個人(naotiki)の意見・見解です。
木更津高専、木更津高専プログラミング研究同好会、木更津高専学園祭実行委員会とは一切関係ありません！
:::

# 管理画面の認証をつくる

学園祭ホームページには各企画のお知らせを表示する場所があり、各企画の最新の情報を見られるようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357553/88c35af9-0f8b-a3bf-ae0a-7b5c4174c456.png)

ということはこれを投稿できるようにする画面も必要な訳ですが、誰でもURLさえ知ってれば投稿できるとかだと駄目なので認証しないと投稿できないようにします。

しかし、一から認証を作るのは色々あって死んでしまうので、すばらしいフレームワークを使うことにしました。
今回は NextAuth.js を使いました。[^1]

https://next-auth.js.org/

ログインする方法はEmail(メールリンク)とCredential(メール+パスワード)の2つにしました。
あと、条件として事前に許可された人しかログイン(ユーザー登録)できないようにします。

ORMには企画管理でPrismaを使用していたのでそこに認証系のテーブル情報も書き加えていきます。

ほぼ https://authjs.dev/reference/adapter/prisma#create-the-prisma-schema-from-scratch にあるやつのコピペですが、 `User` と アクセスを許可された学生のデータが入ってる `Member`を紐付けられるようにしました。

```text:Memberの情報
model Member {
  id          String   @id @default(uuid()) @db.Uuid
  email       String   @unique @db.VarChar(255)
  alias       String   @db.VarChar(255)
  displayName String   @db.VarChar(255)
  group       Group[]
  role        Role     @default(Member)
  createdAt   DateTime @default(now())
  modifiedAt  DateTime @updatedAt
  user        User?
}
```

あとは、`/pages/api/[...nextauth].ts`を**いい感じ**に書きます。

主に設定したことは
* メールをとりあえず自分のメールアドレスからMicrosoftのアプリパスワードを使って送信
* サインインするとき、Memberテーブルにメールアドレスがなければサインインを拒否
などです。

ついでにMiddlewareを設定して管理画面は認証必須にします。
```ts:middleware
export { default } from "next-auth/middleware"
// /dashboard以下 すべてに適用
export const config = { matcher: ["/dashboard/:path*"] }
```

ログインして認証に成功すると管理画面に飛べます！

これはユーザー情報を見られる画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357553/e300a586-48d9-f92e-6800-a9365bfb41de.png)
パスワードログインが設定されていない人はここからすぐ設定画面へ行けるようにしてあります。

# APIを保護する
せっかく管理画面を保護してもAPIを叩けたら意味が無いので管理APIも認証を必須にします。
NextAuth.js のおかげですぐにできます。

```ts
await getServerSession(req, res, authOptions);
```
で`Session`または`null`(未認証)を取得できるのでこれを基にレスポンスすればいいだけです。

簡単！

# おわり
NextAuth.js(Auth.js)を使うと、JWTとかセッション管理とかあまり気にせず手軽に認証を追加できて最強になれるのでとても楽でした！

~~それはそれとしてドキュメントをなんとかしてほしかった・・・~~

[^1]: [Auth.js](https://authjs.dev/)に移行中っぽいです。ドキュメントの整備とパッケージ名の移行が中途半端なせいで地獄を見ました。恨みます。
実装時遭遇エラー

実装時に遭遇したエラーについて、大小問わずメモ書きです。
随時更新できればと思います。

# SQLException: ORA-03115: サポートされていないネットワークのデータ型または表現があります
executeQueryに引数を入れてました。引数を消したら解決しました。
```
resultSet rs = ps.executeQuery(sql); // 誤り
resultSet rs = ps.executeQuery(); // 正
```
[java.sql.SQLException：ORA-03115：サポートされていないネットワークのデータ型または表現](https://www.web-dev-qa-db-ja.com/ja/sql/javasqlsqlexception%EF%BC%9Aora03115%EF%BC%9A%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E5%9E%8B%E3%81%BE%E3%81%9F%E3%81%AF%E8%A1%A8%E7%8F%BE/1071574397/)
# Caused by: java.sql.SQLException: 転送専用の結果セットに対する操作が無効です。 : first
ORA-17075と同義？
順方向にしか移動できないカーソルに対して、next()以外のことをして発生しました。
resultSetはデフォルトでは順方向のみのようです。（ResultSet.TYPE_FORWARD_ONLYを設定した場合と同様）
順方向以外にカーソル移動をしたい場合、createStatement/prepareStatementに対して引数でカーソル種別の指定を行うことで解決できるそうです。
※私の実装環境ではスクロール可能な結果セットがサポートされておらず、上記の対応を行ってもnext以外のカーソル移動はできませんでした。
```
// SQL実行
resultSet rs = ps.executeQuery();

// 取得レコード数のカウント
int count = 0;
while (rs.next()){
    count++;
}

// カーソルを先頭へ移動
rs.first(); // ここでエラー発生
```
順方向にしか進めないけどレコード数カウント後にカーソル先頭から処理を行いたい場合、以下方法になりそうです。
①カウントのwhile文内でカウント時に処理を行う。
②SQL実行を2回行い、1つをレコードカウント用、もう1つを別処理に使用。
パフォーマンス等、懸念事項はあるためどちらが良いかは仕様や目的次第かと思っています。（今回は①で回避しました。）
[カーソル移動](https://www.ibm.com/docs/ja/i/7.5?topic=resultsets-cursor-movement)
[5. ResultSetを用いた更新処理](https://www.techscore.com/tech/Java/JavaEE/JDBC/5/)

# SQLExceptioin: ResultSet.nextはコールされませんでした。
SQL実行時点では、カーソルはどこも指していないようです。
値取得を行いたい場合、next()等でカーソル指定をしないとこのエラーで落ちます。
```
// SQL実行
resultSet rs = ps.executeQuery();

// 実行結果から値取得
rs.getInt(1); // ここでエラー発生

// 取得レコード数のカウント
int count = 0;
while (rs.next()){
    count++;
}
rs.getInt(1); // ここならOK
```

[JAVA.SQL.SQLEXCEPTION: RESULTSET.NEXTはコールされませんでした。](https://blog.felt-life.info/it-gate/2012/05/01/resultset_next_null/)


# .splite()が想定通りに動かない
"|"（パイプ文字）で区切りを入れた文字列をsplite()で分割しようとしましたが、正規表現の特殊文字のため想定通りに動きませんでした。
バックスラッシュを入れてエスケープしたら想定通りの挙動になりました。
```
// 不具合再現
String test = "hoge|fuga";
String[] list = test.splite("|");
console.log("1:" + list[0] + " 2:" + list[1]);

// 出力結果
1:h 2:o

// 修正後
String[] list = test.splite("\\|");
console.log("1:" + list[0] + " 2:" + list[1]);

// 出力結果
1:hoge 2:fuga
```
防災に関わってきて約4年間

これは、防災アプリ開発 Advent Calendar 2023の22日目の記事です。
昨日は。りーちゃんさんの記事でした

# 初めに
こんにちは、今年も書きます。孤独のコーヒーです。
![codqJS-E_400x400.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613330/b5d0b306-b10b-f6da-f835-662473f6345d.jpeg)

さてまず自分の自己紹介から、、主にDiscordBOTを開発している高校2年生です。
メインの開発はDPIとゆう名前の気象・地震・災害などなどの情報をwebhookで送信するBOTです（唐突な宣伝）
（余談ですがこのアイコンの写真は私がとったものであり、一枚しかない写真です。そして小さく映っているのは妹です）
# いきなり本題
いきなりですが、まずこの防災関連の世界に入ったのは今から4年前（え、4年たつの、、）の北海道胆振東部地震が発生し自分も札幌在住のため当然被災。
少し胆振東部地震について語ります。
![2023-12-21_23h23_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613330/bff9f3c1-d5d6-8275-607b-877a8797baac.png)
この地震が発生したのは、午前3時8分当然就寝していますが、突如経験したことのない揺れに襲われ飛び起き、当時まだ小学5年生？6年生？（どっちか忘れた）でしたが、ラジオに興味がありその夜もラジオを聞きながら寝落ちしたため、ラジオからは当然あの警報音がなっていました。
そして自分の地域は停電するのは遅く午前3時24分とかそれぐらいです。そのため最初はTVで情報収集可能でした。しかし停電情報源はスマホをもっていないため、ラジオonly。
ラジオでは大規模な土砂災害が発生と言っていましたが。最初は全くわからずTVで初めて規模をしり絶句。。。
その後恥ずかしながら親としばらく寝てました。
そしてPCで防災について調べると「BSC24」とゆうニコニコの生放送があることを認知。
# BSC24を知ってから

そして視聴しながら、様々なアプリがあることを知りました。
最初はkiwiを入れていた覚えがあります。
しばらくkiwiや強震モニタBSC24を開きながら寝ていました。
（今でもそうです。）
しかし、もっと自分でも知りたい！と思ったのがちょうどコロナの時代です。
また外出先からだと情報が知りたくてもいろいろなサイトなどにアクセスしないと見れず、一括していろいろな情報を仕入れるには結構きつかったです。さらに、
とにかく暇で少し脱線しますが、Pythonを書くようになりこのころは防災から少し離れただの総合BOTをかいていました。
しかし、そろそろ普通のBOTも書くのが飽き別のBOTも書きたい！となった時に、、、、

**災害を提供してくれるBOTなくね**
そーなんです。今は少し増えましたが、今から2年前はほぼなく、ただ地震情報を伝えるＢＯＴは多少ありましたが、気象情報を発信しているＢＯＴはありませんでした。

そこで、、

## 自分で作ればよくね。
ここで、自分の運命(?)が大きく変わりました。
最初に作ったのは今から２年前の2020年まさかの大晦日
（なにやってんすかね。最初はマジで自分用だったのでCMDに表示するだけでした。（たしか写真がありますが、とりあえず上げることを優先します後日編集します！！。現在23時38分間に合え！！）
そして、知り合いより、誘われDiscordにも発信するようになり。
現在は400鯖を超える導入をしていただいています。
（まことに感謝！）

# 最後に
いろいろなんか脱線しましたが、これが約4年間防災に足を突っ込んだ人です。
ここまで読んでくれた方は感謝です。
来年もよろしくお願いします
（ふう、なんとか間に合いそう、23:45 
みんなはもっと計画もって書こうね！！！！

明日はともりんさんです。お願いいたします
pipって何よって話(pythonの話です)

# pipとは

1. Pip installs Packagesの略。プログラミング言語のPythonで開発されたパッケージ管理システムの一つ
1. Pythonの標準に含まれている。
1. 指定したパッケージが他のパッケージを利用している場合(依存関係)にあるとき、参照先のパッケージをインストールしてくれる。

# 会社でpipを利用するための障壁

## ありうる問題
1. 会社がプロキシサーバーでpipの利用を禁止している
1. 上記の問題が故に必要なパッケージが利用できない

### 何だかよく分からないという人のための用語解説
1. **プロキシサーバー**
    PCとネットの中間にたって安全な情報のみを承認するインターフェース
1. **パッケージ**
    必要な機能のまとまり
    Pythonでは必要な機能を再利用しまくって、開発をおこなっている。これらの機能は他の機能を参照していることが多く、その依存関係も調べて自動で必要なパッケージも自動検索で見つけてくれる。
    参照で紹介している、パッケージを一つ一つダウンロードする方法はあるが、スムーズな開発難しい

## 会社で使えないときの対処法
1. **情報システムに相談**
Pythonの必要性を訴えて、必要な情報(プロキシサーバーのアドレスを教えてもらう)
2. **既に導入している部署に相談**
    手順書などがあればそれを見せてもらおう
## プロキシ経由でpipを使うときのコマンド ##
    pip install --proxy="proxyserver:port" [package]





# 参照
https://python.org/

https://e-words.jp/w/pip.html

https://danniko.blog/programming/proxy-pipinstall/amp/

https://codechacha.com/ja/pip-install-beyond-proxy/
同一プロジェクト内で、複数ページを指定する（GAS）

# 議事概要
同一プロジェクト内で、複数ページを指定する。  
=> GETパラメーターでアクセスページを分ける。
例 ```?template=index```

# ソース
```main.js
function doGet(e) {
    const template = e.parameter.template
    return HtmlService.createTemplateFromFile(template)
      .evaluate()
      .setTitle('Title')
      .addMetaTag('viewport', 'width=device-width, initial-scale=1')
      .setFaviconUrl('https://xxx.png')
}
```
計算機をjavaScriptで実装して思ったこと

# はじめに
こんにちは。えか太郎と申します。ポエム回となっております。かなりの駄文。プログラミング初めて1週間くらいのときにJavascriptとで計算機を作ったときに感じたことについて書いていきます。

# 前提条件（当時の私の状況）
* プログラミング初心者
* HTMLとCSS、JavaScriptの基礎を学んだぐらい
非同期処理なんて単語を聞いたこともないくらい初心者です。

# 計算機に必要な機能
そもそもどんな機能が必要なのかという点から考察してみます。
* 四則演算ができること（１）
* 計算できない数を入力できないようにする（２）
* 間違えて入力した最後の文字だけ消せる（３）
* ACで全部クリアできる。（４）
ざっとこんなもんだと思います。これらから学べることは以下の通りです。
# 得られる学び
## 「１，四則演算ができること」から
* ＊（アスタリスク）が掛け算、/（スラッシュ）が割り算を表すなどといった基礎中の基礎から四則演算そのものを学ぶことができる。
* eval（）などのような関数の使い方を学べる。
* evalにはStringｓしか代入できないので文字列と数列の違いを理解できる。

## 「２，計算できない数を代入できないようにする」から
（計算できない数とは「0..1」や「3＋.5」のようなもののことを指す。つまり数学的に未定義の数を指す）
* IF文による場合分け（今この記号は入力できるのか？のような条件）
* 完結な場合分けをしないとネストがどんどん深くなること
* Switch文を使うことでネストの深さの軽減できること
* 「！==」や「>=」などの比較演算子の使い方
* 正規表現によって最後のの文字を取得する
* includeメゾットなどメゾットという概念

## 「３，間違えて入力した最後の文字だけを消せる」から
* sliceメゾットの使い方
* 最後の文字を消すとIF文による場合分けに未定義が生じることがある
      ＝＞プログラムに実際にバグがおこるところを体験できる。

# おわりに
かなり基礎の内容を網羅できるのではないでしょうか？これらは関数をつかうことが前提となるのでそこも学べる。懐かしいなあと初心に帰って書きました。