OmniAICreator/Qiita-1.07M huggingface dataset:
PHP ぼやき日記 2023-12-17

- [次回](https://qiita.com/sj-i/items/4218804e1cd7f41fc4b0)
- [前回](https://qiita.com/sj-i/items/76ade0490d6c991871f5)

不定期に誰に向けるでもなく PHP に関する雑な殴り書きをしている。日付が変わってから変わる前の日付の奴だと言い張って投稿するくらいの雑さ加減。

# Psalm 5.18.0 が降ってきていた
- https://github.com/vimeo/psalm/releases/tag/5.18.0
- PHP 8.3 の `#[Override]` 対応が入ってる

# オレオレメモリプロファイラで memory_limit 越え時の真のコールスタックを得る実装を書いた
- https://github.com/reliforp/reli-prof/pull/384
- 今年に俺が書いたコードの中で一番頭悪いコードオブザイヤーを受賞できそうなやつ
- [記事でちょっと言及していた](https://qiita.com/sj-i/items/2865f212d1ab760a47fc#memory_limit-%E8%B6%8A%E3%81%88%E6%99%82%E3%81%AE%E7%9C%9F%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%AB%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF%E6%A4%9C%E7%9F%A5%E5%AF%BE%E5%BF%9C%E9%80%94%E4%B8%AD) VM スタックをスキャンするやつ、驚くべきことに案外ちゃんと動く

# Reddit で「PHP の `true` と `false` と `null` は定義済み定数ですが何か？」という謎のレスバをしていた
- https://www.reddit.com/r/PHP/comments/18jou7h/comment/kdmiq5a/
- PHP の `true` と `false` と `null` は case-insensitive な定義済定数であり、キーワードではない
- [PHP Parser](https://github.com/nikic/PHP-Parser) や [php-ast](https://github.com/nikic/php-ast) などのパーサでもソースコード中でのこれらの参照は AST 的には定数フェッチであり、リテラルの参照ではない
- VM 命令列へコンパイルされる時点では zval の直接参照まで解決されてるので、通常は意識することはないと思う
    - なおこれは通常のグローバルネームスペースへのフォールバックとは異なる仕組み
        - https://3v4l.org/3PBBa
    - コンパイル時に行われる定数式評価の段階でこれらの 3 定数については[特別扱い](https://github.com/php/php-src/blob/5d853788932caad81c3ba070904af1db3c061dcf/Zend/zend_constants.c#L210)がされた上、ある種の interning により同じ `zend_constant` / `zval` が参照されている
    - よって構文レベルでは実際に定数扱いで VM の定数表にも登録されているものの、実際にみんなのコードに書いてある `true` とか `false` とか `null` とかが完全に他の定数と同じように処理系に扱われているかというと、そこはそうでもない
- なお reddit でも書いてるけど、これらの型の値の `zval` 的な扱いは各操作中で型情報部分のみが見られていて、値部分は全然使われておらず、メモリ上ではキャスト前の値部分がそのまま入ってるみたいなことがあったりする
    - これはちょうど[騙されていた（？）のを直した](https://github.com/reliforp/reli-prof/commit/0ce4890edc8e8744cd7db2ebb94a73a74eacc2fd)ところだったりした
大好きな芸人のじゃんけんネタをアプリ化してみた！

技育キャンプ マンスリーハッカソンで作成。(これが初めての制作物でした。)

### タイトル
シン・ジャンケン

### 発表スライド(デモ、スクリーンショット)
https://docs.google.com/presentation/d/1SkupaDu7pw2J9n-TQlWuEv47s3PhGZ3qclgh9vXdDRk/edit#slide=id.p

### 開発期間
3週間

### 開発人数
個人開発

### 役割
企画　開発　デザイン

### 使用した技術・ツール
Swift,SwiftUI
### プロジェクトの目的・動機
初めて開発するにあたり、ジャンケンアプリを作ろうと思っていたが、ちょうどM-1の予選動画でジャンケンのネタをやっている芸人がいたのでアプリ化したいなと考えました。

### 工夫
・ジャンケンの出す手をランダム関数を使って制御したこと
・デザインを整えたこと



### コードサンプルまたはGitHubリンク
https://github.com/haruki-mochida/Myjanken

### 反省点・学び・今後の改善計画

・初めてのハッカソンだったので事前準備もっとしてればよかった！
・自分の出す手を選んだ上で、画面にコンピュータの手を出して実際に勝ち負け判定をさせたい。
・変数(美魔女カウンター)を画面に表示させたい
・音声をつけたい
・他の芸人のリズムネタなんかもアプリで作ってみたい
LEGO Education SPIKE をPythonでプログラミングする ～その１～

## はじめに
　LEGO Education SPIKE（以下、SPIKE）をPythonでプログラミングするときによく使う関数をまとめました。SPIKEのバージョンはApp3です。

### LEGO Education SPIKEとは？
　全く知らない人のために説明します。こんな感じのロボットを作ったりして、プログラミングや機械設計について学ぶことができます。私が通っている高校の部活では、これで宇宙エレベーターロボット競技会に出場したりしています。
![IMG_2353.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2942430/afa0a0f9-81a1-315e-c785-b0ecca8b0560.jpeg)

## アプリモジュール
### 音　ー＞　`play`関数
　以下のように使います。
```python
from app import sound

sound.play("Cat Meow 1")
```
　引数にワードブロックの時に使える音声の名前を渡してあげます。

## 色モジュール
　以下のように使います。
```python
import color
```
　カラーセンサーモジュールを利用するときに使います。

## カラーセンサーモジュール
### `color`関数
　以下のように使います。
```python
import color_sensor
from hub import port
import color

if color_sensor.color(port.A) is color.RED:
    print("赤色が検出されました。")
```
　引数にカラーセンサーが接続されいるポートを渡してあげます。戻り値は、色モジュールで定義されている色定数です。

## 距離センサーモジュール
### `distance`関数
　以下のように使います。
```python
import distance_sensor
from hub import port

distance_sensor.distance(port.A)
```
　引数に距離センサーが接続されいるポートを渡してあげます。戻り値は、センサーが検知した距離をミリメートルで返します。

## フォースセンサーモジュール
### `pressed`関数
　以下のように使います。
```python
import force_sensor
from hub import port

print(force_sensor.pressed(port.A))
```
　引数にフォースセンサーが接続されいるポートを渡してあげます。戻り値は、ブール値です。

## ハブモジュール
### ポート
　以下のように使います。
```python
from hub import port
import distance_sensor

distance_sensor.distance(port.A)
```
　モーターやセンサーを利用するときのポート指定に使います

### スピーカー　ー＞　`beep`関数
　以下のように使います。
```python
from hub import sound

sound.beep(frequency: 440, duration: 5000, volume: 100)
```
　ハブからビープ音を鳴らすときに使います。`frequency`は音の周波数、`duration`は音を鳴らす時間（ミリ秒）、`volume`は音量です。

## おわりに
　後編は、こちら。

https://qiita.com/cyber-yuito723/items/764cfbbab97da9b6b8c9

　SPIKE関連の記事を他にも書いています。

https://qiita.com/cyber-yuito723/items/bdc1f54a35aa59ebd390

https://qiita.com/cyber-yuito723/items/2346b5d068aa5d7ea6e5
Maker Faire Tokyo2023出展準備メモ

## 背景
- [Maker Faire Tokyo2023](https://makezine.jp/event/mft2023/)に[challenge_club](https://challenge-club.connpass.com)枠で出展しました、本記事はその出展準備メモです
- 主に、[Maker Faire Kyoto2023出展準備メモ](https://qiita.com/seigot/items/d7899a7bfd0ccb2c48bb)からの差分について記載します
- 出展内容によって準備のやり方は異なりそうで、適宜読み替えて頂けますと幸いです

## `Maker Faire Tokyo2023`について

> Maker Faire Tokyo2023
> https://makezine.jp/event/mft2023/
> Maker Faire（メイカーフェア）は、誰でも使えるようになった新しいテクノロジー（カードサイズで3,000円で買えるコンピューター、センサー、3Dプリンター、ロボット、AI、VRなど）をユニークな発想で使いこなし、皆があっと驚くようなものや、これまでになかった便利なものを作り出す「メイカー」が集い、展示とデモンストレーションを行うイベントです。
>
> イベント名称
> Maker Faire Tokyo 2023
> 2023年10月14日（土） 12:00～18:00（予定）
> 2023年10月15日（日） 10:00～17:00（予定）

## 出展申し込み

開催日の4ヶ月前である2023/6までに申し込みが必要

> 出展の流れ
> https://makezine.jp/event/mft2023/callformakers/
> 1. 出展申し込み
>［締切］2023年6月8日（木）13:00
> 2. 選考結果の発表
> 2023年7月6日（木）まで

## 出展準備にてさしあたり困りやすいこと

- 1.申し込み時の概要説明
- 2.出展する上で必要な備品の準備
- 3.出展物の宅急便費用、遠方から大荷物を運ぶと費用がかさむ（東京から遠いほどかさむ）
- 4.当日デモ等の不測の事態対策、見せ方の工夫

## 1.申し込み時の概要説明

- できるだけ展示内容を分かりやすく記載＋過去出展先があればURLやYoutubeリンク等があれば便利です（実際にできているかは置いておいて）
- 出展内容がMakerFaire参加者にどのような価値を感じて頂けるかを述べると説得力が増す気がする
- 圧倒的技術力があれば「こんなモノ作りました！」と一言書いて写真を添えれば伝わる場合も多いような気がする

今回の出展申し込み時は以下活動でコツコツ取組んでいた内容を抜粋して記載しました

https://challenge-club.connpass.com

## 2.出展する上で必要な備品の準備

[MakerFaireKyoto2023へ出展した際の備品](https://qiita.com/seigot/items/d7899a7bfd0ccb2c48bb)を再利用しました。
養生テープや電源タップは数日前にamazonで注文して十分に間に合いそうですが、
テーブルクロスや名刺は微妙に入手困難になる時期があるかもしれないので２週間以上前から準備するとよい。ギリギリは精神衛生上良くない。

https://qiita.com/seigot/items/d7899a7bfd0ccb2c48bb

## 3.出展物の宅急便費用、遠方から大荷物を運ぶと費用がかさむ（東京から遠いほどかさむ）

例えば関西から関東までサイズ180（3辺の合計が180cmまで）の段ボール２〜３個送ろうとすると数千円〜くらい掛かることが多そうです。（今回は片道約8000円くらい〜掛かったはず）
クロネコヤマトの宅急便で以下のような参考サイトがあります。
今回なるべくコストを低くするために、デモ内容をDesktopPCの代わりにJetsonNanoで動かないか検討、などしました。段ボール１個減ることで片道数1000円のコスト削減になるので地味に効きます。

> https://www.watch.impress.co.jp/docs/news/1339409.html
> 180サイズは、3辺の合計が180cmまでで料金は2,400円～

> https://www.kuronekoyamato.co.jp/ytc/search/estimate/kansai.html
> 宅急便運賃一覧表：関西

久しぶりにJetsonNanoを動かすと色々とハマりました。
今後も同じ環境で動かし続けられるかはよくわからない。

https://qiita.com/seigot/items/962e52ef7c71432d44fa

## 4.当日デモ等の不測の事態対策、見せ方の工夫

- 3.によりJetsonNanoを当日デモ表示用マシンとして活用したまでは良かったが、放熱対策が甘かったのか展示２日目の午後一くらいでフリーズした。予備機（Jetson2台目）を稼働＋Jetsonを冷まして再起動することで回避、ファンに加えて何か熱対策を追加で実施すればより安心して使えるかもしれない
- ディスプレイは分解して持っていく事になるが、毎回ネジ紛失が不安である。ネジは養生テープで貼り付け等して確実に紛失しないよう注意が必要である。今回一部ネジを紛失しかけたためここに記録を残す。
- 見せ方の工夫はおそらく今後も考えていく必要がある。そもそも展示内容によると思うが、展示活動の持続性については、割と周りに分かりやすく伝えられるかどうかが結構重要なのではと感じている。

## 今後の課題

- 触って楽しめる展示を増やしたい
- 会場で利用可能な通信環境の準備、バーチャルな体験環境の整備
- 各種コンテスト参加PRを兼ねたデモ展示（仮）

他、多数
出展者同士の交流会などにも混ざってみたい

# 参考

https://makezine.jp/event/mft2023/

https://makezine.jp/event/mfk2023/

https://qiita.com/seigot/items/d7899a7bfd0ccb2c48bb

https://challenge-club.connpass.com

https://makezine.jp/event/makers-mft2023/m0169/
git add . や　git add -A や　git add -a


## git add .

管理されている全ファイル中、カレントディレクトリ以下の変更されたファイルを全て

## git add -A

管理されている全ファイルの中で、全ての変更されたファイルを全て

## git add -a

-aオプションは存在しない
Pythonで乃木坂のブログからワードクラウドを作成するアプリを作りました!

## 技育キャンプ マンスリーハッカソン vol.4
### タイトル
Nogi Blog Search
### 発表スライド(デモ、スクリーンショット)
https://www.canva.com/design/DAFndpr_SX8/WZS900p9FACWxiqBPlO80Q/view?utm_content=DAFndpr_SX8&utm_campaign=designshare&utm_medium=link&utm_source=publishsharelink

### 開発期間
4週間

### 開発人数
個人開発

### 役割
企画　開発　デザイン

### 使用した技術・ツール
Python,HTML,CSS,JavaScript

### プロジェクトの目的・動機
アイドルは様々なコンテンツに溢れていて、全て目を通す暇がない。特にブログは見たいけど時間がなく、後回しになっている事が多い。

好きなアイドルのブログから特徴語を抽出してワードクラウドを作成すれば短時間で、興味のある単語だけでもキャッチできると思った。

### 工夫
・公式サイトからメンバーのリンクと名前をスクレイピングし取得、それを利用して選択オプションを提供しています。

・解析の進行状況を監視する機能を実装しました。

・テキストから名詞のみを抽出し、キーワードの重要度を評価する際のノイズを減少させました


### コードサンプルまたはGitHubリンク
https://github.com/haruki-mochida/nogi_blog_analysis

### 反省点・学び・今後の改善計画

・デプロイまで持っていきたい
・他の坂道グループからも選択できるようにしたい
・計画・設計・開発・デプロイの流れを計画性を持って進められなかった。
・初めてWeb制作をしてみて面白さを感じることができた
・フロントエンドも触ってみたい
AtCoder入茶しました

この記事は、[木更津高専 Advent Calender 2023](https://qiita.com/advent-calendar/2023/nit_kisarazu "") 19日目の記事です。

前→ [Rust100%のWebサイトを作っている話](https://zenn.dev/nxvzbgbfben/articles/59b1893b414e5c "") by @NXVZBGBFBEN
次→ [AtCoder入青記事](https://qiita.com/ku_senjan/items/0c07e1aa8af354cbc37f "") by @ku_senjan 

# はじめに
タイトルにもある通り、ABC332で入茶しました！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589252/b74fb419-e3b7-8ffb-487d-7a230526a710.png)
とても嬉しいです
# 入茶した僕の現状
入茶を目指している人の参考になったら幸いです。

## これまでやってきたこと
### 5〜6月頃
とある人からAtCoderを誘われて始める。
過去問とかちょいちょいやってた。
### 7月頃
テスト期間(下旬)になるまで毎週ABCに出てました。
また、所属している同好会の中で開かれていたバチャコンにも何回か出てました。
### 8~9月頃(夏休み期間)
予定が入ってしまい、参加できなかった回も多かったですが、それでもできる限りABCに参加してました。
7月頃に比べてパフォーマンスの水準が高くなってきていて、成長を感じてました。
### 10~11月頃
学校生活が忙しかったり定期テストが入ってしまったため参加回数がだいぶ減ってしまいました。
このころ、今年のうちに入茶することを決心しました。
### 12月頃
年内に入茶することを目標に掲げてたので、モチベを保ててました。

## 現状どれぐらいまで解けるか
体感8割ぐらいの確率で3完でき、時々C問題が解けない感じです。
パフォーマンスは、200~700の間を推移する感じです。

# これからの目標
- 来年内に入緑したい
- ABCで4完できるようになりたい

# 終わりに
まとまりがない記事となってしまいましたが以上で入茶記事を終わります。
入茶を目指している人の参考に少しでもなれば幸いです。
それでは、メリクリ。良い年末を。
複数のCRM開発・運用でのUI/UX上の学び

![アイキャッチ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211946/a1270dcc-2cdc-42cd-1c14-cdefe50d4e75.jpeg)

この記事は [Ateam LifeDesign Advent Calendar 2023](https://qiita.com/advent-calendar/2023/ateam-life-design) の 19日目の記事です。

# 概要

ここ数年コールセンターのCRM（顧客管理システム）開発・運用に携わっております。

それは時に自社開発であったり、時にノーコードツールでの構築だったりしますが、
CRMを使いやすいUIに改善するとオペレーター1人ひとりの入力効率が高まり、
チリツモで大きな工数削減になり事業KPIに好影響を与えられます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211946/f9551e29-0bbb-c287-0a1a-e729aa710f7e.png" width="400px">

それは、事業に依らない普遍性がある程度あり、
事業を跨いだ活用、もしくはCRMではなくWebの入力フォームなどの別ジャンル等にも
横展開できそうな応用性があるためここに基本的な内容を示したいと思います。

# １つの入力で複数項目を自動入力

入力項目には、他の項目に連動して内容が決まってくる項目があります。

例えば、「対応フラグ」をプルダウンから入力するとします。
その場合「対応日時」や「対応者」、「現在のステータス」は自ずと定まるため、
オペレーターが手打ちする必要性はありません。

そのため、「対応フラグ」だけ決定すると、
あとは自動入力するようにし、効率的に入力が進みます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211946/eb7765be-1723-c2ba-6597-ed90ed739e96.png" width="400px">

また、CRMだけに閉じることなく、特定条件をクリアすると
「Slackで通知」といったようなアクションまでを設定すると
アプリ切替えや手動入力がなくなることで、入力ミスも抑制できます。

# 色・フォント・サイズ・情報

ビジュアル要素はCRMにとって、定量化し難い反面、
可読性ならびに処理効率にダイレクトに影響します。

そのため、適切に使用するための注意点を書き連ねます。

### 色の統一性

エラーは赤色、成功は緑色など、CRM全体を通じて
色の意味合いを踏まえた統一配色を心がけます。
また、基本的な事柄ですがデザイン時には、
CSSで定義している色しか使わないの認識をとります。

### 伝家の宝刀 "高彩度"

そして、内容に注目させたい時…高彩度を使って目立たせる時が来ました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211946/49b7a62b-71cf-789c-a0d4-49002c1b64cd.png" width="300px">

ただし、使いすぎて何を目立たせたいのかわからなくなってないか？、
高彩度の背景に色があり、コントラストが中途半端になってないか？
など俯瞰しながらページ内で決められた数以下になるように使っていく必要があります。

### 適切な情報量と順

CRMを利用するシチェーションの多くはお客様と電話していると時など、
マルチタスクが前提の状況にあり、オペレーターには心理的余裕はあまりありません。

そのため、膨大な顧客情報の内<font color="red">『対応オペレーターに今何が必要か？』</font>を意識し、
情報を必要最小限に減らし、上から```1 確認すべき内容``` ➡ ```2 入力欄``` といった流れを意識し、オペレーターの認知負荷を減らすことを徹底します。

なお、いくつかの改善をやっていてわかったことですが、
オペレーターにはCRMの最短ルートを発見する嗅覚があり、
そのルートから外れた所に『使ってもいいけど使わなくてもいい便利な機能』を
配置してもまず使ってもらえません。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211946/1ce71af6-de24-7309-7381-741f9bfd506f.png" width="300px">

ルート上で必ず通る（使うことになる）配置を心がけましょう。

# ダッシュボードとランキング要素

トップページにKPIを記したダッシュボードを置くことで、
オペレーターの成績や事業状況を一瞬で把握できます。

また、"本日のランキング"などを職種や部署ごとに設定しておくことで、
オペレーター間で競争意欲を持たせられるのでチャレンジングな部署になります。

その他、顧客の検索機能などはどのCRMにも存在すると思いますが、
複雑な条件を保存しておき、ワンクリックで呼び出せる、
フィルタ機能があるとログインから顧客セグメントへの発信までの時間が短くなります。


# 最後に

CRMの面白い所は、基本的に[toC]サービスと違い、自社内にオペレーターという
ユーザーがいるため、いくらでもFBを取り入れられることです。

ただし、ダイレクトな反応をもらえてやりがいを感じられる反面、
要望通り対応しても何故かあまり効果的でないこともあります。

そのため、要望をもらった時には、
- 真に解決したい課題は何か
- その課題をクリアするとどうKPIに影響あるか
- 既存の機能では解決することは出来ないのか
- 数ある実装方法の内、工数と快適性のバランスの良いものはどれか

などを深く考えていく必要があると常々思っております。

[toC]のWebサービスに比べると確かに地味に感じる部分も多いですが、
色々なシーンで必要不可欠な役割を果たすので私自身、
今後も他者がデザインしたCRMから学んでいきたいと思います。

閲覧いただきありがとうございました。
初めてOSSコントリビュートするためにやったこと

:::note info
これは [ZOZO Advent Calendar 2023](https://qiita.com/advent-calendar/2023/zozo) カレンダー、シリーズ 5 の 17 日目の記事です。
:::
# はじめに
OSSに貢献してみたいけど、何をすればいいのか分からない・ハードルが高そうと思っている人は多いのではないでしょうか。まさに自分がそうでした。
そこでこの記事では、技術力を高めるという目的というよりは、まずはとにかく簡単なissueを探してOSS活動の雰囲気を掴みたい・成功体験を積んでみたいという人を対象に、最初の一歩として踏み出しやすいissueの探し方を自分の経験をもとに共有できればなと思います。

# 貢献しやすいissueを見つける
普段使っているツールやライブラリの改善点を見つけて自分でissueを起票したりcommitするのはなかなかハードルが高いですよね。
そこで今回は、[GitHub Help Wanted](http://github-help-wanted.com/)を使って世界中のOSSからissueを探してみます。

では具体的にどういったことを意識しながらissueを探していたのか見ていきます。
#### `good first issue`ラベルで絞り込んで探す
GitHub Help Wantedはラベルを使用してissueを絞ることができ、中でも`good first issue`や`easy`、`documentation`は我々ひよっこコントリビューターにうってつけのラベルです。
個人的には`good first issue`は比較的簡単な内容が多かったと思いますので、まずはこのラベルで絞り込むのをおすすめします（もちろん併用可）。

#### 新しいissueから探す
古いissueは情報が不足していて手を付けるハードルが高いか、他のつよつよエンジニアでもなかなか対応の糸口が見えなかったという可能性があります。とにかくサクッと貢献したい我々ひよっこコントリビューターは、そういった難易度高めのissueを選ぶのは最初は避けた方が良さそうです。

#### 議論が始まっていないissueを探す
議論が活発なissueは大抵込み入った内容になっていて、こちらも難易度高めのものが多いです。もちろん途中から英語で建設的な議論に参加してともに解決していければ理想ですが、我々ひよっこコントリビューターには少々荷が重そうです。

#### コードに深く踏み込まなくても良さそうなものを探す
GitHub Actionsやドキュメントの修正（特にtypo）などは、issueの背景や関連するコードを読み込まなくていいので比較的取り掛かりやすいです。特定の言語で絞り込んでもいいですが、簡単そうだと思ったら意外と重めの内容だったということは少なくなかったので、「簡単なissueを探す」という点では効率は良くないかもしれません。

#### いけそうなissueはすぐにPRを出す
簡単なissueはすぐに誰かが対応しちゃいます。これはいける！と思ったら、その日のうちにPRまで出しちゃいましょう。
かくいう自分も「お、これいけそうかも」と思ってのんびり実装を進めていたissueが2、3日でcloseされていたことが何度かあり、その度に精神的なダメージをもらっていました。

以上を加味して自分が選んだissueはこちら。
https://github.com/tricorder-observability/Starship/issues/91
まだ改善の余地があるのでcloseにはなっていないですね。

issueを決めたらforkして実装した後、PRを出します。
PRのフォーマットはOSSごとに慣習がある場合もあるので、他のPRも参考にしながら作成しましょう。

自分が投げたPRはこちら。
https://github.com/hyperioxx/frontman/pull/60
簡単なGitHub Actionsのワークフローを追加しただけです。概要もissueのリンク貼ってるだけなので、これはあまり参考にしない方がいいかもしれないです。。
ちなみにPR投げて2,3分でマージされました。~~本当に内容確認したんですかね...~~


# おわりに
いかがでしたでしょうか。
まずはこういった簡単なissueから始めると、OSSに対する抵抗感や苦手意識は少なくなっていくのではないでしょうか。
そしてゆくゆくはお世話になっているライブラリやコミュニティに貢献できるようになっていきたいですね。

ではまた。
【ゼロから学ぶNuxt3×Typescript】⑤リアクティブ変数とクラスバインディング

Nuxt３×TypeScript 学習
下記の参考サイトを見ながら、Nuxt３とTypescriptを学ぶ第5回。

▼　神回|vue3.js nuxt3 typescriptどうやる？【ゼロから解説】

https://field.asia/%E7%A5%9E%E5%9B%9Evue3-js-nuxt3-typescript%E3%81%A9%E3%81%86%E3%82%84%E3%82%8B%EF%BC%9F%E3%80%90%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E8%A7%A3%E8%AA%AC%E3%80%91/


前回はこちら👇

https://qiita.com/sakuc47/items/11244655b961637005b2

第1回はこちら👇

https://qiita.com/sakuc47/items/2770d40720070b682ee9

前回はreactiveとrefを使って状態管理ができるようになりました。
今回は配列を書いていくところから！


### 1.求人情報を入れる`<ul>`を書く
```vue
<template>
  <input type="text" name="name" v-model="person.name">
  <button type="button" @click="addSan">登録</button>

  <p>あなたの名前は<span class="u-tx-bold">{{ person.name }}</span></p>
  
  <button type="button" @click="showProfile">プロフィールを表示</button>

  <p v-if="isShowProfile">id: {{ person.id }}</p>
  <p v-if="isShowProfile">name: {{ person.name }}</p>
  <p v-if="isShowProfile">age: {{ person.age }}</p>

  <ul>
    <li v-for="job in jobs" :key="job.id">
      <p :class="{ active:job.id == 2, active2:job.id == 3 }">
        求人ID: {{ job.id }}
      </p>
      <p>求人タイトル: {{ job.name }}</p>
      <p>求人内容: {{ job.content }}</p>
    </li>
  </ul>
</template>
```
- v-forディレクティブを使用して、jobs配列内の求人情報を繰り返し表示
- :key属性
    - Vue.jsに対して各アイテムの一意な識別子を提供します。
- :class属性 クラスバインディング
```vue
<p :class="{active:job.id == 2,active2:job.id==3}">求人ID: {{ job.id }}</p>
```
これは、右辺の条件を満たすならactiveを返すというvueの記法。

- `job.id` が 2 であれば、`active`クラスが追加される
- `job.id` が 3 であれば、`actived2`クラスが追加される

### 2.リアクティブな変数jobsを作成し、その初期値として求人情報の配列を代入
```vue
<script language="ts">

import { ref , reactive } from 'vue'

export default {
  setup() {
    const name = ref('')
    const nameWithSan = ref('')

    const isShowProfile = ref(false)

    // 空の配列を初期値とするリアクティブ変数 jobs を作成
    const jobs = ref([])
    // jobsのvalueプロパティに、求人情報のオブジェクトを要素とする配列を代入
    jobs.value = [
      { id: 1,
        title: '求人1',
        content: '求人1の仕事内容です。'
      },
      { id: 2,
        title: '求人2',
        content: '求人2の仕事内容です。'
      },
      { id: 3,
        title: '求人3',
        content: '求人3の仕事内容です。'
      },
      { id: 4,
        title: '求人4',
        content: '求人4の仕事内容です。'
      },
    ];

    // 中略
    return {
      name,
      nameWithSan,
      person,
      isShowProfile,
      // 　jobs 追加
      jobs,
      addSan,
      showProfile,
    }
  }
}
</script>
```
- 空の配列を初期値とするリアクティブ変数 jobs を作成
- jobsのvalueプロパティに、求人情報のオブジェクトを要素とする配列を初期値として代入
    - 求人情報が変更されると、関連するUIも自動的に変更される 

### 今回はここまで！

### 参考サイト

https://ja.vuejs.org/guide/essentials/reactivity-fundamentals

https://implist.dev/entries/vue3-reactive-and-directive

https://qiita.com/FumioNonaka/items/08ab308cf1e931d4b2eb
【AWS】APIGatewayでLambda関数を呼び出す設定手順【APIGateway】

## はじめに
簡単な処理を行うWebアプリケーションでは処理をLambda関数に実装してそれをWebアプリケーションから呼び出すいわゆるサーバレスアプリケーションを構築することがあります。
今回の記事ではサーバアレスアプリケーションの基本的な構成であるAmazonAPIGatewayを利用したLambda関数呼び出しの実装例を投稿しました。

[この構成の利用例(署名付きURLを発行する)]

https://qiita.com/Nana_777/items/5730fa1f613b8747a6ce


## アーキテクチャ図

![アーキ図.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/4531270f-c4f0-d178-4006-79adf84de1e6.png)


## 構築手順
### 1．Lambda関数の実装
#### ①Lambda関数を作成します
※特にAPIGateway用の設定等はなく、必要に応じた処理を実装してください
※ここでは呼び出された後でメッセージを返すだけの処理を書いています
![Lambda作成1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/375cf5fb-059c-74f1-1170-2c0d3b005992.png)
### 2．API Gatewayの設定
#### ①APIタイプを選択
・ここではWebアプリケーションから呼び出される「HTTP API」を選択
![APIGateway1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/a2233b4f-0939-7fc2-b5a2-8e64425d59ef.png)
#### ②「統合を作成して設定」
・1の手順で作成したLambdaを指定
![APIGateway2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/784a920d-93e7-816d-36d8-79bf8c7b94a9.png)
#### ③「ルートを設定」
・メソッドはGetやPostを選択できますが、ここではANYを選択
![APIGateway3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/160e944b-cb6f-4c64-e342-f9f36c2ef772.png)
#### ④「ステージを設定」
・変数やタグの設定を行う単位になるステージを設定する
![APIGateway4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/1a096fb8-68da-e6b7-dc61-0fe183f376c5.png)
#### ⑤設定を確認して「作成」
![APIGateway5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/4b41e12e-bbb9-87e0-dd4f-6265f35ee86e.png)

#### ⑥Lambdaのコンソール画面でAPIGatewayがトリガーになっていることを確認
![Lambda作成2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/2b568af5-d15d-7f44-64c7-65e87ce23120.png)

### 3．動作確認
①WebブラウザでAPIのURLを実行してみる
・Lambdaのコンソール画面かAPIGatewayのコンソール画面で作成したAPIのURLが確認できるため、それをWebブラウザのURL欄に入力して動作確認する
![動作確認1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/2b6c17c9-4988-e03c-3cb1-bd73e9dce8f2.png)

![動作確認2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/4e94df55-f25a-ad4f-6051-14d277df0460.png)
↑Lambdaから返されるメッセージが表示されたことを確認


## 追加で設定
・今後の記事で開設予定ですが、APIGatewayの運用にはコスト面やセキュリティの観点からいくつか注意するポイントがあります。ここではコスト面の設定として「使用量プラン」の設定について記載しておきます
### 使用量プラン
APIのリクエスト(その後続処理で呼び出されるサービスを含む)によりAWSのコストが発生している場合、APIリクエストは必要最低限の回数に絞る必要があります。また、APIが不正アクセスにより大量のリクエストが行われた場合もコスト増につながります。
そのためリクエストを制限するための使用量プランというものがあります。
#### 設定手順
①APIGatewayの左メニューから「使用量プラン」を選択
![APIGateway6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/8fa98c89-fdc0-9899-7560-af57b65988f5.png)
②使用量プランンの詳細の設定
・1秒当たりのリクエスト回数、クライアントの同時リクエスト数、1日当たりのリクエスト回数の制限を設定します
![APIGateway8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/7f368ef2-3dac-e80e-d903-f92cfa16709e.png)


## さいごに
APIGatewayとLambdaを使用したサーバレスWebアプリケーションは簡単に実装でき、運用の負担も少ないためこのアーキテクチャを採用するケースは多いですが、利用者や利用回数が多い場合のコストや権限制御も考慮すると意外と気にしないといけないことが多いと思います。
場合によってはEC2などに独自のシステムを構築してあげたほうがコストが運用コストが安いこともあるかも・・・サービスの利便性だけでなく、システムがどのように利用されるかも考慮してアーキテクチャを検討していきたいところです。
メディアサイトにおけるHタグコンポーネントについて考えてみる

Hタグごとにコンポーネントを作成する際に型定義をどうしていいものか悩みました…。

:::note info
思考した内容をまとめましたのでコンポーネントを作成する際の参考にしていただけると幸いです！
:::

## Hタグはasを利用してポリモフィック的に作るべきか？

Hタグはh1からh6までタグがあります。
asを利用することで1つのコンポーネントに複数の役割を与えられます！

```typescript
import { ReactNode } from 'react';

type Props = {
  as: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
  children: string;
};

const Heading = ({ as: Tag, children }: Props) => {
  return (
    <Tag>{children}</Tag>
  )
};

export default Heading;
```

hタグだけだと決めていればリテラル型で定義するのも良いかと考えています！

ただ、Hタグをポリモフィックなコンポーネントとして定義するよりも、別々に分けて定義する方が良いのでは？というのが私の考えです！

:::note info
例に出したコンポーネントは、スタイルのないコンポーネントですが、h1〜h6までのスタイルをどれだけシンプルに書けたとしても見づらい状態になる可能性が高いと考えています。

h3タグのデザインを修正すると他のhタグにも影響がでる可能性を及ぼす可能性が出るので、コンポーネントは分ける方が良いのでは？と考えております。
:::

ポリモフィックコンポーネントについての説明は別の記事で紹介していますのでよければ確認してください！

https://qiita.com/tanimoto-hikari/items/ca21fbac3bc0db79c6d9

## Hタグの型定義はどうするべきか？
例えば下記のようなコンポーネントを実装したとします。

```typescript
import { FC } from 'react';

type Props = {
  children: React.ReactNode;
} & JSX.IntrinsicElements['h1'];

const Heading: FC<Props> = ({ children }) => {
  return <h1>{children}</h1>;
};

export default Heading;
```

`JSX.IntrinsicElements['h1']`で拡張してみました。
本来h1タグに付与できない属性を付与された場合にエラーを出したいです！

:::note warn
このままだと任意の`class`や`style`を付与された場合も設定さえあれば受け取れてしまいます…
:::

統一したかったはずのデザインを自由に変更できるHeadingコンポーネントになるのは避けるためにOmitで一部型を除いた新しい型を作りたいと思います。

```diff_typescript
import { FC } from 'react';

type exclusionOptional = 'className' | 'style';
type Props = {
  children: React.ReactNode;
- } & JSX.IntrinsicElements['h1'];
+ } & Omit<JSX.IntrinsicElements['h1'], exclusionOptional>;

const Heading: FC<Props> = ({ children }) => {
  return <h1>{children}</h1>;
};

export default Heading;
```

TypeScriptが用意してくれているinterfaceを利用して自前で定義しなくても`Omit`などを利用してさまざまな型を作れます。

`Omit`については別の記事で紹介していますのでよろしければご覧ください！

https://qiita.com/tanimoto-hikari/items/9cfd4d390493e9e3f0dd


## 【Hタグコンポーネントを作る時の型定義について考えてみる】まとめ
ついついまとめてしまいたくなるのが心情ですが、時には分けるという選択も良いのでは？と考えています。

:::note info
影響範囲を小さくすることで変更容易性を担保することになるのでコンポーネントが増えることよりも小さく、複雑度が低い状況を作ることの方が長くサイトを運用するという観点では大切な場合もあると考えます！
:::

作ったコンポーネントを利用する時のことを考えるとpropsが多くなればなるほど覚えるが大変です…

使う側の観点と実装者の両方の観点から長く安定的に運用できるコンポーネントを作れるように引き続き精進します！
Streamlitで画面を録画するメニューが出てこないときは

この記事はKDDI Engineer & Designer Advent Calendar 2023の7日目として投稿されたものです。
このアドベントカレンダーは「KDDIのみんなでTechな記事を書こう！お仕事に関係しても関係なくてもOK！」という企画となっています。
ちなみに、本記事は私自身のお仕事とは関係ないものです。

## Streamlitとは

StreamlitはPython向けのWebアプリケーションフレームワークです。  

https://streamlit.io/

Streamlitを使うとフロントエンドの知識ゼロでもデータを可視化するためのWebアプリケーションを簡単に作れます。以下のような機能が特徴。  
- 変数を地の文に書くだけで、GUIに出力される(**マジックコマンド**)
- `st.radio`や`st.text_input`のようなWidget APIを呼び出すだけで、GUIコンポーネントが生成される

## 本記事のサマリ

ハンバーガーメニューに「Record a screencast」が出てこないときは以下を確認しよう

- ```config.toml```で```client.toolbarMode```を設定しているか
- ブラウザでサイトに適切な権限が許可されているか

## 問題

Streamlitでは画面を録画する機能がビルトインされているのですが、ひさしぶりに使おうとしたらそもそもハンバーガーメニューにそのメニューアイテムが出てこないので困りました。  
参考：[Streamlitで画面を録画する](https://qiita.com/ak-sakatoku/items/0ae72217f46c46dd76a4)

https://qiita.com/ak-sakatoku/items/0ae72217f46c46dd76a4

## 設定ファイルの確認

1.20.0あたりから1.22.0にかけてハンバーガーメニューのメニューアイテムが整理されました。  
[Changelog](https://docs.streamlit.io/library/changelog#version-1220)によると、

> Customize the visibility of items in the toolbar, options menu, and the settings dialog using the client.toolbarMode config option (#6174).

だそうです。

https://docs.streamlit.io/library/changelog#version-1220

```.streamlit/config.toml```にdeveloperオプションを設定しましょう。  
```.streamlit/config.toml```がそもそも存在しない場合は新規作成しましょう。  

```toml:config.toml
[client]
toolbarMode = "developer"
```

## サイトの権限の確認

以下の画像のような状態だとブラウザが画面の録画を許可してくれていないので、Streamlitがハンバーガーメニューからメニューアイテムを消してしまうようです。  

![streamlit-connection](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/c062e20a-b3f9-e1a7-08b0-4650943c29c9.png)

ブラウザによっては、HTTPで通信しているサイトはlocalhostを除いて権限を設定できないようなので注意しましょう。  

## おわりに

Streamlitはアップデートの頻度がそこそこ高いので、たまにこういうことがあります。  
Changelogsをチェックするようにしましょう！  

## 本記事について

本記事は[アウトプットガチ勢が作った高速記事作成フレームワーク](https://qiita.com/Sicut_study/items/9b20ac5ded003cb6d55a)を参考にしています。  
高速アウトプットを身に着けたい！
「ゲームで世界を変える！」 社会的影響を生むゲームの事例

ゲームは単なる娯楽以上のものです。最近では、教育、健康、社会正義など、さまざまな分野でポジティブな変化を生むための強力なツールとして注目されています。この記事では、社会的なインパクトを生み出している画期的なゲームの例を紹介します。

# ゲームと社会の関わり
ゲームはもはや単なるエンターテイメントではありません。現代のゲームは、プレイヤーに深い思考を促し、社会問題に対する理解を深めるためのツールとして進化しています。ここでは、ゲームがどのようにして社会問題に光を当て、人々の考え方や行動に影響を与えるかについて掘り下げます。

## ゲームが社会問題を照らす方法
ゲームは、現実世界の複雑な問題をシミュレーションすることにより、プレイヤーに新たな視点を提供します。例えば、「Papers, Please」は、架空の国境警備員としての日常を通じて、移民と安全保障の難しさを描き出しています。このようなゲームは、ニュースや報道では伝わりにくい、人々の生の声や感情を伝えることができます。

https://ja.wikipedia.org/wiki/Papers,_Please

https://store.steampowered.com/app/239030/Papers_Please/

また、ゲームは複雑なデータや統計を視覚化し、プレイヤーが直感的に理解できる形で提示することができます。この手法は、特に環境問題や健康問題など、データが重要な役割を果たすテーマにおいて効果的です。

## ゲームが人々の考え方や行動に与える影響
ゲームは、単に情報を提供するだけでなく、プレイヤーがその情報をどのように処理し、反応するかにも影響を与えます。ゲーム内での決断や選択は、現実世界での意思決定にも影響を及ぼす可能性があります。たとえば、気候変動に関する意識を高めるゲームは、プレイヤーが日常生活でより環境に優しい選択をするきっかけになることがあります。

さらに、ゲームは共感を生み出す力も持っています。他者の立場に立って物事を考えることで、異なる文化や背景を持つ人々への理解を深めることができます。この共感は、社会的な課題への関心を高め、実際の行動変化を促す力になります。

## 結論
ゲームは、遊びを通じて社会問題に光を当て、プレイヤーの考え方や行動に深い影響を与えることができる強力なメディアです。エンターテイメントの枠を超えたゲームの可能性は、今後もさらに探求されていくでしょう。社会的な意識を高め、行動を促すゲームは、私たちの世界をより良い方向に導くための一助となり得るのです。
Canvaを少し触ってみた

# Canvasを少し触ってみた
友人からチラシを作成してほしいと頼まれたので、Canvasを使って作ってみた。
そこでの所感をまとめてみる。

## 便利だと思った機能
1. Webブラウザとスマホアプリから使用することができ、出先でも更新可能。
2. 閲覧限定で誰にでも共有できるURLを発行することができ、リアルタイムでデザインを見てもらうことができる。
3. テンプレートがあるので簡単にデザインを作成することができる。
4. 全体的に操作が直観的でわかりやすい。

## 欲しいと思った機能
1. 行内で複数の文字サイズやフォントを使用することができないようで、行内の一部文字だけを異なる文字サイズやフォントに変えれるようにしてほしい。

## 不明な機能
1. AIによるデザインの自動生成も対応しているようだが、有料機能なのか使い方がわからなかった。

## URL
https://www.canva.com/
Djangoでデフォルトで出力されるファイルの役割

Djangoを使ってアプリケーションを作るときに、下記コマンドを実行すると以下のファイルが出力されます。
これらは、どんなアプリケーションを作成するときにも共通で必要になるファイルで、効率よくアプリを作るために必要なファイルたちとなっています。

```zsh
# コマンド
django-admin startproject XXXproject
```

```zsh
# 出力されるファイル
% tree
XXXproject
├── XXXproject
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py
```

それぞれのファイルの役割を簡単にメモしました。
今後、自分の理解が進んだら追記・修正して完成度を高めていく予定です。

## __init__.py
このディレクトリがパッケージであることを示すためのファイル。
このファイルが存在さえしていればパッケージとみなしてくれるため、中身は空でOK。

## asgi.py
非同期処理を行う時の処理を記載するためのファイル。
asgi = Asynchronous Sever Gateway Interfaceの略です。
よりパフォーマンスを追求したいときに使うファイルのため、最初は無視して問題なし。

## setting.py
プロジェクト全体の設定を記載するためのファイル。

## urls.py
ブラウザから受け取ったリクエストをもとに、表示部（ビュー）を切り替えるためのファイル。
他のフレームワークで言うとroutesファイルみたいなもの。

## wsgi.py
WebサーバとWebアプリケーションを接続するための設定が記載されたファイル。
言葉だけでは分かり辛いけど、WebサーバとDjangoの間を取り持つようなイメージ。

## manage.py
Djangoが持つ便利機能を設定するためのファイル。
Qiitaのポエム記事を「雑に」除外するchrome拡張

:::note info
この記事は [クソアプリのカレンダー | Advent Calendar 2023 - Qiita](https://qiita.com/advent-calendar/2023/kuso-app) の2つ目のカレンダーの18日目です。
:::

:::note warn
- 本記事では「ポエム記事」の良し悪しについては特に言及していません。
- また、本記事における **「ポエム記事」の定義は大雑把** で正確性は何もありません。
:::

# デモ

Qiitaのポエム記事を除外するChrome拡張を作りました。

![Kapture 2023-12-18 at 00.06.59.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363036/6d8bf550-7169-185c-1eb4-a2a7bc466514.gif)

# これは何？

Qiitaの記事一覧画面内からポエム記事へのリンクを除外するChrome拡張機能です。
ここでいう「ポエム記事」とは、「本文中にコードブロックを含まない記事」を指します。
（勝手に定義しました）

```shell
# コードブロックとはこれのこと
# QiitaのMarkdownなどでは ``` で表現できるやつ
```

例えば、下記画像は筆者の[ユーザページ](https://qiita.com/c6tower)です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363036/359a9fda-5121-29ac-b47a-0c2608dd8803.png)

この画像内の記事を分類すると、

- ポエム記事（＝本文中にコードブロックを含まない記事）
    - [【Git】ブランチの命名規則を調べてたらIssueドリブン開発という存在を知った](https://qiita.com/c6tower/items/fe2aa4ecb78bef69928f)
    - [笑顔じゃなくなったらGoogle Meetから強制退出させられるchrome拡張機能を作った](https://qiita.com/c6tower/items/3d9c0da133780f65a5b5)
- それ以外の記事
    - [これから始めるなら気にしたいGoの作法](https://qiita.com/c6tower/items/3eec89c68e4cdbc4fa19)
    - [SnowflakeをTerraformで構成管理してみた](https://qiita.com/c6tower/items/898470e5e3fac776e206)

となります。
そのため、拡張機能を実行するとポエム記事へのリンクが下記の通り除外されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363036/6bf47982-fe0b-d2d2-19de-ed86261eef60.png)

ちなみに、「非表示にしてしまうと、どの記事が除外されたかわかりにくい」「本当にページ内の全記事をチェックしたのか不安」といった声が筆者自ら上がってきたので、

- ポエム記事のリンクテキストなどを薄くする
- ポエム記事には `ポエム` タグを付与する
- ポエム記事以外には :thumbsup: を付与する

といった機能を追加しました。
（冒頭のデモ画像では、わかりやすさ重視のためにこちらの機能を利用）

これらを適用した結果が下記画像です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363036/2527a3a1-b6e3-d169-151a-ea591fa69b1c.png)

# Qiitaのサーバに負荷をかけすぎない配慮

ポエム記事の定義として「本文中にコードブロックを含む記事」としていることからわかるように、この拡張機能はページ内に存在するリンクに都度リクエストを送信しています。
GETリクエストのためそこまでサーバへの負荷は大きくないと予想していますが、さすがに秒間で1000とか2000とか投げるのはよろしくないでしょう。
そのため、リクエスト頻度や回数を抑える工夫をいくつか設けました。

まず、デモ段階では **安全を期して秒間1リクエスト** になるようリクエスト間隔を調整しています。
（軽くしか調べて[QiitaAPIのrate limit](https://qiita.com/api/v2/docs) くらいそれっぽい情報見つけられなかったので、とりあえず怒られなさそうな範囲に留めた）

また、Qiitaの記事のみにリクエストを送信できれば良いので、 **リクエスト先を `https://qiita.com/<ユーザID>/items/<記事ID>` に限定** しています。
2023年12月時点で、[ホーム](https://qiita.com/) や [トレンド](https://qiita.com/trend) ページに一度に表示される記事は30件なので、最大でも1回に30リクエスト程度に抑えることができています。
（つまり、ページ内のポエム記事リンクを除外するために毎回最大30秒要している、という意味 :innocent: ）

# さいごに

Chromeウェブストアでの公開は間に合わなかったので、この記事が投稿されてから申請します。
（気力があれば）

そして、改めて注意書きを。
本記事はポエム記事が有害であることを主張するものではありませんし、むしろ筆者はポエム記事から得られる知見もたくさんあるよ派の人間です。

最後まで保身のための文章を色々と散りばめましたが、そもそもこのchrome拡張はコードブロックの有無でしかポエム記事判定を行なっていない性質上、

- ポエム的な内容ではないがコードブロックを含まない、例えばアーキテクチャ解説のような記事も除外されてしまう
- 懇切ご丁寧に `ポエム` タグが付与されている記事であっても、コードブロックが含まれていれば除外されない

といったクソアプリ仕様なので問題ないか。

お疲れ様でした。
【Ruby】切り上げ、切り捨てメソッドまとめ

## はじめに
Ruby silver認定試験の勉強をしていた際に、小数点系のメソッドで気づきがあったのでまとめてみました。

## round
使う機会が割と多いのではないでしょうか。
挙動は以下の通り。
・自身から最も近い整数のうち最大のものを返す
・最も近い整数が2つある場合は0から遠い方を返す(いわゆる四捨五入ですね)
```ruby
> 1.9.round
=> 2
> 1.4.round
=> 1
> 1.5.round
=> 2
> -1.4.round
=> -1
> -1.5.round
=> -2
```
・引数に数値を渡すことで、引数の小数点の位を四捨五入します
```ruby
> 1.15.round
=> 1
> 1.15.round(1)
=> 1.2
```
・```half:```オプションで最も近い整数が2つある場合の丸め方を指定できます
```ruby
> 2.5.round(half: :up)
=> 3
> 2.5.round(half: :even)
=> 2
> 2.5.round(half: :down)
=> 2
```
```:up``` 0から遠い方に丸められます。
```:even``` もっとも近い偶数に丸められます。
```:down``` 0に近い方に丸められます。
※[rubyリファレンス](https://docs.ruby-lang.org/ja/latest/method/Float/i/round.html)より

## floor
続いてfloorメソッド
挙動は以下の通り

・それ自身より小さな整数のうち最大のものを返します(ここポイント)
```ruby
> 1.9.floor
=> 1
> 1.1.floor
=> 1
> -1.9.floor
=> -2
> -1.1.floor
=> -2
```

初歩的ですが、自分は切り捨てされるメソッドとして認識していたため、
負の数の場合も切り捨てされると思っていました。
レシーバーが負の数の場合「それ自身より小さな整数のうち最大のもの」という条件だと
(0から遠い方に)切り上げになるんですね。

## ceil
こちらはfloorメソッドの逆になります。
・それ自身より大きな整数のうち最小のものを返します
```ruby
> 1.9.ceil
=> 2
> 1.1.ceil
=> 2
> -1.1.ceil
=> -1
> -1.9.ceil
=> -1
```

floorメソッドと同じパターンで、レシーバーが正の数の場合と負の数の場合で挙動が異なりますね。

## truncate
・それ自身と0の間にある整数のうち最も近いものを返します(小数点以下を切り捨て)

```ruby
> 1.9.truncate
=> 1
> 1.1.truncate
=> 1
> -1.9.truncate
=> -1
> -1.1.truncate
=> -1
```

引数で切り捨てる桁数を指定でき、-(マイナス)を指定すると整数部分の桁を切り捨てます。
```ruby
> 1.19.truncate(1)
=> 1.1
> 12.34.truncate(1)
=> 12.3
> 12.34.truncate(-1)
=> 10
```

## abs(おまけ)
切り上げ切り捨て系メソッドではありませんが、
同じシーンで使われることもあるかと思いますので記載しておきます。

・自身の絶対値を返します
```ruby
> -1.abs
=> 1
> 1.abs
=> 1
> -123.abs
=> 123
```
dart fixをいつ実行するか考える

この記事では `dart fix` を実行したい場合、いつ実行すると良いかを考えたいと思います。

## dart fixについて

`dart fix` はコードを静的解析し問題があれば修正を行ってくれるコマンドです。

問題の修正は次の２つを対象に行われます。 
- 自動修正が関連付けられている、dart analyzeによって問題として特定されたもの。 
- Dart および Flutter SDK の新しいリリースに更新するときの API の使用法が古いもの。

具体の利用例だとVSCodeなどでDartプラグインを入れていれば修正のプロンプトが表示されることがあると思います。その内側で利用されている仕組みが `dart fix` だったりします。

![スクリーンショット 2023-12-17 11.13.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57963/fbbfefa3-4d1c-032e-2d75-e9385983ae54.png)

他にも対象とするコードが多い場合などは、コマンドで直接実行することもできます。
具体のイメージとしては、Flutter の ver up などがイメージしやすいと思います。

コマンドを実行することでコードを修正できるものだと、`dart format`などもありますがその性質において `スタイルの修正` と`実行を加味した上でのコード修正` では非なるもとなっています。

https://dart.dev/tools/dart-fix

https://dart.dev/tools/dart-format


## 悩ましい点

コマンドで実行するにあたっては、実行時間の観点で悩ましさがあります。

というのも前述のような目的の違いから、`dart fix` の場合は実行の際にコードに静的解析が入るためです。

以下は `dart format` との比較です。
今回は変更が入りませんでしたが、変更がある際にはさらに実行時間がかかります。

```
time dart format lib

> dart format lib  0.22s user 0.08s system 53% cpu 0.555 total
```

```
time fvm dart fix --dry-run lib

> dart fix --dry-run lib  10.24s user 2.17s system 116% cpu 10.643 total
```


## dart fix をいつ実行するか

上記踏まえていつ `dart fix` を実行するか考えてみます。

Flutterのver upなど外部の影響で破壊的な変更が入る時は確実に実行すべきタイミングかなと思います。
※ 影響範囲が広くなるので、`--dry-run` などでリスクヘッジはしておくの推奨。

それに追加の観点として、日々の開発の中でこまめに実行したい気持ちがあります。
というのも意図せず `dart fix` の対象になるようなコードが入ってしまうことはあるなと感じており、それらをできるだけ小さい変更範囲になる前提で実行していきたいからです。

これこそプロンプトで解決できる問題だろうと思いつつ、自分は気づかないこともあったりすので、何らかのタイミングでコマンドも実行したい気持ちがあります。

### [VSCode] preLaunchTaskの段階で実行してみる

以前は git のイベントにhookして実行を試したこともありましたが、10秒も時間を要するとformatterなどと合わせて実行するのはなかなかに辛いなと感じました。

そのため、今はVSCodeの `preLaunchTask` のステップで実行するようにしています。

```launch.json
{
    "version": "xxx",
    "configurations": [
        {
            "name": "Run develop",
            "request": "launch",
            "type": "dart",
            "args": [],
            "preLaunchTask": "dart: fix" // <- ここ
        },
    ]
}
```

```task.json
{
    "version": "xxx",
    "tasks": [
      {
        "type": "shell",
        "command": "dart",
        "args": ["fix", "--apply"],
        "label": "dart: fix",
        "detail": "dart fixの実行",
      }
    ]
  }
```

良い点としては、`preLaunchTask` に設定しておくとhot reloadの際にも実行してくれます。

悪い点としては、buildの時間が伸びてしまいます。build時間のペインの方がでかいという人はプロンプトなどでやっていくのが良いのかなという気持ちです。

### [追記] pre-pushにした
- preLaunchTaskにするとpost-commitなど実行しているformatterなどと実行タイミングが分けられるのでいいなと思っていたのですが、実行頻度が上がってしまいそれはそれで辛かったので、pre-pushなどがいいなと思い直しました。

## まとめ

自分が実行すると良さそうと思っているタイミングは以下です。

- 外部要因で大きく変更が必要になった時。
- ~~変更範囲を抑えるために`preLaunchTask`で実行~~
    - pre-pushで実行だ！

トレードオフになる部分もあるので、チームで開発する場合は、どういう目的で何を重視するか目線合わせしておくと親切かなと思います。
Chrome 121で追加される予定のCSSの新機能を一足先に紹介！


# はじめに

2024/1/17にリリース予定のChrome 121で追加されるCSSの新機能を一足先に紹介します。
Chrome 121で追加された機能については、こちらに記載していますので良かったら確認してみて下さい！

https://qiita.com/MURAMASA2470/items/9f6da9fc4a6b25d08671

# 追加される機能

## テキストハイライト関連のプロパティ値継承の追加

`::selection`や`::highlight`などハイライト関連のプロパティが子要素へ継承されるようになります。

### 使い方

```css
::selection {
  color: red;
}

::highlight {
  background-color: yellow;
}

```

上記の例では、選択テキスト（::selection）の色が赤くなり、ハイライト（::highlight）の背景色が黄色になります。


## スクロールバーの色を指定できるプロパティの追加

スクロールバーの色や太さを指定する為のプロパティが追加されました。
- `scrollbar-color` スクロールバーの色を変更
- `scrollbar-width` スクロールバーの幅を変更

`scrollbar-color`プロパティには、`color`プロパティで指定可能な値などが指定出来ます。

### 使い方

```css
::-webkit-scrollbar {
  /* スクロールバーの色を指定 */
  scrollbar-color: green;

  /* スクロールバーの幅を指定 */
  scrollbar-width: 6px
}
```


## font-paletteアニメーションの追加

`font-palette`でパレットを切り替える際に、アニメーションをつけることが出来ます。

### 使い方

```scss
/* フォントパレットのアニメーション */
@keyframes change-palette {
  0% {
    font-palette: normal;
  }
  100% {
    font-palette: colorful;
  }
}

/* アニメーションを適用する要素 */
div {
  animation: change-palette 2s infinite alternate;
}

```

## スペルエラーおよび文法エラー時のスタイルの追加

ブラウザが誤りとしてハイライトしたテキストにスタイルを適応するCSSが追加されました。
これにより、開発者はデフォルトのスペルエラーおよび文法エラーに対して、より読みやすい色を指定することが出来ます。

### 使い方

```css
/* スペルエラーを赤くする */
::spelling-error {
  color: red;
}

/* 文法エラーに下線をつける */
::grammar-error {
  text-decoration: underline wavy red;
}
```


## SVG向けのCSSマスキングの追加

Chrome 120でのCSSマスクの拡張に続き、SVG向けの新しいマスクが追加されました。

以下の4つのマスクがサポートされています。
- `mask-repeat` マスク画像の繰り返しの設定（マスク画像の敷き詰め方法）
- `mask-position` マスク画像の位置の設定
- `mask-composite` マスクの合成操作（複数のマスク画像の組合せ）
- `mask-mode` mask-image で定義されたマスクを輝度マスクとアルファマスクのどちらで扱うかを設定

また、マスク画像の参照元をローカルではなくURLを指定して表示できるようになります。

### 使い方

```css
/* SVGに適用される複数のマスク */
svg {
  mask: url("https://example.com/sample.svg");
}
```


## ルビに関するCSSの追加

新しいCSS表示プロパティの値`ruby`と`ruby-text`が追加されました。
これらはそれぞれ、`ruby`は`<ruby>`タグ、`ruby-text`は`<rt>`タグの代替プロパティになります。
専用のタグを使わずとも、`<div>`タグなどにこのプロパティを指定することで、ルビを扱えるようになります。

### 使い方

```css
/* Ruby要素の表示 */
.ruby {
  display: ruby;
}

/* Rubyテキストの表示 */
.ruby-text {
  display: ruby-text;
}
```


# 参考

https://developer.chrome.com/blog/chrome-121-beta?hl=ja
IchigoJamのフォントの白マスの位置ごとの数を求める

[IchigoJam](https://ichigojam.net/) のフォントの白マスの位置ごとの数を求めてみた。
すなわち、8×8ピクセルの各位置について、IchigoJam のフォントの文字コード0～255すべてのパターンのうちその位置が白になっているのが何パターンあるかを求めてみた。

~~「位置ごと」の「イチゴ」の部分~~

※IchigoJamはjig.jpの登録商標です。

# プログラム

```
10 ' ｼﾛﾏｽ ｲﾁ ｺﾞﾄ ﾄｳｹｲ
20 CLS
30 FOR I=0 TO 7
40 FOR J=0 TO 7
50 [8*I+J]=0
60 LOCATE 4*J,12+I
70 PRINT DEC$([8*I+J],4);
80 NEXT:NEXT
90 FOR C=0 TO #FF
100 FOR I=0 TO 7
110 R=PEEK(8*C+I)
120 FOR J=0 TO 7
130 X=8*I+J:LOCATE 12+J,2+I
140 IF (R>>(7-J))&1 PRINT CHR$(#8F);:[X]=[X]+1:LOCATE 4*J,12+I:PRINT DEC$([X],4); ELSE PRINT CHR$(#80);
150 NEXT:NEXT
160 WAIT 10
170 NEXT
180 LOCATE 0,21
```

このプログラムは、[CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/deed.ja) でライセンスする。

# 解説

* 10行目：タイトル
* 20～80行目：画面とカウントを初期化する
* 90～170行目：各パターンを処理する
  * 100～150行目：パターン内の行をそれぞれ処理する
    * 110行目：行のデータを取得する
    * 120～150行目：各列を処理する
      * 130行目：処理中のピクセルに対応する配列の要素と画面の位置を設定する
      * 140行目：処理中のピクセルを描画し、白マスであればカウントを行う
  * 160行目：少し待ち、処理したパターンと、ここまでのカウントを見せる
* 180行目：カーソルを結果の下に移動する

# 実行結果

IchigoJam BASIC 1.4.3 (IchigoJam Q) で実行した結果、以下の結果が得られた。

![実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/cac59bee-0e90-02c1-52ad-bc8c16acaae1.png)

## 白マスが多かった位置TOP3

以下の位置は1-originである。

1位：左から4番目、上から7番目 147パターン
2位：左から3番目、上から7番目 126パターン
3位：左から4番目、上から5番目 125パターン

1位の場所は、唯一半分を超えてぶっちぎりの1位である。
2位以下は僅差であり、123～126パターンがそれぞれ1箇所ずつ存在する。

## 白マスが少なかった位置TOP3

以下の位置は1-originである。

1位：左から8番目、上から2番目 16パターン
2位：左から8番目、上から8番目 17パターン
3位タイ：左から8番目、上から7番目 18パターン
3位タイ：左から1番目、上から8番目 18パターン

19～21パターンの場所もそれぞれ存在する。

## ヒートマップ

結果をヒートマップにしてみた。

![ヒートマップ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/81efba6f-e7d7-b3c4-9cf1-23b0f8760b8b.png)

全体的に、角や端は少なめ、真ん中は多めという傾向がみられる。
一方、上端は比較的多め、右から2列目 (1-origin) は比較的少なめとなっている。
FastReport VCL & FMX 2023.3 の日本語化(1)

# FastReport VCL & FMX 2023.3 の日本語化(1)

以前、[FastReport Embarcadero Edition を日本語化](https://qiita.com/igy/items/6224f1be773a7937015f)を書きましたが、Ver.2023.2 あたりでLocalization Systemが変更されたようで、Recompile Wizardがなくなり、TfrLocalizationController の Languageプロパティを切り替えることで言語の切り替えが出来るようになっています。

ただ、実際に日本語が表示できるようになるまでには、いくつか手動で行うことがありますので、今回はそのあたりを書いてみたいと思います。

## FastReport VCL & FMX 2023.3 をインストール

Delphi 12のGetItからFastReport VCL & FMX 2023.3がインストールできます。
インストール先は、
C:\Users\ユーザー名\Documents\Embarcadero\Studio\23.0\CatalogRepository\FastReport-2023.3
になります。


## TfrLocalizationController

FastReportを使った既存のプロジェクトに TfrLocalizationController を追加します。

ただ、この時点では、オブジェクトインスペクタで、Languageプロパティの箇所のドロップダウンリストにはEnglishしか表示されず、直接、Japaneseと入力しても、印刷ダイアログやプレビュー画面は英語表記のままです。

当初、GetItからインストールできるEmbarcadero Editionでは日本語化できないのかな・・・と思いましたが、言語別のリソースパッケージをインストールすることで、LanguageプロパティでJapaneseが選択できることをDEKOさんに教えていただきました。


## リソースパッケージをインストール

インストール先の
VCL : RS29\VCL\Win32フォルダにある frLanguageJapanese29.dpk
FMX : RS29\FMX\Win32フォルダにある FMXfrLanguageJapanese29.dpk
をコンパイルして、インストールします。

これで 既存のプロジェクトに追加したTfrLocalizationController の LanguageプロパティのドロップダウンリストにJapaneseが選択できるようになり、コンパイルすると、印刷ダイアログやプレビュー画面などで日本語表示できます。

**印刷ダイアログ(VCL)**
![fr2023_vcl_printdlg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318490/20bacc87-10d0-0b37-fa89-5128103c7eb7.png)

**PDFファイルへのエクスポート(VCL)**
![fr2023_vcl_exportpdf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318490/ad555a7e-ff67-a303-ba9f-00e521698fe3.png)

**印刷ダイアログ(FMX)**
![fr2023_fmx_printdlg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318490/7fb23b7e-e2e3-6828-f550-efbac28170f9.png)




## 最後に

以前のバージョン同様、日本語のリソースファイルは、すべての文字が日本語に翻訳されているわけではなく、英語のままの箇所があります。
ただ、以前のバージョンは、XMLファイルがそのままフォルダに格納されていたのですが、現在のバージョンは、frLanguageJapanese.res に格納されているようです。

この frLanguageJapanese.res に格納されているファイルの書き換えに関しては、[FastReport VCL & FMX 2023.3 の日本語化(2)](https://qiita.com/igy/items/81c1cb704b5a03d753dc)で書きたいと思います。
AWS FIS チュートリアルやってみた


## AWS FISとは
- AWS Fault Injection Serviceのこと
- フォールトインジェクション実験をするためのフルマネージドサービス。
- Windows OSには対応していない。

## このサービスを使おうと思った理由
- システムに負荷をかけた時に、耐性、回復力があるか確認できるツールを探しているため。

## チュートリアルをやってみる
今回は、ユーザーズガイド記載を参考にした。

https://docs.aws.amazon.com/ja_jp/fis/latest/userguide/fis-tutorial-run-cpu-stress.html

#### ①EC2を準備して、ClowdWatchアラームを作成する。
閾値はCPU使用率を最大値50%。期間は1分
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148393/56092dec-a4d0-3e23-af27-909d29bd208e.png)


#### ②実験テンプレートを作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148393/09d18ad8-144f-9374-d5b8-1addaef83691.png)

#### ③実験を開始する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148393/def4e411-b285-fdc9-aec4-6873978c28f4.png)

#### ③結果
数分後、CPUUtilizationが100%まで上昇しアラーム状態となった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148393/4c3d1d59-5d4c-7a31-c872-769ee1f10937.png)

実験は設定の通り、Stoppedになった。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3148393/3ca1de00-e9b5-4ff2-6150-38b048ac8a8b.png)

## 感想
- OSに触ることなく負荷をかけられるのは便利だと思う。
- 用途に合わせたシナリオがあれば、効果的なツールだと思う。
パレード限定の奴隷を作った

この記事は[Qiita Advent Calendar クソアプリ](https://qiita.com/advent-calendar/2023/kuso-app) シリーズ3　17日目の記事です。

昨日は@arie0703 さんの [ランダムにおすすめのおやつを教えてくれるSlackワークフロー作ってみた](https://qiita.com/arie0703/items/98255ca3bffc747a05ef)でした。
読んでいておなかがすいてしまいました！

## そうだ！奴隷をつくろう

※これ以降、ゆる学徒ハウスフル尺ラジオのネタバレを含みます。

古代ローマには凱旋パレード専用の奴隷がいたそうです。
その奴隷は、功績をあげた将軍が国民に持ち上げられることでいい気になって暴君にならないように耳元で「お前はただの人間だ」とずっとささやき続ける役目だったようです。
### 定期的になにか言ってくるだけのものだったら作れるのでは？
定期的になにか言ってくるものといえば通知だ！定期的に通知が送られるだけのアプリだ！
届き続ける「お前はただの人間だ」という通知で頭を冷やすことが可能に！すごい！
通知を定期的に送るだけだし、GASからLINEにメッセージ送るだけでいいかな？作ろ！
## 仕組み
GASの定期実行→LINE→通知が来る！
### LINE Notify の準備
自分だけのグループを作成します。ここに奴隷からメッセージを送ってもらいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618819/560bcd97-132b-b354-5245-de4ffcd83684.png)

### LINE notifyの設定
Line notifyにLINEのアカウントでログイン
https://notify-bot.line.me/ja/
マイページからトークンを発行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618819/ff33addf-4c31-fceb-bc66-3a6669d122fc.png)

奴隷のグループを選択して、いい感じの名前をつける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618819/773dfb6c-f70d-632d-40cf-1c348edda55a.png)

発行されたトークンをコピペしておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618819/7a52c25c-1adb-9617-f054-9328c6157241.png)

### GASでメッセージを送るだけのコードを書く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618819/181933be-85df-b6e2-8123-23c0a4ea07c8.png)
```
const LINE_NOTIFY_API_TOKEN = '[トークン]';

function sendLineMessage() {
  const message = `お前はただの人間だ`;
  const notifyUrl = 'https://notify-api.line.me/api/notify';
  const options = {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${LINE_NOTIFY_API_TOKEN}`,
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    payload: {
      message: message,
    },
  };

  UrlFetchApp.fetch(notifyUrl, options);
}
```

実行すると……

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618819/b1cc6c52-c261-7570-6dcd-b2ce8c1c4ec6.png)

送られた！！！！！！！！
あとはこれを1分ごとに定時で動かして……

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618819/29ae0d47-165b-2a9a-a623-9aec8de9fcc0.png)


できあがり！


## さいごに
今回は自分が特別な存在ではないただの人間だということを突きつけてくる奴隷……のかわりにLINEでメッセージを送る機能をつくりました。

面白がって1分ごとに送るようにしてたらちょっと気持ちか沈んだので、ほどほどにすることをおすすめします。
ここまで読んでくださりありがとうございます！

明日は @tenugui_taro さんの フロント周りでなにかクソアプリ　です。楽しみですね！
curlでメッセージ送信（Teams）

## ➀チームにアプリ追加
Incoming Webhook
![2023-12-17_23h33_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184925/622b23f2-1609-23aa-2d2d-3df611d0dd97.png)

※個人チャットの方にアプリは追加できない。（チームが必要）

## ➁実行
- コマンド
    ```shell
    curl -H "Content-Type: application/json" -d '{"text": "Hello World!"}' 【Webhook-URL】
    ```
- 結果
![2023-12-17_23h35_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184925/cae7a8f8-253b-4cf7-9d85-4afb259377f8.png)
nextcloudの公式dockerイメージをtls化してみた

## 作成物

github: https://github.com/tdzz1102/nextcloud-tls-docker

dockerhub: https://hub.docker.com/r/tdzz1102/nextcloud-tls

証明書をコンテナにマウントするだけでhttpsが有効化されます。使い方は上記リンクのいずれかに参考してください。

## このイメージを使う（作る）理由

[nextcloud公式イメージ](https://github.com/nextcloud/docker)は、nextcloud本体とapache2から構成するものです。apache自体はtlsに対応できるが、公式イメージに活用されなかったです。httpsの対応策として[all-in-oneイメージ](https://github.com/nextcloud/all-in-one)もありますが、オレオレ証明書が使えません。しかも私的には使わない機能が多すぎて、煩わしい感じがします。

このイメージは、公式イメージに基づいて、組み込みapacheをsslモジュールを有効化して、与えられた証明書を使ってhttpsサービスを提供させるものです。

## 使い方

```bash
PATH_TO_CERT=/your/certificate.crt
PATH_TO_KEY=/your/private.key
```

証明書ファイルの場所を環境変数として指定し、

```bash
docker run -p 443:443 \
           -d --name nextcloud-tls \
           -v $PATH_TO_CERT:/cert/cert.pem \
           -v $PATH_TO_KEY:/cert/key.pem \
           -v nextcloud-data:/var/www/html \
           tdzz1102/nextcloud-tls:20231217
```

でコンテナを起動します。

これで、nextcloud☁️へのhttps接続ができるようになりました！

## 作り方

```dockerfile
FROM nextcloud
COPY ./default-ssl.conf /etc/apache2/sites-enabled/default-ssl.conf
RUN a2enmod ssl
```

提供した`default-ssh.conf`が公式イメージから`docker cp`したもので、変更は以下の二行のみ：

```apache
SSLCertificateFile      /cert/cert.pem
SSLCertificateKeyFile   /cert/key.pem
```

## 余談

半年間も無事に使ってきたので、安心に使ってください。

`sed`を使えば、コピペをせずdockerfileをより綺麗に書くべきです。また時間あれば改善します😃。
LocalでDockerを用いてサーバー間の通信をするときは気をつけよう

## 状況
フロントエンドはNext.js、バックエンドはRailsを用いて開発をしています。
Next.jsのサーバーコンポーネントでバックエンド側にリクエストをする際に、下記のようなエラーが発生しましたので、解決方法について説明したいと思います。

```
frontend_1  |  ⨯ unhandledRejection: TypeError: fetch failed
frontend_1  |     at Object.fetch (node:internal/deps/undici/undici:11372:11)
frontend_1  |     at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
frontend_1  |   cause: Error: connect ECONNREFUSED 127.0.0.1:8080
frontend_1  |       at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1555:16)
frontend_1  |       at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
frontend_1  |     errno: -111,
frontend_1  |     code: 'ECONNREFUSED',
frontend_1  |     syscall: 'connect',
frontend_1  |     address: '127.0.0.1',
frontend_1  |     port: 8080
frontend_1  |   }
frontend_1  | }
```
## 解決策
今回のエラーはNext.js側でサーバーコンポーネントを使ったことに原因がありました。
この場合、二つのサーバーが通信することになりますが、
LocalでのDocker環境で同じローカルホストアドレスを使うと、自分自身にリクエストをかけることになるためエラーになります。
詳細はこちらをご参考ください。https://www.sambaiz.net/article/359/

解決策としては、fetchをする際のURLを`http://localhost:8080/api/v1/users/1/urls/2`から`http://backend:8080/api/v1/users/1/urls/2`に修正することです。
※`backend`はDockerのサービス名になります。
```docker-compose.yml
version: '3.8'
services:
  backend:
```
```getUser.jsx
export default async function getUser() {
  const response = await fetch(`http://backend:8080/api/v1/users/1/urls/2`)
  if (!response.ok) {
    throw new Error('fail')
  }
  return await response.json()
}
```

## 余談
サーバーコンポーネントも単純にもう一つのサーバーであることで、思わぬ所からエラーになりますね。
何時間を調べても解決策がわからなkったのですが、Twitter（X）でエラーが発生して大変だと涙を流してたら、
いろんな方からアドバイスをいただき、解決できました。（ありがとうございます！）
https://x.com/wanchanmask/status/1736378307866919174?s=20

おそらくアドバイスがなかったら解決できなかったと思います。😭

それでは、読んでいただきありがとうございました！
BASICのソースをElixirに移植してみよう！ #1 序文がただのポエムになったわ

# 1. OverView

Space, the final frontier...宇宙、それは人類に残された最後の開拓地

大昔、もう僕が子供の頃、宇宙戦艦ヤマトも放送されてない時に、アメリカでは宇宙大作戦（スタートレック）のゲームをコンピューター上で再現しようとしていた人がいたそうです。

https://www.nakajim.net/index.php?Trek

ゲームの文書の翻訳はこちら
https://www.nakajim.net/trek/trek.html

この時代のコンピューターのスペックに合わせて、このゲームはかなりコンパクトなソースだったわけですが、
当時のマイコンのメモリは非常に少なく動かない機種も多かったそうです。
そこで、このゲームを小型のコンピュータでも、簡略化し、より小さいメモリで動かせる様にしたのが、Tiny Trekです。

後述の理由で、こいつをElixirに移植してみようと思い立った訳ですが、こんなもん読めるかい！と言うくらいに
メモリ節約のテクニックが詰まったソースです。詳しくはおいおい書きますが、こんな感じで何が何だかわからん。

```
45 F.I=71TO152:@(I)=0:N.I:@(8*X+Y+62)=4,M=A.(@(8*U+V-9)),N=M/100
```

これ、省略形で書かれておりますが、実際にはこういうソースです。

```
FOR I=71 TO 152
    @(I)=0
NEXT I
@(8*X+Y+62)=4
M=A.(@(8*U+V-9))
N=M/100
```

F.とかN.とIとか省略形で命令を書くとメモリを節約出来る、もうそこから節約しているソースなのです。
えー、これ読むの？awkで変換せんとダメか？と思ってたところに、このソースをPC-6001にわかりやすく移植されたナナオさんと言う方がいまして。

http://p6ers.net/hashi/startreklegacy.html

これならっ、これなら俺にも読める！移植してくださった！ナナオさんありがとうございます！と移植を開始した次第です。

本当はちゃんとして移植を完了させ、完全なものを出すべきかと思ったのですが、試行錯誤、様々な言語の壁を乗り越える様、どんどんリファクタリングをする過程を、記事にしていきたいと思います。

# 2. 動機と最初の意識転換について

さらにポエムが続きますが、僕と同じハマり方をしている人がいたら楽しいので、書いておきます。

言い訳は抜きにして、どうもElixirの勉強が捗らない、Elixirと言うのは非常にパワフルな言語で、見よう見まねでコピペしていれば、スマホの掲示板アプリが、1.5時間のハンズオンで、誰でも出来てしまいます。

しかし、どうも、ほかの言語の様にさくっと書けない…俺は阿呆か？と卑下したところで始まらないので、コードを読んでいるうちに、関数型言語やElixirの書き方の細部にこだわって、ロジック自体をないがしろにしたからではないかと思う様になりました。

と言うのも、僕の得意なプログラミング言語からの置き換えElixirの機能を語れば、あれがない、これがない、と不便に見えるのですが、別に処理をする上で、ループも分岐(if文)もすべてある。

要するにプログラム全体の構造を考え直し、やりたいことに立ち戻らないとダメだろう。

例えば、今回のEasy Trekは全部で64個のクォドラントそれぞれに、100面ダイス(乱数)を振って5以下の場合、宇宙基地を配置します。

BASICのソースだと、以下の様な処理になります。
```
    FOR I= 0 TO 63
        # 1d99を振る。5以下でベースが存在する。
        J=-(FNR(99)<5)
        B=B+J       # Baseの数を増やす、追加されるのは、FNR(99)<5の結果である事に注意
        A(I)=-10*J
    NEXT I
```
これ、変数A(0) - A(63)に、宇宙基地(Star base)をランダムで配置しているのですが、私は以下の様にしました。

```
# あまり綺麗な書き方ではないのですが…
starbase_list = Enum.reduce(0..63, [], fn _x, acc ->
        if :rand.uniform(100) <= 5 do
            starbase = [Set_objects.set_item(acc)]
            [starbase | acc]
        else
            acc
        end
    end)
```

データ構造が違うので、単純な比較は出来ませんが、BASICのLoopと同等の文法を求めるのではなく、元の目的を考えてロジックを組んでコードを書けばよいのではないのだろうか？そう言う蓄積がないから、コードが書けないのではないだろうか？と考えた次第です。

上のElixirのコードも読んでしまえば
1. Enum.reduceで、0から63までループする
2. :rand.uniform(100) の結果が5以下なら、starbaseと言うリストにオブジェクトを追加していく。

それほど、大きな差異があるわけでもない。要は「何をするか」を決めてなく、漠然と既存の自分の知っている言語の面影を追っていただけだったのではないかと反省しました。

そこで、何か手ごたえのあるソースを読もうとおもっていたのですが、ちょうど古いゲームのコードを別件で探していた際に、Tiny Trekのコードが、確かに記法やメモリ節約のため、読みにくい部分があるももの、ロジック自体は非常によく練られていて簡潔であり、勉強鵜や移植に向いているんじゃないかと気づいたわけです。

そう思って、気楽に始めました。
さて、ここまでデカい口を叩いた成果が出るかは…やれんのか？やれません。
いやもう、このソース、すっごくよく出来てるんですよ。TinyBasicの記事を書きたくなるくらいにｗ（本末転倒）