OmniAICreator/Qiita-1.07M huggingface dataset:
ログリーディングのすゝめ

みなさん、こんにちは。昨年はコロナに倒れておりましてアドベントカレンダー2年ぶりの参加です。

最近はレガシーな巨大アプリの保守開発に取り組みつつCI/CDもやっています。今日はCI/CDに取り組む中で思う、全エンジニアに個人的にお勧めな手軽にできる活動を紹介しようと思います。

# 前段

## 懐かしき、かつての開発現場

ちょっと昔話をします。

かつてCOBOLソースの修正をするときは、自分の手元のテキストエディタで修正して(入力補完なんて存在しないし構文エラーも検出されない)、コンパイル環境のUnixマシンにアップロードして、ターミナルで繋いで、コマンドでコンパイルしていました。
手元ではコンパイル通るか分からないまま書いているので、コンパイルエラーがしばしば発生しました。コンパイル通ったら動作確認して、できたソースは自分でソース管理のリポジトリにアップロードしたり、評価環境に配置したりしていました。
この頃はレビューも印刷物ベースで実施されており、紙にCOBOLのソースを印刷してソースコードレビューを行い、レビュー時と違う差分が提出されてないかを評価担当者が目検してたりしました。10年ほど前の話です。

ほぼ手作業でやってるので、ソースコードファイルをマシン間で転送する際に文字化けする問題の対処だったり、コンパイル通らない原因の対処だったりを自ら対処していました。

その後、COBOLをスーパーハイパーウルトラ頑張ってJava化し、当たり前にIDEを使ってコード書きながらビルド・デバッグするようになり、コードもgit管理するようになり、レビューをMRやPR上でするようになり、徐々にビルドや各種チェックを自動化して今に至ります。

## 自動化していった結果どうなっているか

改めて過去と比べると、めちゃくちゃ便利になった！！これは間違いない。無駄な作業が減った上に、各人の手作業工程での作業漏れやバラつきも最低限のラインは揃えらえるようになったと思います。
一方で、何がどうなって修正したものが出荷されていっているのか、ブラックボックス化も進みました。（更に自動化の仕組みの中にも技術的負債が蓄積し・・・という話は今回は省略）

そしてエンジニアが「何か自分の入れた修正が環境に適用されてないんですけど」とか「何かチェックで赤くなってるけど無視しちゃった」とか「急いで暫定モジュール出したいのにビルドが終わらない」ってCI/CDチームやら関係者らに言う事態が発生する時代の到来です。

ちがう、そうじゃない！！！私たちが作りたかった便利な世界はこれじゃない。
せめて、どうしてそうなっているか知ろうとして欲しい。
・・・マインドの話はきっと他に沢山のポエムがあるかと思うので、すぐにはじめられることの話をします。


# いますぐにできること

「よく分からないけれども何か動いている(あるいは動いていない）」
「なんかエラーっぽいログが出てるけど、動いてる…？」

CI/CDの仕組みに関わらず、自分以外の誰かが開発してきたアプリの保守に関わる者であれば誰しも経験する可能性があることだと思います。
理解のために、ドキュメント読んだり、先輩の話を聞いたり、AIに聞いてみたり、色々な選択肢があると思うのですが、その選択肢に入れていただきたいのが **ログを眺めてみること** です。

自動化スクリプトにしろアプリケーションにしろ、あらゆるものはログ出力があります。無いことは非常に稀です。

**そのログを読みましょう。**

## ログリーディングの心構え

全てを理解できなくても構わないけど、少しずつ仲良くなりたい、という気持ちで向き合います。

* いつ・どこ・何から書かれたログなのか
* 何をしようとしているのか
* どういう順番で処理しているのか

を**推測しながら、とにかく読んで**みましょう。

必要に迫られて調べたり、大量に読んだりする内に、推測が少しずつ確証になり読めるようになっていきます。


### トラブル発生時に読む

正常時のログと異常時のログを比較してみましょう。 
どこから違いが生まれているかが、原因調査の第一歩になります。

**異常時のログにERRORとかFailedとかExceptionが出ている場合はラッキー**です。
確実とは言えませんが、それが原因な可能性が割と高いです。
世間一般的な仕組みを利用している場合には、ググると情報出てくることも多いです。

CI/CD関係のトラブルにおいては、ログを見て、ここに問題がありそうだがどう思うかという形でCI/CDチームにご相談いただくと嬉しいです。

CI/CDに限らず、相手を知ろうする歩み寄りの態度に対しては、きっとエンジニアは温かな態度になると思います。
つまり、一緒にトラブル対応をする仲間を得やすくなるってことですね。

すごい、ログ読むといいことがありそう！


### 常時にも読む

さらにお勧めなのは、困ったときに限らず、ログ出力を目にする機会があればログを眺めてみることです。

こういう技術をここで使ってるのか、とか、このコマンドでこんなことができるのか、等の技術的なキャッチアップもできます。
だんだん慣れてきて、このタイミングでいつもこういうログが出る、これは普段は目にしないログだな…というのが分かるようになります。近所のお散歩みたいな感覚です。

この状態になると処理への理解が進んでいるはずです。

また、何やら時間がかかってる処理がある等にも気付くようになります。
変化のいち早い察知や、問題箇所の発見に繋がり、処理や実行環境の改善になることもあります。

すごい、ログ読むといいことがありそう！！


### ログについて語ろう

沢山のログを読んでいると、だんだんログ出力のあるべき姿について語れるようになってきます。
こういう情報を出して欲しい、ログレベルはこうすべき、ログの保持期間は～、ログの参照性を高めるにはどうしたら、まで考えが至ってくるはずです。

読み手から書き手へ、更に流通経路まで考えられる、ログの設計者としての素地がいつの間にか形成されます。

ログ出力はアプリケーション開発の中でも必須な要素です。
作成者はやはり利用者のことが分かっている方がいいものができます。
つまり開発で設計やコーディングする時にも活かせる体験が自然とできている状態になります。

すごい、ログ読んで語るといいことがありそう！！！


# まとめ

アプリケーションのログでも、ビルドスクリプトのログでも、まずは読んでみましょう。最初はよく分からなくても、少しずつ理解していけばいいのです。
ログを読むと処理への理解が深まり、仲間が増え、開発者としての技術力がアップします。いいことだらけです。

ログを読みたくなってきたあなたにも、いいことが沢山ありますように。
そしてログを読んだ上での会話がエンジニアの間でされることが増えますように。

ログリーディング is fun!
UbuntuとwindowsのデュアルブートSSDを換装する

タイトルの通りの事をしたので備忘録

# SSDのクローンとwindowsの起動
今回はwindowsでSSDをクローンする

1. クローン対象のSSDを適当なSSDケースに入れてPCに接続する
1. 今回買ったSSDはCrucialなので、[True Image for Crucial](https://www.acronis.com/ja-jp/promotion/crucialhd-download/)を使った
1. システムドライブをそのままクローンする様な設定でやる（メモ取り忘れた）
1. クローンできたら、元々PCについていたSSDを外し、クローンしたSSDを取り付ける
1. grubを無視すると、windowは起動するはず

# Ubuntuの起動
Ubuntuは起動ディスクのUUIDが変わるので、fstabとgrubの設定を変更しないと起動できない


### grub
設定を書き換える必要があるぽいけど、boot-repairでやると楽です
live USBから起動してインストール＆設定する


```
sudo add-apt-repository ppa:yannubuntu/boot-repair && sudo apt update
sudo apt install -y boot-repair
```

インストールが完了したらboot-repairを起動し、「おすすめの修復（Recommended Repair）」を選択する
再起動するとgrubのメニューは表示されるようになる

### fstab
起動ディスクのUUIDが変わるのでfstabの設定を変更する

1. live USBから起動する
1. GpartedでディスクのUUIDを調べる
    1. `パーティションをダブルクリック→UUID`
1. 起動ディスクはRead Onlyになってるので一度rwでリマウントする
    ```
    mount -o remount,rw /
    ```
1. vimで`/etc/fstab`にあるUUIDを↑で調べた値に変更する
1. 再起動する

ここまでやるとデュアルブートでUbuntuもWindowsもどちらも起動できるようになるはず

以上
Image.networkでGoogle Drive上の画像を取得しようとした話

# はじめに

現在作成しているアプリでGoogle Drive上の画像を読み込みたいと思い、実装してみたのですが問題発生。

```dart
        var url = "https://drive.google.com/uc?export=view&id=$fileId";
        var downloadImage = Image.network(url,
          headers: {
            "Authorization": "Bearer $accessToken"
          },
          loadingBuilder: (context, child, loadingProgress) {
            if(loadingProgress != null){
              return _noImage;
            }
            return child;
          },
          frameBuilder: (context, child, frame, wasSynchronouslyLoaded) {
            if(!wasSynchronouslyLoaded && frame == 0){
              // ロード完了
            }
            return child;
          },
          errorBuilder: (context, error, stackTrace) {
            return _noImage;
          },
        );
```

これを実行すると以下のエラーが発生する。
```
Exception: Invalid image data
             Exception: Invalid image data
             #0      _futurize (dart:ui/painting.dart:6637:5)
             #1      ImageDescriptor.encoded (dart:ui/painting.dart:6494:12)
             #2      instantiateImageCodecWithSize (dart:ui/painting.dart:2291:60)
             #3      PaintingBinding.instantiateImageCodecWithSize (package:flutter/src/painting/binding.dart:182:15)
             #4      NetworkImage._loadAsync (package:flutter/src/painting/_network_image_io.dart:153:22)
             <asynchronous suspension>
```
これを解決するのが今回のお話です。

# Goodle Driveで提供されるURL

## 共有のURL

Google Driveで共有の際提供されるURLは
```
https://drive.google.com/file/d/{fileId}/view?usp=drive_link
```
になります。
このURLをChromeで確認するとこんな感じでいっぱい通信が行われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/613a1238-c96c-0e90-99e2-c9f78832607e.png)

おそらくですが、共有で提供されるリンクでは、最初にHTTP Status 200で返却される内容がHTMLなので失敗すると予想されます。

## ダウンロードのURL

では次にダウンロードで使用されるURLを確認します。
URLは以下の通りです。
```
https://drive.google.com/uc?export=view&id={fileId}
```
このURLをChromeで確認すると、複数の通信が発生していることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/8657de3c-f598-47f0-a252-6c50bc12e745.png)

ただ、リダイレクトされまくったあとの200のヘッダを見ると Content-Type:image/jpeg で返却されているので、よさそうに見えます。
しかし実際には Exception: Invalid image data が発生します。

対象画像の共有の設定を リンクを知っている全員 に変更すると表示されました。

認証情報を付与してリクエストできれば、共有設定を リンクを知っている人全員 にしなくても行けそうですが、手段がわからないので、現段階ではこれで行くしかない。

```dart
        var url = "https://drive.usercontent.google.com/uc?id=$fileId&export=download";
        var downloadImage = Image.network(url,
          headers: {
            "Authorization": "Bearer $accessToken"
          },
          loadingBuilder: (context, child, loadingProgress) {
            if(loadingProgress != null){
              return _noImage;
            }
            return child;
          },
          frameBuilder: (context, child, frame, wasSynchronouslyLoaded) {
            if(!wasSynchronouslyLoaded && frame == 0){
              // ロード完了
            }
            return child;
          },
          errorBuilder: (context, error, stackTrace) {
            return _noImage;
          },
        );
```

# まとめ

- Image.network で指定するURLはダウンロードで使用するURL
- 画像の共有設定は リンクを知っている全員 にする
MUI ModalコンポーネントにあるdisableScrollLockプロパティ

:::note
業務の中で、`MUI`の`Dialog`コンポーネントを使用してダイアログを作成した際に、背後のコンテンツのスクロールを制御したいという状況がありました。その際に、`disableScrollLock`プロパティという便利なものがあったので記録します
:::

https://mui.com/material-ui/api/modal/#Modal-prop-disableScrollLock


#### 概要
* プロパティ名: `disableScrollLock`
* 型：`boolean`
* デフォルト:`false`

このプロパティは、`Dialog` や `Modal` コンポーネントに対して `true` または `false` の値を設定することで使用できる。

#### 使用例
下記の例では、`disableScrollLock` プロパティを `true` に設定しています。これにより、ダイアログが開いている間でも、ページの背景をスクロールできるようになります。
```typescript
import React from 'react';
import Dialog from '@material-ui/core/Dialog';

function MyDialogComponent(props) {
  return (
    <Dialog open={props.isOpen} onClose={props.handleClose} disableScrollLock={true}>
      {/* ダイアログの内容 */}
    </Dialog>
  );
}
```
VSCodeの色分けを意識したら世界が変わった話

## はじめに
VSCodeを触り始めて約1年経ちました。

エンジニアの中では「当たり前、常識」とされていることでも、プログラミング初心者は知らないこともあります。
先輩とペアプロ中に何気なく交わした会話で、それまで知らなかったことに気づくことができ、コードが一気に読みやすくなりました。
おそらく常識すぎて販売されている書籍などには明記されていないと思うので、共有します。
もし、プログラミング初心者の方の中に私のように知らずにコードを書いている方がいらっしゃったら、この記事を読んで世界変えましょう。

### 自己紹介
私は2023年9月1日にフロントエンドエンジニアとして自社開発のSaaS企業に入社しました。
未経験独学で、薬剤師からの転職です。
詳しくはこちらをご覧ください。

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


## 前提
VSCodeのカラーテーマがダークモダン(Default Dark Modern)の場合の配色です。
カラーテーマを変更していると色は異なるので自分の配色に置き換えて読んでください。

## 背景
先輩とモニターにVSCodeの画面を映しながらペアプロしている時の会話です。

私「これpropsで渡ってきているの関数なんですかね？親コンポーネント見にいくか…」
先輩「それ黄色だから関数じゃない？」
私「え？黄色だと関数なんですか？？？」
先輩「そうそう。変数は水色、型は緑だよ」
私「…え、本当だ🫢意識したことなかった…」

こんな感じの会話でした。

## 具体例で説明
以下のコードを例に色分けを意識して読むと…
![スクリーンショット 2023-12-14 0.34.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3537832/5a1430aa-d1eb-5dcd-74f2-927fcf1348f8.png)

3行目の`ProfileProps`は緑なので型だとわかります。
その下の4〜6行目は型定義の書き方を覚えていなくても、：の右側が緑なのでこれも型なんだと見ただけで判別できます。

12行目の`<Avatar>`は緑、その上の`<div>`は青ですね。色が違うので別の意味を持つことが予想できます。JSXの中で型定義ではなさそうなので、コンポーネントなんだろうなと判別できます。

色を意識して情報を取り込むことで、コードが一気に読みやすくなりました。

## 世界が変わった
当たり前すぎて、「いやそれぐらいわかるでしょう。なんでわからないの？」と言われてしまうかもしれませんが、先輩に言われるまで、本当に気づいていませんでした。
VSCodeを見ても、もちろん色が付いているのはわかるのですが、「カラフルだなー😇」ぐらいにしか思ったことがありませんでした。

色を意識してコードを見てみると、確かに色が意味を持っていました。
色からも情報が得られるので、そこに何が書いてあるかを文字として読む前に、役割を知ることができます。
これが私には衝撃的でした。**世界が変わりました。**

プログラミング初心者なので、まだ文法が不安な箇所が多々あります。初めて見るソースコードでは、どれがReactのコンポーネントなのか、JSXなのか区別ができなかったり、どこに型を書けばいいのか忘れるなんてことがよくあります。
今までは、大文字・小文字で判断したり、都度文法を調べたりしていました。しかし、色でも判別ができることを知ると、色だけ見ればそれがなんの役割を持っているのか判別できるので、コードを読んで理解するスピードが格段に上がりました。

## 終わりに
この大発見をしたときの衝撃は今でも忘れられません。「今までなんで気づかなかったんだろう」とショックも受けました。
エンジニアにとって当たり前でも、プログラミング初心者にとっては当たり前ではないことはたくさんあるはずです。しかし残念ながらそれがまとまっている書籍や記事は少ない…😭
同じようなエピソードありましたらぜひ教えてください！
エクスプローラによるファイルの復元について

# はじめに

今回はエクスプローラによる**ファイルの復元**についてです。

最近、現場のとある管理表の記載内容に違和感があり、**「以前のバージョン」から復元ポイントのファイルを確認**したことがありました。
その際、管理表がデグレードしていることに気づいたのですが、一緒に確認していた新卒社員さんが「以前のバージョン」を知らず、後日やり方を聞かれました。

デグレの他にも、
* 間違った内容で保存した
* ファイルを誤って完全削除した

場合などにも有効です。

ここでは確認方法を書いていきます。

# 使い方
使い方は**とっても簡単**です。
エクスプローラにて復元したいファイルがあるファルダを開き、余白を右クリックし、「プロパティ」をクリックしてください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530030/f892c5e3-f46c-bd5c-74e8-f9683241df5c.png" alt="代替テキスト"
       width=30%>

次に「以前のバージョン」タブを選択します。
下にそのフォルダのファイル履歴もしくは復元ポイントのフォルダの一覧が表示されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530030/451b6da4-3041-2013-74e6-52cf04b85be2.png" alt="代替テキスト"
       width=40%>

確認したい日時のフォルダを選択し、「開く」をクリックすると保存された時点のフォルダが表示されます。
以前のバージョンの**ファイルを確認**したり、**コピーして持っていく**ことも可能です。

また、フォルダのバージョンの一覧からフォルダを選択し「復元」をクリックすることで**フォルダ自体を復元**することも可能です。
<font color="Red">※あくまで保存された時間のフォルダの復元になりますので注意してください。</font>


# 使用するには設定が必要
:::note info
ファイルを確認、復元するためには、ファイルの履歴や復元ポイントの設定をする必要があります。
:::

現場のファイルサーバ等であれば、毎日定刻に保存している場合が多いかと思いますので、気になった方はプロパティから確認してみてください。


尚、自分のPCで設定したい方は以下のサイトが分かりやすかったので参考にしてみてください。
[Windows 10：以前のバージョンって？－使い方教えて！](https://www.ubackup.com/jp/windows-10/previous-versions.html)

# 最後に
如何でしたでしょうか。
もちろん、デグレや意図しないファイル削除などないに越したことはありませんが、もし起こってしまった場合はこの記事を思い出していただけますと幸いです。
便利な機能なので、ご存じなかった方は是非試してみてください。
SageMathを使ってみました。

# SageMath
簡単に言えば数学の高速計算ソフトウェア？　pythonで書けるので学習コストも低い
オンライン上でも試せるらしい。
https://sagecell.sagemath.org/


CTFの勉強をしていてcryptoで桁の大きい数を扱うのでローカルのpythonだと計算ができなくて困っていたら何やらSageMathというものを使えばいいということを耳にした。

## 早速インストール

macだったのでこのgithubからインストール。
https://github.com/3-manifolds/Sage_macOS/releases


## 使ってみる
ソフトウェアをインストールすれば、jupyter notebookもそのまま使えるとのことだったので、

![スクリーンショット 2023-12-13 16.39.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1090990/baf630b2-d55b-5f04-2cf3-2822695c685e.png)

Classic Jupyterと開きたいフォルダとを選択。


無事jupyter notebook開けたんですけど、cryptoの問題を解くときによく使うpycryptodomeをimportしてもエラーが出たのでその備忘録。

```SageMath 10.2:answer.jpynb
from Crypto.Util.number import *
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In [23], line 1
----> 1 from Crypto.Util.number import *

ModuleNotFoundError: No module named 'Crypto'
```

ChatGPTに聞くとsysをimportしてsys.pathをprintしろということだったので

```SageMath 10.2:answer.jpynb
import sys
print(sys.path)
---------------------------------------------------------------------------
['/Users/yamaguchiyutaka/study/TsukuCTF2023/crypto', '/private/var/tmp/sage-10.2-current/local/var/lib/sage/venv-python3.11.1/lib/python311.zip', '/private/var/tmp/sage-10.2-current/local/var/lib/sage/venv-python3.11.1/lib/python3.11', '/private/var/tmp/sage-10.2-current/local/var/lib/sage/venv-python3.11.1/lib/python3.11/lib-dynload', '', '/private/var/tmp/sage-10.2-current/local/var/lib/sage/venv-python3.11.1/lib/python3.11/site-packages']
```
pycryptodomeが入った場所を確認する。

```SageMath 10.2:answer.jpynb
!pip show pycryptodome
---------------------------------------------------------------------------
Name: pycryptodome
Version: 3.19.0
Summary: Cryptographic library for Python
Home-page: https://www.pycryptodome.org
Author: Helder Eijs
Author-email: helderijs@gmail.com
License: BSD, Public Domain
Location: /Users/yamaguchiyutaka/.sage/local/lib/python3.11/site-packages
Requires: 
Required-by: 
```
sys.pathにpycryptodomeを追加。

```SageMath 10.2:answer.jpynb
import sys
sys.path.append('/Users/yamaguchiyutaka/.sage/local/lib/python3.11/site-packages')
```

### 解決しました！

やはりむやみやたらにローカルにpipするのはまずいのかな？
まあ、ChatGPT最強ということがわかりました。
技育CAMP名古屋キャラバンに参加してみてのお話し

# まず初めに…
このQiitaはコードのすぇつめいもごうぃろくもないことをご了承ください。

# 名古屋キャラバンになぜ参加することになったのか
始まりはHACK SUMMER東海でのお泊り会で愛知工業大学の人と出会い一晩過ごして意気投合し僕が「ハッカソンを一緒に出ないか？」と誘いました。
その後祭り場Techで再会しそこで「君も名古屋キャラバンに参加する予定になったよ」って突然に言われびっくりしましたΣ(ﾟДﾟ)　。

# 終わってみてどう思ったか
* まず体調管理はとても大切だと思いました、なぜならインフルエンザになってタスクを他の人に任せてしまったからです。
だから今後は体調管理をしっかりし改善したいと思います。

* 自分の技術不足を痛感しました。仲間との会話についていけず理解が足りていなかったからです。
今後は一つのことに集中して技術の理解度を深めていきたいと思いました。

# 今回の技育CAMP名古屋キャラバンに出ての感想
今回のハッカソン何か強くね？って思いました。
初手からガイジも出て来て発表の時心拍数が異常に高くて笑いました。
S.Y先輩…強すぎますよ…
    マヨネーズセンサー…ママ…
# 最後に一言
今回初めてQiitaを触りました、疲れたけどQiitaを触れてとても良かったです。
JS書けないけど非同期処理はTurbo Framesで作れる

### そもそもTurboって？

TurboはJSのバンドラー(ex: webpack,esbuildなど)を使わなくても非同期で画面が変わるような処理をしたいときに便利なRails標準機能のこと。HotwireはTurbo, Stimulus, Stradaの３つの相性のことで、詳しく知りたい方はわかりやすい記事もあるのでぜひ。

[stimulus-rails gemを読み解く - Qiita](https://qiita.com/yasu-sg/items/08d586ef53b63e32531d)

[猫でもわかるHotwire入門 Turbo編](https://zenn.dev/shita1112/books/cat-hotwire-turbo)

### Turbo Framesとは

通常の画面遷移でHTMLが丸ごと置き換わるのに対して、Turbo Framesでは```<turbo-frame>…</turbo-frame>```というHTMLタグのようなもので囲った要素が非同期で置き換わります。

### 何が便利？

ちょっと前まで画面の一部だけ非同期（画面遷移なし）で変更したい、みたいなことがあると思った時は「JSを書きましょう」というのが一般的だったみたいです。そこでJSを書く量を削減できるTurboというRailsが搭載しているJSライブラリがあるみたいです。

### Turbo Framesちょこっと試してみる

- TODOアプリのタスクのupdateアクションを非同期でやってみる
- 実装前の仕様の説明
    - 実装前のコード(taskだけパーシャルにしてるよ)
    
    ```ruby
    #_task.html.haml
    .task__name= task.name
    - if task.description
      .task__description
        = safe_join(task.description.split("\n"),tag(:br))
    ```
    
    - new/createアクションは作っていてedit/updateはまだ実装していない状態。(画面は下)
        
![スクリーンショット 2023-12-14 0.24.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327469/cf633078-270f-2f31-7dc3-5bd6cf5eb8b4.png)

        

- 実装後の仕様
    - タスクの名前の右側に編集ボタンを作る
    - 編集ボタンをクリックすると
        - タスクの名前の部分がフォームに
        - 編集ボタンが更新ボタンに
    - 更新ボタンをクリックすると
        - フォームが元に戻る
        - ボタンが元に戻る

1. 編集ボタンを追加する

```ruby
#_task.html.haml
.task__name.d-flex.justify-content-between.mb-1
  = task.name
  = button_to '編集する', edit_project_task_path(@project), class: 'btn btn-sm btn-outline-primary'
```

1. controllerとroutesを修正してedit/updateアクションを作成

```ruby
#tasks_controller.rb
def edit
end

def update
  if @task.update(task_params)
     redirect_to project_path(@project)
  else
		# renderするときにstatusが必要なので注意
    render :edit, status: :unprocessable_entity
  end
end
```

```ruby
#routes.rb
Rails.application.routes.draw do
  resources :projects, only: %i[show new create edit update destroy] do
    resources :tasks, only: %i[create edit update]
  end
.
.
.
```

1. 差し替えるフォームを作成する

```ruby
#edit.html.haml
= render 'form'
```

```ruby
#_form.html.haml
.task__form
  = simple_form_for [@project, task] do |f|
    .row
      .col-11
        = f.input :name, label: false
      .col-1
        .d-flex.justify-content-end
          = f.button :submit, '更新する', class: 'btn btn-sm btn-primary'
```

1. パーシャルを呼び出している箇所をturbo-frame-tagで囲む

```ruby
#_task.html.haml
= turbo_frame_tag task do
  .task__name.d-flex.justify-content-between.mb-1
    = task.name
    = link_to '編集する', edit_project_task_path(@project), class: 'btn btn-sm btn-outline-primary'
  - if task.description
    .task__description
      = safe_join(task.description.split("\n"),tag(:br))
```

- 以上で完成です。railsでの実装は```turbo_frame_tag```で差し替えるviewを囲むだけなので非常に簡単ですね！
- 完成後の動き

![Videotogif (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327469/3f61ac1a-f750-8da8-def0-a3e33a95fa87.gif)


### 実装中に忘れがちなこと

- TurboFramesは差し替えるviewsをアクション名から探しにいってるので、パーシャルだけ差し替える場合もアクションがレンダリングするviewsを用意する必要があります。
【Flutter】今年触れた技術について〜riverpod〜

今回はFlutterで状態管理パッケージとして日本でとても人気なriverpodを紹介します:writing_hand:

### 環境
Mac OS:Sonoma14.1.2
Android:33
Android Studio:Android Studio Giraffe | 2022.3.1 Patch 4

## riverpod

https://pub.dev/packages/riverpod

こちらに関しては既に多くの記事が書かれています。
特に私は今年のFlutterKaigi2023で発表されたちゅーやん（中條 剛）さんの発表がおすすめです！

https://qiita.com/isekiryu/items/f1ebf59715507fafc120#%E6%88%91%E3%80%85%E3%81%AB%E3%81%AF%E3%81%AA%E3%81%9C-riverpod-%E3%81%8C%E5%BF%85%E8%A6%81%E3%81%AA%E3%81%AE%E3%81%8B---inheritedwidget-%E3%81%8B%E3%82%89%E5%A7%8B%E3%81%BE%E3%82%8B-app-state-%E7%AE%A1%E7%90%86%E6%89%8B%E6%B3%95%E3%81%AE%E8%AA%B2%E9%A1%8C

また、そのちゅーやんさんがZennでriverpodに関してのbookを作成中です。(現在：2023/12/13)
途中から有料ですが、個人的にとても気になっています！！

https://zenn.dev/chooyan/books/92a0a489f68233

では、また明日〜〜
プロジェクト工数可視化におけるTableau Tips

この記事は セゾン情報システムズ [Advent Calendar 2023](https://qiita.com/advent-calendar/2023/sisco) 14日目の記事です。

簡単なデータを使って、Tableauで可視化するための小ネタを記載していきます。

# はじめに
複数プロジェクトの工数を管理するのは大変です。また部門長視点では、各PL/PjMにやり方を任せるとチェックするのも大変だと思います。Tableauで同じVizで管理できるようになるとデータも民主化されますし、見方も統一されて素晴らしい効果が発揮されます。
今回のインプットデータはExcelを使っていますが、勤怠管理システムや会計システムと連動させれば自動化もされ、より一層高い効果が見込めます。

# 使用するデータ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982568/9f998c1c-e2d1-338d-6e40-0008858e6120.png)
非常にシンプルですが、プロジェクト工数管理に必要な日付と工数（今回は金額を想定）が入ったデータを使います。工数は実績、見込、計画の3種類です。
※12月は実績が締まっていない "実績0" を想定したデータです。

# まず最初にやること
個人的なこだわりですが、まずワークブック全体のフォントを変えます。
**メニュー > 書式設定 > ワークブック**
ワークブック全体の書式を一括で変えられます。
もちろん後でも変えられますが、最初にやることで見た目も好みになって綺麗に作れている感が出ると思います。とりあえず私の好きな「メイリオ」にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982568/e88cc2b4-3d99-a746-5d99-cddaaba174fb.png)

# 日付をFY(fiscal year)に変換する
日付を会計年度に変換します。
1. **DATEADD('year', -1, [日付])** のディメンションを作成(名称は「日付fy」とします)
1. 作成したディメンションに対して、**既定のプロパティ > 会計年度の開始** を指定

# グラフ化してみる
区分、日付、工数を使って一旦そのままグラフにしてみます。
グラフは工数積み上げをイメージしやすい棒グラフを選択。メニューの **マークラベルを表示**を選択するとラベルが出ます。個人的にラベルは不要なので消しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982568/817afcfb-cfbc-456e-6e6a-78207b635c32.png)


# 工数を累計にする
**メジャーを右クリック > 簡易表計算 > 累計** を指定します。
実績、見込、計画 すべてのメジャーに対して適用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982568/a57a470a-a578-e4f6-089a-ddbed9739097.png)

累計に変換するとラベルが勝手に長いものになるので、**別名の編集** で分かりやすい名称に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982568/cce042ee-2751-4f6f-fa20-9a71bf4ee6c2.png)

# 過去の見込を実績に置き換える
過去の見込を実績に置き換えることで、フォーキャストを正確に出します。
私は下記のやり方で実施しています。

1. 過去を示すディメンションを作成する（ディメンション名：過去）
ここはかなり無理やりな感じですが、日付が過去かどうかを判別するT/Fを用意します。
**((DATEPART('year',[日付]) < 2023) OR (DATEPART('year',[日付]) = 2023) AND (DATEPART('month',[日付]) < 12))**

1. 実績を考慮したメジャーを作成する（メジャー名：見込(実績考慮)）
**SUM(IF [過去] THEN [実績] ELSE [見込] END)**

1. グラフに反映する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982568/41c21b48-cf2b-7618-544b-d564e42419c9.png)
12月より前の見込が実績に置き換えられました。

# 予算線(可変)を入れる
予算はおおよそ固定なので、アナリティクスの定数線でも十分ですが、
複数のプロジェクトを管理したい場合や条件で予算を変更したい(予算変更前とか最新予算とか)は定数線では実現できません。
1. 予算メジャーを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982568/a756892c-cfde-beb1-e011-68774d0fe168.png)
今回は予算が1,500,000の想定で、無駄なIF文を入れて作成します。
プロジェクトが複数ある場合や予算に条件を入れてフィルタで切り替えたい場合はIF文を編集してください。
1. 一旦定数線を入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982568/50e46d7c-aa72-0e40-dcef-6d3536477e03.png)
定数線は左メニューバーのアナリティクスにあります。
1. 定数をパラメータに変更する
定数線をクリックして編集を押して、値で固定→総計(値が1つしかないので最大、最小でも同じ)を指定し、新しいパラメーターの作成をクリック(図左)。
ワークブックを開いたときの値で作成したメジャーを指定(図右)。
※パラメーター名は分かりやすい名称へ変更した方が良いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982568/f42897d4-b0c7-2b86-7b79-ebb0e7065b41.png)

あとはラベルを「予算」にして完了。
ラベルを値にしないのは、値だと線の意味が不可解になるためです。値はカーソルを合わせれば見ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982568/8eda49a8-1a77-fd1a-6a1f-0e009b37042d.png)

以上です。
ストリーミング配信やってみた

## はじめに

私が行っている業務で試験的にストリーミング配信をやってみようとなったので、S3 を使って簡易的なストリーミング配信のテストをしたので記事にしてみました。

## ストリーミング配信とは

インターネットを介した動画配信や音楽配信の方式で、データをダウンロードして視聴開始するのではなく、データを受信しながら同時に随時再生していくことができることが特徴です。

### メリット

- インターネット環境があればすぐに視聴することができる
- ストレージの空きが不要
- セキュアな配信ができる

### デメリット

- ネットが安定している必要がある

## ストリーミング再生をやってみよう

今回は AWS の S3 を使ってストリーミング再生をやってみました。
方法は非常に簡単です。
まずは input.mp4 の動画を用意してください。

そして下記のコマンドを実行します。

```
ffmpeg -i input.mp4 -codec: copy -start_number 0 -hls_time 10 -hls_list_size 0 -f hls output.m3u8
```

これを実行すると m3u8 ファイルと ts ファイルが複数生成されます。

### ffmpeg

オープンソースのマルチメディアフレームワークで、動画や音声を変換処理を行うことができるものです。
主な機能は以下のようなことができます。

- 動画や音声のデコード
- フォーマットの変換
- 動画の加工

使い方はターミナルで実行かライブラリとしてコードの中で行うこともできます。
今回はターミナルを用いて行いました。

上記のコマンドを見ると hls や m3u8 というコマンドが含まれています。

### hls とは

hls とは配信規格のことで http で動画配信を可能にするものです。
http プロトコルで動画配信することができるので、専用のサーバーを用意することがないのも特徴です。
m3u8 と ts ファイルで配信をします。

分割されたビデオファイルを短いセグメントごとにダウンロードして再生することでストリーミング再生を実現しており、オンラインビデオ配信の主要な手段としなっています。

### m3u8 とは

HLS 配信をするためのプレイリストファイルです。
これは動画を細切れに分割したファイル（ts ファイル）の URL が記録されています。
m3u8 ファイルに従って、ts ファイルを取得して再生をしています。
最初私は m3u8 ファイルがあれば再生できると思い込んでいましたが、m3u8 ファイル自体はテキストファイルになるため再生することはできません。

### あたらめてコマンドの解説

上記の説明を踏まえると ffmpeg を使って mp4 の動画を m3u8 ファイルに書き換えていることがわかります。

```
ffmpeg -i input.mp4 -codec: copy -start_number 0 -hls_time 10 -hls_list_size 0 -f hls output.m3u8
```

1. ffmpeg
   ffmpeg ライブラリを使用します。
2. -i input.mp4
   `-i`は input の略で入力したいファイルを指定しています。
3. -codec: copy
   オーディオとビデオをそのままコピーすることを意味しています。
4. -start_number 0
   HLS セグメントファイルの開始番号を 0 にしています。output0.ts から保存されるようになります。
5. -hls_time 10
   HLS セグメントの長さを 10 秒に設定します。
6. -hls_list_size 0
   プレイリストに含めれる最大のセグメント数を指定します。０は無限を意味しますので、全てのセグメントがファイルに含まれるまでを意味します。
7. -f hls
   出力フォーマットを HLS に指定します。
8. output.m3u8
   出力するファイル名を指定します。

このようにしてストリーミング再生に必要なファイルを作成します。

### ストリーミング再生用の HTML ファイルの作成

下記のようにしてコードを作成しました。src はそれぞれのコードに編集する必要がありますが、基本的には以下のコードで大丈夫です。

```html
<html>

<head>
    <title>VHS de HLS</title>
    <link href="https://vjs.zencdn.net/7.4.1/video-js.css" rel="stylesheet">
</head>

<body>
    <video-js id=example-video width=1280 height=720 class="vjs-default-skin" controls>
        <source src="https://mybakettest.s3.ap-northeast-1.amazonaws.com/output/output.m3u8"
            type="application/x-mpegURL">
    </video-js>
    <script src="https://vjs.zencdn.net/7.4.1/video.js"></script>
    <script>
        var player = videojs('example-video');
    </script>
</body>

</html>
```

## S3 にアップしよう！

AWS の登録方法はこちらの記事では割愛させていただきます。
マネコンから S3 を開いてアップロードの行います。
アップロードするファイルは先ほど作成した html ファイル（ここでは smaple.html）と ffmpeg で作成した m3u8 ファイルと ts ファイルを選択します。

![S3マネコン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991303/d50b03a4-59a6-6741-f77e-08ca53fbf8fb.png)


## S3 にアップした動画の確認
無事に動画を再生することができました！

![ストリーミング.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991303/25009136-ddbf-8f4b-b4bd-cece1b6aaa0d.png)

## 終わりに

NetflixやYoutubeなど動画サービスはよく使用する技術だったので仕組みを知ることができて嬉しかったです！また、この喜びを読んでくださった方にも伝わる嬉しいです！
機械学習エンジニアとして5年経ったのでもう一回キャリアを振り返る

# 概要
　アドベントカレンダー記事なのでゆるく書いていきたいですが、30過ぎて機械学習エンジニアになってから5年経ちました。データサイエンティストをやったりしながらもなんだかんだこの仕事を続けています。フリーランス転向したり法人作ったり身の回りの変化は大きいのですが、仕事面でも徐々にシニアエンジニアとしての役割を任せられたり、レビューする側に回ったりもしています。その辺りを今一度振り返ってみたいと思います。

# キャリアチェンジしたきっかけと当時の環境
　32歳でコードを書かない世界から機械学習の世界に飛び込んだのですが、多分に運に恵まれていたと思います。当時はAIって言葉がまだまだ一人歩きしていた時代で、理系の院卒で勉強して齧ったことがあるくらいでもワンチャン採用されました。今のようにデータサイエンティストという言葉が市民権を得ている時代の直前という感じで、AIってすごいらしいよ〜という時代でしたので、ゼロから作るディープラーニングを読んだというレベルでも採用されました。
 正直、ポートフォリオも作ってないですし、ただ運が良かっただけなので再現性は全くないですが、今となっては5年続く仕事を選べて本当に良かったと思っています。そこから派生して副業に取り組んだり、法人を作ったりなどの経験もしたので、人生の転機になったのは間違えないなと思っています。

# 5年間の経験
## 技術面
　フリーランスということもあって様々な技術を経験させてもらっています。直近はScikit-learnを使ったDeepではない予測モデルの構築ですが、大半の期間はPytorchを使ったDeepLearningでした。領域もGANやVAEの生成モデルや、画像解析、Pytorch Geometricを使ったグラフニューラルネットワーク、キャリアチェンジした当社は自然言語処理でした。かなり雑食的な機械学習エンジニアとして活動させてもらっています。
 どれが得意というのもなく、データが画像であろうと、デーブルデータであろうと、テキストであろうとそこそこやれるという感じだと思っています(裏を返すとどれもすごくない)。

 ## 業務面
 元々基幹システムをやっていた人間なので、お堅いシステムの方が得意だなぁとは感じます。人事・給与のようなバックオフィスや、売上の予測など少しレガシーな業界の業務の方が力を発揮しやすい気がします。
 また業務上の役割も徐々にレビュワーだったり、後輩のエンジニアに助言したりなどシニアエンジニアとしての立場が強くなっています。後輩のエンジニアに技術やお作法を伝えたりすることも増えて、随分と偉ぶるようになったなwと思っていたりもします。


## 副業面
　私の場合最初の雇用が正規雇用ではなかったので、何も躊躇うことなく、経験1年弱でフリーランス転向したのですが、キャリアの初期にコロナと親の死のダブルパンチで収入が途切れました。よい子は真似したらダメな動き方ですが、コロナ禍で地元でやることなくてUdemyを作ったり、それがきっかけて統計や機械学習の教育に携わらせたりもらったりもしています。法人化したのも副業が多いからというのが理由です。

# 5年間の経験を通して思うこと
　今までの経験を通じて思うのはキャリアなんて思った通りにはならないって感じています、私は新卒でERPの開発をやっていたのですが、コーディングなんてやりたくねえと思って情報システム部に転職したのですが、気がついたら機械学習エンジニアをやっています。それも、たまたま理系の院卒で数学にそこそこ明るくて、当時AIが流行り始めていて未経験者でもポテンシャルがあれば採用されたといういろんな条件が重なってからの今のキャリアです。
 　月並みな意見になるのですが、今できることをしっかりやるというのが大事なのかなぁと感じます。元々数理的な素養があったのに加えて、情報システム部にいた時も、基幹システムのデータに向き合ったりする時間が多く、データドリブンな環境にいたから今があるんだろうなと感じています。副業面もコロナ禍で身内の不幸で実家に篭ることになり、やることないからUdemy作ってリリースしたみたいなことが今の状態につながっていたりするので、そういった目の前でできることを取り組んでいることで何か開けるものがあるのかなと思います。
  少なくとも、新卒で入った会社を辞めた時に、機械学習なんて言葉知らなかったですし、手を動かさないエンジニアになったのに、そこから月日が経ってバリバリコード書いているなんて思ってもいなかったです。ただ、振り返ってみると自分のキャリアは全て繋がっていて、それは自分なりに向き合ってきた結果なんだろうなぁと感じます。

ありがとうございました！！
営業が仕様書作ってみた

# はじめに
私自身が、ベトナムに在住していて、オフショア会社に勤めております。
日本人コミュニティーのイベントに参加した際、ここなんか非効率だなと考えていた際、外付けの機能でなんか色々作れるのではと思いつき仕様書から書いてみました。

# 前提
・現在の実務は主に営業職です。なお、私が勤めている会社の手は、基本的に借りないものとする。
・勉強している言語はPythonとする。
・本来は、各ドキュメントを使うのですが、今回はこちらのサイトで記録します
・つまり自主制作です。もう一度言います自主制作です。

## 仕様書

### 1. 画面仕様
メイン画面
参加者情報の一覧が表示される。
各参加者の支払い記録、残金、通知が確認できる。
参加者情報入力画面
CSVやエクセルからのファイルアップロードボタンがあり、ファイルを選択することで参加者情報を一括で入力できる。
手動での参加者情報入力フォームが表示され、名前、連絡先などが入力できる。
### 2. 機能仕様
参加者情報の一覧表示
参加者情報が表形式で表示され、名前、支払い記録、残金、通知などが見やすく表示される。
支払いの記録
各参加者に対して支払い情報を手動で入力できる。
残金の計算
各参加者の支払い金額と実際の支払いすべき金額の差を計算し、残金を表示する。
通知機能
支払い期限が近づいた場合や、残金が残っている場合にユーザーに通知を送る。
データの保存
参加者情報、支払い記録、通知などのデータはデータベースやファイルに保存され、次回の利用に備えられる。
集計機能
飲み会の合計費用や各参加者の支払い状況を簡単に確認できる集計機能を提供する。
エクスポート機能
データをCSVや他の形式でエクスポートできる機能を実装し、必要な場合にデータを共有できるようにする。
### 3. データ構造
参加者情報
名前
連絡先
支払い記録（支払った金額、支払った日時など）
### 4. インフラ構成
フロントエンド: ユーザーインターフェースの表示
バックエンド: データ処理、通知、計算などのロジックの実行
データベース: 参加者情報、支払い記録などのデータの保存
### 5. その他
セキュリティ: ユーザーデータやイベントの情報を適切に保護するために、セキュリティ対策を実施する。
ドキュメンテーション: コードやアプリの使用方法に関するドキュメンテーションを充実させる。


## 詳細設計書
### 1. 参加者情報の一覧表示
#### 1.1 概要
参加者情報を表形式で表示する画面の詳細設計。

#### 1.2 画面レイアウト
ヘッダー: メニューへのリンクやアプリのタイトルを表示。
メインコンテンツ: 参加者情報の表を表示。
名前
支払い記録
残金
通知
#### 1.3 機能
メイン画面に参加者情報を取得し表示する機能。
参加者情報の並び替えや絞り込み機能。
#### 1.4 データ取得と表示
バックエンドから参加者情報を取得するAPIを呼び出し。
取得したデータを表形式に整形し、フロントエンドに表示。
#### 1.5 ユーザーインタラクション
テーブルヘッダーをクリックすると、該当するカラムで昇順・降順にソート。
各参加者の名前や支払い記録をクリックすると、詳細情報がモーダルで表示。
#### 1.6 エラーハンドリング
参加者情報の取得に失敗した場合、エラーメッセージを表示。
#### 1.7 パフォーマンス
大量の参加者情報にも対応できるようにページネーションを実装。
#### 1.8 テスト
単体テスト: バックエンドのAPIに対するテスト、フロントエンドのコンポーネントに対するテスト。
結合テスト: データの取得から表示までのフローに対するテスト。

# 最後に
いかがだったでしょうか。
今回は要件定義や詳細設計書を書いてみました。
実際に開発がすすんだら執筆いたしますので、お楽しみにしててください。
春から続けてきた社内での勉強会を振り返る

# 要約
- 社内で月1回程度、LT形式の勉強会を企画・開催してきた
- 大切にしてきたことは「楽しくやる」「内容の充実を図る」「継続する」
- 企画者で振り返りを実施し、聞き手（インプット側）にとっての価値を高める施策を今後のTODOとした

# はじめに
こんにちは、エンジニアの [@jnamix](https://qiita.com/jnamix) です。
今年の4月から、同僚と2人で月1回程度、LT形式の社内勉強会を企画・開催してきました。
この記事では、これらの勉強会について振り返りたいと思います。

# 実施内容
## 概要
月に1度・1時間、オンラインでのLT会という形で実施しました。
毎回テーマを決め、事前に告知した上で発表者を募りました。
当日、発表者は5分の持ち時間で、設定されたテーマに因んだ事柄について発表します。

## テーマ
実施したテーマは以下の通りです。
テーマの選定や当日の進行は、主に私と同僚の2人で担当しました。

| 月   | テーマ              |
|:----:|:------------------:|
| 4月  | テーマ自由           |
| 5月  | PHP                |
| 6月  | JavaScript/TypeScript |
| 7月  | テーマ自由           |
| 8月  | データベース         |
| 9月  | テスト               |
| 10月 | テーマ自由           |
| 11月 | AI                 |
| 12月 | クラウド（予定）      |

# 目的
## 組織の技術的な成長機会を創出する
エンジニアの技術の習得には、本人のインプットとアウトプットの両方が欠かせないと考えています。
その機会を、組織全体へ安定的に提供することで、（私も含め）各自の技術的な成長を促進するねらいがありました。
下記に示す通り、この意図は勉強会自体の設計にも反映されています。

- 業務で扱う要素技術を中心にテーマを選定
    - インプットすることで得られるメリットを大きくする
- 複数の発表者を募るLT形式を採用
    - 複数人の発表を想定し、アウトプットのチャンスを増やす
    - 持ち時間を短くし、アウトプットのハードルを低くする
- 定期的に継続して開催
    - 安定した学習・発表機会を提供する

# 大切にしていること
## 1. 楽しくやる
**楽しくやる、これが何より重要だと考えます。**
私はほとんどの回で座長を務めましたが、開催中は可能な限り気持ちの良い進行ができるよう努力をしました。

具体的には、

- 発表前後は拍手をする・求める（オンラインならボタンでも）
- 質疑応答のタイミングなどを利用して、ポジティブなフィードバックを提供する
- 質疑応答の時間を可能な限り余らせない配慮をする

といった基本的なことではありますが、準備などに時間を割いてくれた発表者それぞれにリスペクトの気持ちを持った上で、参加者全員に楽しく感じてもらえるようなやさしい場を提供できるように工夫しました。


## 2. 内容の充実を図る
参加者にとって、学びのある勉強会にできるように努力しました。基本的には、発表の質と量の両方を追求する戦略を取りました。
例えば特定のテーマを設定した場合、テーマに近い技術を業務で扱っているチームに個別で声をかけました。具体的には、

- `PHP`がテーマのとき → PHPのアプリをメインで運用しているチームへ声をかける
- `JavaScript/TypeScript`がテーマのとき → Next.jsで開発しているチームへ声をかける

というような形です。このようにすることで、より専門性や実用性の高いナレッジが広められることを期待しています。

一方で、一回あたりの発表者は多ければ多いほど良いと考えているため、テーマによる発表内容の制限を最大限に緩和しました。毎回、選定したテーマについて、その「要素」があれば発表してよいと案内しています。例えば`PHP`がテーマの場合、業務で扱っているLaravelのWebアプリから接続しているデータベースについて語る、みたいな発表もOKとしています。また、発表内容を制限しないテーマ自由の勉強会も定期的に開催することにしています。

## 3. 継続する
この勉強会を定期的に開催することは、組織の技術的成長のための「扉を開放する」状態を維持することであり、私自身それに価値があると感じています。
将来的に、この勉強会をある程度続けていくと、発表者が固定化されてしまったり、参加者が減ってしまったりと、マンネリ化を感じてしまう場面があるかもしれません。しかし、そうなったとしても開催は続けよう、ということを決めています。「扉を開放する」には、続けるしかないためです。
もし、うまくいかなくなったときは、とにかく続けることを前提として、改善策を検討したいと思っています。

# 振り返りと今後について
先日、この勉強会について企画を共にした同僚と振り返りを実施し、今後の方針について話し合いました。

## 聞き手にとっての価値を高める
これまで、勉強会の内容については、主に発表者や発表内容を中心にケアしてきました。一方で、聞き手がどう感じたかや、どのようなモチベーションで参加しているかを十分確認できていなかったところが反省点でした。
発表には聞き手が欠かせないため、彼らのフィードバックは非常に重要です。そこで、下記のようなTODOがリストアップされました。今後の勉強会の開催にあたって、取り組みたいと考えています。

- 参加者数を計測し、企画の指標としてウォッチする
- 勉強会終了後にアンケートを取り、フィードバックを得る
- テーマを募集し、勉強会の企画に反映する

# おわりに
今後も、組織の技術的成長に少しでも貢献できたらと思います。
まずは、この勉強会を継続すること。個人的には、LTのようなプレゼン形式でない勉強会にもチャレンジしてみたいと考えています。

最後まで読んでいただきありがとうございました。
【Ruby】処理の実行時間を知りたい

## 背景
・leetCodeをやっていると処理時間が表示されるので、パフォーマンス改善を意識することができる。
・ただし、submitした状況によって処理時間にブレが発生する。
・難易度が簡単なやつほど、処理が単純なのでブレが大きい。
→ ローカルでやってみるか。

## 実装（サンプル）
```ruby: sample.rb
require 'active_support'
require 'active_support/core_ext/benchmark'
result = Benchmark.ms do
  # 処理
end
puts "処理時間 #{result.ceil(2)}ms"

```
## 解説
・Rubyには標準でBenchmarkというモジュールがある。
・msメソッド（ミリ秒で表示する機能）を使うには、active_supportでbenchmark.rbが拡張されているものを使う必要がある。
・小数点以下がすごく長いので、適当な位置でceilメソッドを使用してみた。


## 参考
https://spirits.appirits.com/doruby/10326/
v0によってコンポーネント開発は加速するか

## v0とは
Vercelが提供するサービスの1つで、入力したテキストに対応したUIを提案してくれる生成AI。
プロンプトへ入力したテキストに合わせて、UIと[React](https://react.dev/) × ([shadcn ui](https://ui.shadcn.com/) or [tailwindcss](https://tailwindcss.com/))のコードを生成する

2023年12月13日現在はPrivate Beta版として機能を提供

## UIを生成する
プロンプトに「Material You Button」と、入力すると以下のような結果が得られる([生成物](https://v0.dev/r/f72pvDnrWv2))。

![スクリーンショット 2023-12-13 13.09.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591069/969a7f38-0a6d-5c9f-421f-cd655dd351cc.png)

3つのUIが提案され、Codeを押すとそれぞれのコードを確認できる。
![スクリーンショット 2023-12-13 13.10.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591069/496a8311-4877-ef2c-ef0d-fca043229c0a.png)

生成されたボタンはどちらかといえばMaterial Design2の見た目をしていている([参考](https://m3.material.io/components/buttons/overview))。
Material Design Youの見た目へ近づけるために、角丸に丸みを帯びさせたい場合には生成物に対して追加の入力が可能。
![スクリーンショット 2023-12-13 14.12.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591069/931118f3-d388-ac6b-b5f6-55e23877110b.png)

生成物に対する入力は特定の箇所に対して行うこともできる。
![スクリーンショット 2023-12-13 14.17.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591069/b3e3f707-5dd9-d213-360e-e2ba396bd0cd.png)

![スクリーンショット 2023-12-13 14.17.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591069/1b15ff8e-5c37-c5af-ce87-144827e0f85b.png)

このような生成物は基本的には公開される。`Premium`プランに加入することで、非公開に生成することができる。
![スクリーンショット 2023-12-13 14.18.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591069/48b917de-78e4-c1ef-edb8-0d545b1fd131.png)

他者の生成物は誰でも閲覧することができる。
![スクリーンショット 2023-12-13 14.21.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591069/9babc62c-8d71-2deb-96dc-9ce700c6aa13.png)

## 感想
ポジティブな感想として以下の点を抱いた。
- 集合知を元に特定機能のUIを生成できる
- 大きなコンポーネントのマークアップを任せられる
- 自分の思い描くUIへ微調整を行える

ネガティブな感想として以下の点を抱いた。
- ロジックの生成を行なってくれない
- スタイリング方法が限られている
- a11yに対する考慮は多分ない(意味論に沿った要素を配置してくれる)

今すぐ、React開発を劇的に加速させるようなツールにはならないように感じた。

現時点では以下のように使用することが多そう。
- デザインを飛ばして開発するときにUIからマークアップまでしてもらうとき
- デザインについて考える時の案を出すとき

今後、ロジックなども組み込めるように進化するとコンポーネントの開発速度が劇的に上がると感じた。
Python×ElastiCache for Redis:初心者向け簡単チュートリアル2-ハッシュ型-

## はじめに
本記事は以下の記事の続きとなります。

https://qiita.com/sergicalsix/items/b5fbd68b1a341ecebc81

:::note warn 
以下は前回記事をご覧ください。
- ライブラリのインストール
- データベースの接続
:::

今回はElastiCache for Redisでハッシュ型を扱う方法について述べます。

## ハッシュ型:Redisへの書き込み
ハッシュ型は1つのkeyに対して、複数のfieldとvalueの組を持つことができます。

基本的な書き込みは以下のように`hset`を用いて記述します。

```python 
import redis
redis_host = 'エンドポイント'
redis_port = 6379
client = redis.Redis(host=redis_host, port=redis_port,decode_responses=True, ssl=True)

key = "id1"
mapping = {"a":"1"}
client.hset(key, mapping=mapping)
```

またRedisは、int型やfloat型、Noneをそのまま保存することはできず、文字列として保存する必要があります。

```python 
def to_str(value):
    """
    int型とfloat型を識別して、型情報と共に文字列型として保存し、Noneを"null"として保存する関数
    """
    if isinstance(value, int):
        return f"int:{field_value}"
    elif isinstance(value, float):
        return f"float:{field_value}"
    elif value == None:
        return "null"
    return value
    
pre_mapping = {"a",1,"b":None}
mapping =　{field: to_str(value) for field, value in pre_mapping.items()}
client.hset(key, mapping=mapping)
```

## ハッシュ型:Redisへの読み込み
ハッシュ型の読み込みは以下のように`hgetall`を用いて行います。
前述のようにint型やfloat型の変数を文字列型から本来の型に戻す場合は、`cast_value`を使えば良いです。

```python 
def cast_value(value):
    """
    int型とfloat型のprefixを識別して本来の型にキャストし、"null"をNoneに戻す関数
    """
    if value.startswith('int:'):
        return int(value.split(':', 1)[1])
    elif value.startswith('float:'):
        return float(value.split(':', 1)[1])
    elif value == "null":
        return None
    return value
    
key = "id1"
res = client.hgetall(key)
res = {field: cast_value(value) for field, value in res.items()}
```

## おわりに
Python×ElastiCache for Redisのハッシュ型の使い方の解説は以上となります。

一旦、本アドベントカレンダーでのPython×AWSのDBの解説は以上としますが、機会があれば(1)RDSやMongoDBのプログラムを解説し、(2)速度試験を行うという記事をまとめたいと思います。


- 前回までの類似記事はこちら


https://qiita.com/sergicalsix/items/b5fbd68b1a341ecebc81

https://qiita.com/sergicalsix/items/74ac10a50aeb2cbc2bdf

https://qiita.com/sergicalsix/items/38bfed6e5fca7ac8e82e
Vue2 ⇒ Vue3への移行日記 ～方針決定編～

# はじめに
この記事は [DENSO アドベントカレンダー 2023](https://qiita.com/advent-calendar/2023) の14日目の記事です。

私は、社内でWebアプリを開発しているのですが、Rails6×Vue2で作っています。
ただ、Vue2のサポートが今年いっぱいで切れてしまうので、Vue3へ移行することになりました。
せっかくなので、移行の経緯を残しておこうと思い、筆を執っています！

# 公式ドキュメントの確認
公式の[Vue3移行ガイド](https://v3-migration.vuejs.org/ja/migration-build.html)をまずは確認。

どうやら移行ビルドなるものがあるようです。

> @vue/compat（別名「移行ビルド」）は、設定可能な Vue 2 互換の動作を提供する、Vue 3 のビルドです。
>
> 移行ビルドはデフォルトで Vue 2 モードで動作します。ほとんどの公開 API はいくつかの例外を除いて、Vue 2 とまったく同じように動作します。Vue 3 で変更または非推奨となった機能を使用すると、実行時警告が表示されます。機能の互換性はコンポーネント単位で有効化/無効化できます。

とのこと。
とりあえず、年末までに移行を完了させるのに良さげと思い移行ビルドをもう少し調べてみました。

すると、いくつか気になる点がでてきました。

# 移行ビルドを採用したときの懸念点
### 移行ビルドを使用しても移行が困難である可能性がある
公式に下記のような記載あり。
> 注意: アプリケーションが大規模で複雑な場合、移行ビルドを使用しても移行は困難である可能性が高いです。

さらに、[移行ビルドだと正常動作しないライブラリがあるという事例](https://note.com/dev_makuake/n/n0af433e5c153)も発見。

### 移行ビルドも近い将来サポートが切れそう
上記公式の注意書きの続きにこのような記述が。
> 移行用ビルドは 3.1 から提供され、3.2 のリリースラインと同時に公開され続けます。将来のマイナーバージョン（2021 年末以降）で移行用ビルドの公開を終了する予定ですので、それまでに標準ビルドへの移行を目指す必要があります。

今回移行ビルドを使ったとしても、また近い将来に通常のVue3への載せ替え作業が発生しそう。


### Vue3への直接の乗り換えはそんなに大変じゃない可能性が高そう
[OPTiM](https://tech-blog.optim.co.jp/entry/2023/10/30/100000)さんや[Makuake](https://note.com/dev_makuake/n/n0af433e5c153)さんの記事を見ると、Vue3から追加されたComposition APIではなくVue2で使われているOptions APIのままであればVue2⇒Vue3の移行はそこまで大変じゃないとのこと。

むしろ大変なのはVueとセットで使われることの多いVuetifyのバージョンアップらしいのですが、幸いなことに私たちはVuetifyは使っていない(Bootstrapを使ってます)のでこの点は問題なさそうです。

# 移行方針
上記理由より、**移行ビルドは使わずに直接Vue3へ移行**ことに決めました。但し、年末まで時間がないため、下記のような進め方にしました。

- 移行ビルドは使わない
- Options APIのままにする
- 一番最初に使用しているライブラリがVue3に対応しているか調査し、対応していない場合代替候補を探す
- 一旦差分が一番小さくなるようにVue3へ移行し、リファクタなどはバックログに積む


# 終わりに
公式ドキュメントだけ読んで移行ビルドを使おうかとも思ったのですが、もう少し調べてみると直接移行したほうが良さそうでした。やっぱりちゃんと下調べするのは大事ですね。

[次回]
[ライブラリ調査編](https://qiita.com/usk0513/items/f4d6b4f221d7cf221cd5)へと続く。
アプリのデータ保存先としてcsvファイルではなくデータベースを用いる理由

# 1. はじめに
アプリケーション開発において、一般的にデータ保存先としてRDB(Relational Database)が活用されます。この理由について、CSVファイルに保存する場合と比較して考察した内容をまとめます。

# 2. CSVファイルではなくRDBを用いる理由

## 2.1 データの構造化と整合性
データベースはテーブルとしてデータを構造化し、関連するデータを組織的に保存できます。これにより、データの整合性が向上し、データ間の関係を簡単に管理できます。CSVファイルではデータ構造を明示的に定義するのが難しく、整合性を保つことが難しいことがあります。例として、外部キー制約が挙げられます。

## 2.2 検索とクエリの効率
データベースは索引を使用してデータに高速にアクセスできるため、大規模なデータセットでも検索やクエリのパフォーマンスが向上します。CSVファイルでは全体をスキャンする必要があるため、大量のデータに対する検索が非常に遅くなる可能性があります。

## 2.3 トランザクション管理
データベースはトランザクションをサポートし、データの一貫性を保つために変更を管理できます。これにより、データの不整合やエラーが発生しにくくなります。CSVファイルではトランザクションの管理が難しく、データの安全性が低くなります。

## 2.4 同時アクセスと複数ユーザー対応
データベースは同時に複数のユーザーがアクセスでき、データの競合を避けるための仕組みを提供します。CSVファイルでは同時に書き込むとデータが壊れる可能性があります。

## 2.5 データのバックアップと復旧
データベースは定期的なバックアップと復旧機能を提供し、データの喪失を最小限に抑えます。CSVファイルでは手動でのバックアップが必要であり、データの復旧が難しいことがあります。

## 2.6 セキュリティ
データベースはアクセス制御や権限管理を通じてセキュリティを向上させることができます。CSVファイルではアクセスコントロールが限定的であり、データが不正に変更される危険性が高まります。

# おわりに
これらの考察から、特に大規模かつ複雑なデータセットを扱う場合や、データの一貫性とセキュリティが重要な場合には、データベースを使用することが一般的であることがわかりました。
その1

WPFとMVVMパターン
ReactiveProperty
自作クラスのリストをバインド
テキストとレクタングルを縦に並べる
それを4つ表示する

まず、自作クラス `CustomItem` を定義します。

```csharp
using System.Windows.Media;

namespace YourNamespace
{
    public class CustomItem
    {
        public string Text { get; set; }
        public Brush Color { get; set; }
    }
}
```

次に、ViewModelを作成します。

```csharp
using System.Collections.ObjectModel;
using Reactive.Bindings;

namespace YourNamespace
{
    public class MainViewModel
    {
        public ReactiveCollection<CustomItem> Items { get; } = new ReactiveCollection<CustomItem>();

        public MainViewModel()
        {
            // 仮のデータを追加
            for (int i = 0; i < 4; i++)
            {
                Items.Add(new CustomItem
                {
                    Text = $"Item {i + 1}",
                    Color = i % 2 == 0 ? Brushes.Blue : Brushes.Red
                });
            }
        }
    }
}
```

そして、MainWindow.xamlでこれらをバインドします。

```xaml
<Window x:Class="YourNamespace.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:YourNamespace"
        mc:Ignorable="d"
        Title="MVVM ReactiveProperty Example" Height="300" Width="300">

    <Grid>
        <ItemsControl ItemsSource="{Binding Items}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Text}" HorizontalAlignment="Center"/>
                        <Rectangle Width="50" Height="50" Fill="{Binding Color}" Margin="5"/>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>
```

最後に、MainWindow.xaml.csでViewModelをデータコンテキストに設定します。

このコードでは、`ItemsControl`を使用して `Items` プロパティにバインドし、`ItemTemplate`内で`StackPanel`を使用してテキストとレクタングルを縦に配置しています。
kubernetesのtaintと和解したい

## スケジュールとは
あるNodeにPodを割り当てること

## Taintとは
ある条件を満たさないとPodをスケジュールさせないようにする機能。想定しないPodの作成を防ぐ。
Taintは`key`,`value`,`effect`の3つの要素からなる。マニュフェストファイルに記入されている`key`と`value`が一致しない場合、`effect`が発揮される（Podがスケジュールされないなど）

## NodeにTaintを設定する方法
`node01`に、`app`というキーの値が`batch`じゃないとスケジュールしませんよ〜（=`NoSchedule`という効果が発揮されますよ〜）というTaintを設定する例

```bash
$ kubectl taint node node01 app=batch:NoSchedule
```

ここに以下のようなyamlファイルで`pod01`というPodを作成しようとする
```yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod01
spec:
  containers:
  - image: nginx
    name: pod01
```
```bash
$ kubectl create -f pod01.yaml
```
ステータスを見ると`pending`になる
```bash
$ kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
pod01   1/1     Pending   0          4s
```
taintをちゃんと設定する
```yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod01
spec:
  containers:
  - image: nginx
    name: pod01
  tolerations:
  - key: "app"
    operator: "Equal"
    value: "batch"
    effect: "NoSchedule"
```
`Running`になる
```bash
$ kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
pod01   1/1     Running   0          4s
```
ChatGPTを用いた映画字幕への語注作成

## はじめに
こんにちは、GlobeeでCTOをやっています上赤です。
[Globee Advent Calendar](https://qiita.com/advent-calendar/2023/globee)10日目の記事です。

弊社では様々な業務領域でChatGPTを活用していますが、今回は映画字幕への語注作成サポートに活用した際の記録を残します。

## 前提
弊社が作っているサービス[abceed](https://www.abceed.com/)では、**映画を使った英語学習**を行うことが出来ます。どんな学習ができるのかに興味がある方は、[こちら](https://note.com/globee/n/ne81dc1b60ccb)の記事に詳細ありますので、是非御覧ください。

さて、映画を英語教材として活用するためには、映画のフレーズごとの秒数調整/語注解説作成/直訳作成など、様々な作業が必要です。

そのような作業は弊社オリジナルコンテンツチームが行っているのですが、正直かなり**負荷が大きい作業**です。作業を進めていく中で、ChatGPTを使ってオリジナルコンテンツチームの負荷が減らせないものか？と考え、挑戦してみることにしました。

なお、弊社オリジナルコンテンツチームの構成/業務内容については、[こちら](https://note.com/globee/n/n56d5ca46a56b)の記事にまとまっていますので、もし興味がある方は合わせてご覧ください。ネイティブと日本人が協力して質の高いコンテンツを作り上げる、非常に面白いチームです。

## やりたいこと
映画コンテンツをより学習しやすくするために、映画内の各フレーズに対して1つ1つ語注を付ける必要があります。
![1700401325215-U2CLBK2V5N (3).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49019/a5b5afd0-d48c-ab2d-990f-05d559ee9aaf.jpeg)

当初はそれを一つ一つゼロから作っていたのですが、**ChatGPTによって各フレーズの語注の候補を提案し、それを人の手で修正及び追記する**方針にすれば作業速度を上げることが出来るのでは？という発想に至りました。

## やったこと
最初は、以下のような単純なプロンプトを使って各フレーズの語注を生成していたのですが、オリジナルコンテンツチームから
* 簡単すぎる単語が語注に含まれており、削除する手間がかかる
* フォーマットが統一されていない
* 語注の内容が間違っていることが多い
などの問題で、作業がそこまで効率化されないというFBがありました。

### 当初使っていたプロンプト例
```
こちらは、ある映画・ドラマ{filmname}のセリフです。

例に従って、質問のセリフの中に、単語と文法を3〜7個までできるだけ多く選んで、例と同じフォーマットで語注を作成してください。

例：
セリフ：a band of brave heroes brought us back.
答え：
■ a band of 【限定】〜の集団、〜たち
■ bring back 【動】〜を連れ戻す

問：
セリフ：{dialog}
答え：
```

### 最終的な処理フロー
その後、様々な試行錯誤を経て、以下のようなフローに落ち着きました。

![Untitled (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49019/3c7d8eaa-6c1b-d2c3-d837-d20a95686042.png)

このフローを全て説明すると長くなりすぎてしまうので、かなり簡略化して説明します。

まず、
* 映画のフレーズに対して完全に自由に語注を生成させるプロンプト1
* 過去に採用した語注のデータベースを元に、対象単語を指定して語注を生成させるプロンプト2
を用意します。

2つのプロンプトによって作成された語注をマージし、更にそれに対して、該当単語で過去に採用した語注のリストを加え、**語注の候補リスト**を作成します。

次に、作成した語注の候補リストを、
* フレーズと語注の候補リストを元に、そのフレーズにおいて最も適切であると思う語注を選択するプロンプト3
に与え、語注の最終候補を取得します。

#### プロンプト3の例
```
以下の英語単語あるいは文法の説明のうち、一番文脈に合っているのはどちらですか？

例：
文章：You must release that handle!
説明：
A【動】：〜に対処する	
B【動】：〜を扱う	
C【句動】：〜を扱う、〜に対処する	
D【動】：〜を対処する	
E【動】：〜に対応する、〜に対処する	
F【動】：(問題など) に対処する	
G【名】：ハンドル 

答え：G

問題：
文章：{phrase}
説明：
{option}

答え：＿（選択肢のみ）
```

最後に、取得した語注の最終候補に対し、手動のロジックでフォーマットの調整及び簡単すぎる単語の除外を行い、最終結果とします。

このフローによって、当初課題だった以下の点は大きく改善され、オリジナルコンテンツチームの作業時間削減に貢献することが出来ました！
* 簡単すぎる単語が語注に含まれており、削除する手間がかかる
* フォーマットが統一されていない
* 語注の内容が間違っていることが多い

## まとめ
当初の想定よりもかなり複雑なフローになってしまいましたが、複数のプロンプトとロジックを組み合わせたフローにすることで、単発プロンプトよりもかなり高い効果を得ることが出来ました。
今後も様々な領域でChatGPTを活用し、業務改善をしていけたらと思います。

弊社では、現在アプリ/Web/サーバーエンジニア/PjMなど、ほぼすべての開発ポジションを募集中です！
ちょっとでも興味持った人は以下からカジュアル面談をご検討ください。色々お話します！
[採用ページ](https://globee.notion.site/Globee-d184eefc3561480292481299c64b04bc)
matplotlibで日本語を使う方法（GoogleClab）

# 記事概要
matplotlibで日本語を使う方法（GoogleClab）。  
何もしないとタイトルや軸ラベルが文字化けする。

# 方法
japanize_matplotlibをインストールして、
```
!pip install japanize_matplotlib
```
日本語フォントを読み込ませる。
```python
import matplotlib.pyplot as plt
import japanize_matplotlib
plt.rcParams['font.family'] = 'IPAexGothic'
```

# 参考
<a href="https://azusa.shinshu-u.ac.jp/~hasegawa/class/programming/index.php?Python/matplotlib%E3%81%A7%E6%97%A5%E6%9C%AC%E8%AA%9E%E6%96%87%E5%AD%97%E5%88%97%E3%82%92%E4%BD%BF%E3%81%86" target="_blank">matplotlibで日本語文字列を使う</a>
リモートワークの悩みに響いた「世界一流エンジニアの思考法」

# はじめに
リモートワークの働き方に悩んでいたんですが、[世界一流エンジニアの思考法](https://amzn.asia/d/6iN0FAg)という書籍を読んだら色々と響くものがあったのでまとめてみます。

# 書籍の概要
著者の牛尾剛さんはMicrosoftでシニアソフトウェアエンジニアとして活躍されている方です。
本書は牛尾さんが同じチームの一流エンジニアから学んだ思考法（マインドセット）が数多くまとめられています。

# リモートワークの悩みに響いた内容

1\. クイックコールのすすめ
2\. 「気軽に聞ける仕組み」は「気軽に断れる空気」とセットになっている
3\. 意見が対立しても「否定しない」

順番に触れていきます。

## 1\. クイックコールのすすめ

対面よりもコミュニケーションが取りづらいリモートワークにおいて生産性を上げるためにはクイックコールを積極的に活用するといいそうです。

クイックコールとは予定されていないビデオ通話のことで、
「今ちょっといい？」って聞かれてOKだったら「いいよ！」とビデオ通話を始めることです。

こんな気軽に声を掛けられたらいいなと思いました。
リモートワークだと相手の様子もわからないしホント声を掛けづらいんですよね。

質問したいときも、声を掛ける前にあーだこーだ悩んでしまって無駄な時間を掛けてしまうことがよくあります。
もっと気軽にクイックコールして、悩む時間を減らしていかなければと思いました。

一方で、「今ちょっといい？」だけだと言葉足らずかなという思いもあります。

「今ちょっといい？」では用件が全くわからないので逆に断りづらいんですよね。

「◯◯で躓いていて、ちょっとアドバイスもらっても良い？」くらいの一言を足すとよりいいのではないかと思いました。

## 2\. 「気軽に聞ける仕組み」は「気軽に断れる空気」とセット

リモートワークにおいて声の掛けやすさは重要ですが、
いざ声を掛けようとすると「今は忙しいかな」「迷惑にならないかな」とあれこれ考えてしいます。

この声の掛けづらさの原因は「気軽に断れない空気」のせいもあると気付きました。

忙しかったら断ってもらえればいいと考えれば、声を掛けるハードルも大きく下がりそうです。

そういえば、ジュニアの方に「もっと早く質問してくれればいいのに」と思うことがあるんですが、自分が気軽に聞ける空気を作れていなかったなと反省しました。

まずは自分から気軽に聞く＆気軽に断ることで良い空気を作っていきたいです。

## 3\. 意見が対立しても「否定しない」

人と関わる上で意見が対立することは決して避けられませんが、
相手を尊重した伝え方をすることが大切なのだと学びました。

反対意見も「そんな考えはおかしいよ」と伝えるよりも
「僕の意見は君と違ってこうなんだ」と伝える方が何倍もいいですね。

リモートワークだと相手の顔が見えない（常にビデオはOff）ので、表情で伝えられない分、言い方による影響は大きいのだと思います。

# 最後に
リモートワークでの悩みは環境要因が大きいと思って諦めていましたが、マインドを変えるだけで改善できることに気付けました。
早速明日から実践していきたいと思います。
ここまで読んでいただきありがとうございました。
【DDIA 読破】監訳者まえがき

この記事は、[気合いで DDIA 読破 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/ddia) 1日目の記事です。

# この連載の目的

この連載は、 @ebi_yade がオライリー・ジャパンから出版された「データ指向アプリケーションデザイン」を 2023年12月中に読破することを目標として、その読書メモを公開する企画です。

https://amzn.asia/d/hcsP75P

なお、事情から着手が遅れまして、1日目の記事を書いているのは12月13日となっております。

すでにお尻に火がついていますが、やっていきます。

# なぜ今この本を読むのか

実は、初日の記事を「監訳者まえがき」に割いた理由は、読み進んでいなかったからではありません。[^1]

この本を実際に買うきっかけが、監訳者の斉藤 太郎さんが今年登壇していらっしゃったイベントでの公演だったからです。

https://www.youtube.com/live/ZiKWXc0fSCw?si=7EwAzJ_JwE4NRBTO

もちろん DDIA の存在自体は昔から存じ上げておりましたが、とにかく聖書のような分厚い本と認識しており、なかなか手を出せずにいました。

しかし、斉藤さんの理路整然とした語り口や、なにより羅針盤を与えてくれるような公演内容に後押しされて、この本を購入することに至りました。

とはいえ実際に届いてみると「やっぱり分厚いなぁ」といった印象で、年末まで放置してしまったので、この連載企画を立ち上げることにしました。

以降の読書メモでは、ぼちぼちフランクな言葉遣いを致しますが、これはあくまで私の個人的な読書メモですのでご容赦ください。

# 読書メモ: 監訳者まえがき

クラウドの普及によって分散処理を行うためのインフラが手頃になったし、そもそも CPU の性能向上が遅くなってきた以上は分散処理が必要不可欠だよね、という話から始まります。

しかしながら分散処理と言っても複数の専門性に分類され、相対的な位置付けや共通理解を作ることが難しい分野であることを指摘しています。

これにより、エクストリーム賢人ゴリマッチョ以外の人が分野全体を概観するのは厳しいようです。

そこで、包括的な教科書的存在として君臨することが、本書の存在意義とのことです。

ところで、実は以下の記述の最後の一文が、誰に対してのメッセージなのかピンと来ませんでした。

> 対象とする読者は、エンジニアや研究者はもちろん、データを扱って仕事をするデータサイエンティストや、Web サービスを構築してビジネスを起こす人なども含まれます。データがシステムの裏側でどのように処理されるかを知っていることはデータに基づいた決断への自信にもつながります。生物学でもシーケシング技術の急激な発展により、ゲノム情報という大規模データを突然手にしたため、エンジニア以外でも使えるデータ処理の基盤を整えることが急務になっています。

もちろん間違ったことを言っているようには聞こえませんし、自分が生物学を取り扱う領域に詳しくないことが影響している節はありそうです。

とはいえ、生物学を例に出しているだけで、「どんな領域でもブレイクスルーが起きたら同じような変化が起こりうるよ」という含みは感じ取れます。

その上で、エンジニアに向けて「基盤を作るときに役立つよ」と言っているのか、対象読者として挙げたデータサイエンティストについて例示しているのか、確信が持てませんでした。

もしかしたら、「データサイエンティストとエンジニアの境界線は強く意識しないぐらいが理想的」ということなのかもしれません。

# 【宣伝】会社のアドベントカレンダー

私が働いている[面白法人カヤック](https://www.kayac.com/)でも、Qiita のアドベントカレンダー企画をやっています。

Qiita に投稿している記事は会社と直接関係ありませんが、企画の運営をしているのは私です。

どんどん面白い記事が投稿されていますので、ぜひご覧ください！

https://qiita.com/advent-calendar/2023/kayac-group

# 修正リクエストを受け付けています

この記事は GitHub で管理しています。以下のリポジトリに Pull Request を送っていただければ、記事内容の修正を検討いたします。（コメント欄に書いていただいても構いません。）

https://github.com/ebi-yade/qiita/blob/main/public/ddia-2023-day01.md

[^1]: 実際、現時点であまり読み進んでいないのは事実ですが......。
C# LINQ 最大値・最小値・合計値などを算出する

# 備忘録

LINQには最大値・最小値・合計値などを算出する便利な機能があるが、標準偏差を求めるメソッドがない。

# サンプルコード

```cs            
List<double> doubles = new List<double> { 3.2, 3.5, 3.6, 4 };

//最大値
double max = doubles.Max();

//最小値
double min = doubles.Min();

//合計値
double sum = doubles.Sum();

//平均値
double mean = doubles.Average();

//分散 = 自乗和 / 要素数 - 平均値^2
double variance = doubles.Select(x => Math.Pow(x - mean, 2)).Average();

//標準偏差 = 分散の平方根
double stdDev = Math.Sqrt(variance);

//最頻値
double mode = doubles.GroupBy(x => x) // 各要素の出現回数をカウントする
	.OrderByDescending(g => g.Count()) // 出現回数が最大の要素を取得する
	.Select(g => g.Key) // 最頻値を取得する
	.First();

//中央値
double median = doubles.OrderBy(x => x).ElementAt(doubles.Count / 2);
```

# 参考ページ

https://qiita.com/c60evaporator/items/59ad0dbebc53c742a4c9

https://qiita.com/mori95y/items/9948cea172e90dfd6847