OmniAICreator/Qiita-1.07M huggingface dataset:
2024 情シス関係でかかわったもの振り返り

# これは何
- 2024年でかかわったプロジェクト・個人活動にて情シス関連で使える業務や技術の備忘録
- 振り返ってベンチマークを知るため（今自分のできる技術を客観的に振り返るため）
- 構成は月単位でどれぐらい期間がかかったかもスピードや社内調整にかかった時間を確認して来年につなげる

# 月単位での振り返り

## 1月
- メール移行の社内調整（サービス選定と稟議は昨年の10月から12月で実施）
- JamfProを用いた社用携帯の移行（約90名）

https://www.jamf.com/ja/

## 2月
- メール移行の技術部分の最終調整
    - SPF・DKIM・DMARK・DNS・旧メールサーバーと紐づいているシステム関係移行手順書作成
    - 新しいツールやアドレス帳の移行準備

## 3月
- メール移行本番
    - メール移行後の運用フォロー対応

## 4月
- メール移行後の不具合修正を開発会社と連携して対応
    - 主にios版のバグ収集とそれに対する回避策フォロー
- Jamf Proを用いた社用携帯の移行（約20名）

## 5月
- Cortexを用いたセキュリティバージョンアップトラブル対応
- SKYSEAを用いたセキュリティパッチ（Cortexインストール修正のバッチ）を配布

 https://www.paloaltonetworks.jp/cortex

 https://www.skyseaclientview.net/

## 6月
- ChatGPT（Teams）を検証導入
    - 運用・使い方・社内規定・利用者マニュアル作成

 https://openai.com/ja-JP/

## 7月
- ネットワーク解析ツール検証
    - ntopng
    - nProbe
- Google Api 
    - 発行・契約・料金管理
- GCP管理

 https://www.ntop.org/products/traffic-analysis/ntop/

 https://console.cloud.google.com/marketplace?hl=ja&inv=1&invt=AblmEA

  https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy?hl=ja

## 8月
- LineBotの検証
    - GAS
    - Bizrobo（RPA連携）
- au回線の電波障害対策
    - レピーターの設置
    
 https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy?hl=ja

 https://developers.line.biz/ja/docs/messaging-api/building-bot/

 https://developers.google.com/apps-script?hl=ja

 https://rpa-technologies.com/

 https://www.au.com/mobile/area/dennpa-support/repeater/

 ## 9月
 - Azure多要素認証を社内運用を加味して変更
     - 「Microsoft Authenticator」は携帯紛失時にとても手間なので無し
     - 携帯紛失時にモバイル会社と連携して対応ができる「SMS認証」で統一
 - JamfPro・Apple Business Manager・MDM（iPadは別サービスでiPhoneはJamf Proで管理）
     - 年一のアクセストークン更新

https://learn.microsoft.com/ja-jp/entra/identity/authentication/tutorial-enable-azure-mfa

https://business.apple.com/

## 10月
- Instagram：ビジネス用アカウント発行
    - 運用・使い方・社内規定・利用者マニュアル作成
- ネットワーク解析ツール本社運用開始
    - ntopng
    - YAMAHAルーター
        - ミラーポート設定

https://network.yamaha.com/products/routers

## 11月
- ネットワーク解析ツール支社運用開始
    - nProbe
        - Hyper-V
        - 仮想環境でLinux（Ubuntu）で構築＆運用開始
    - YAMAHAルーター
        - ミラーポート設定

https://learn.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v

## 12月
- Bizrobo
    - マスターサーバーをWindows11で構築
        - 製品動作安定稼働のため
- Google Workspace
    - 管轄外のアカウント精査＆移行

https://support.google.com/a/answer/11112794?hl=ja

# 振り返った感想
- 端末管理やアカウント管理は、今の会社の運用に合わせたやり方がちょっとだけ分かった
- ネットワーク関係は、解析の結果様々な要因で遅くなったりするので、解析のやり方をもっと調べないと思った
    - 「tcpdump」とか見て生のデータ解析もできるようにしていく必要あり

# 来年に向けて
- ネットワーク環境に関しては、スムーズなネット環境がすべての業務かかわるため、回線速度の改善を務める
    - 特にハブ機器周りが古い物があるので、予算確保して交換をしていく
- 帯域の問題もあるので「帯域保証（ギャランティ）型」と「ベストエフォート型」を本社と支社を選定して、整備していく

https://www.gate02.ne.jp/media/it/column_71/#%E3%83%99%E3%82%B9%E3%83%88%E3%82%A8%E3%83%95%E3%82%A9%E3%83%BC%E3%83%88%E5%9E%8B%E3%81%A8%E3%81%AF%EF%BC%9F

# 余談
個人的な活動で行っている「教育版マインクラフト」のアカウント管理が「Microsoft Entra 管理センター」で管理されているので、「多要素認証」を変更する経験を活かせたのは非常に助かりました。
「法人版のMicrosoftアカウント管理」と「個人（ボランティア活動）でのMicrosoftアカウント管理」のいい感じの管理のしかたは、これからのアップデートに合わせて変更をしていく必要がありますね。

https://education.minecraft.net/ja-jp

https://learn.microsoft.com/ja-jp/entra/fundamentals/entra-admin-center

では皆様よいお年を！！
工数管理は何に役立つの？TimeTrackerNXで検証してみた！

# はじめに
今回はメンバー目線から見た工数管理について書いていこうと思います。

* 工数管理をしているけど、ただやっているだけ
* 上長から頼まれてやっているけど何に役立つのかわからない
* 会社のためにやっている

など、なあなあにしていたり目的が明確でないまま工数管理をしていませんか？

ぜひ管理職の方にも拝読いただければと思います！

# あなたのイメージする工数管理は？
工数管理と聞いて、何をイメージしますか？

私は工数管理を始めたころ、上司や管理職のためのツールだと考えていました。

しかし、視点を変えることで自身の成長に大きく繋げることができます。

# TimeTrackerNXを利用して考えてみる
そこで今回はTimeTrackerNXというアプリケーションを使ってみようと思います。

:::note info
TimeTrackerNXとは
ソフトウェア開発、ハード設計、営業、Web制作などの知識労働・デスクワーク業務における工数管理・プロジェクト管理のためのツールです。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924373/66f0226d-d0fd-010c-9882-714ceb0a7ec1.png)

株式会社デンソークリエイトさまがオンプレ版を提供しており、
グローバル・アスピレーションズ株式会社さまがクラウド版を提供しています。

工数管理を自身に活用する方法についてフォーカスしていきます。

# １日に何をしているか言えますか？
担当のプロジェクトやその日のタスクは決まっているかもしれませんが、
意外と何をしたのかまでは言えないと思います。

TimeTrackerNXでは工数入力をより詳細に行うことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924373/4ea8cc05-6dd9-0289-6545-34f2d562b107.png)

入力単位が５分から設定できるため、様々なタスクを同時進行で行っているユーザーなど
こだわりを反映させることが可能です。

工数入力を以下のように登録することで、自分が１日に何をしたのか
どれほど時間をかけたのか、可視化することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924373/218cf76b-7a26-966c-a604-e314e2fb2022.png)

:::note info
入力したタスクにはメモ書きが登録できます
:::

**時間ベースで記入することで、自分の時間配分をより意識しやすくなります。**

# 集計で上司との1on1に
TimeTrackerNXはデータの分析に非常に長けています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924373/d70ca2ac-ef67-6754-d530-4b342f28957a.png)

クイックレポート機能で**どのプロジェクト**に**どれほど時間をかけたのか**
一目で確認することができます。

Excelや他ツールでわざわざ資料を作成する必要が無いので便利です。
工数入力の状況で円グラフの割合も変化するので、まさにリアルタイムの状況を
上司やメンバーに報告することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924373/f8a9558a-de62-d91a-e4a1-01c84cbb3328.png)

リソースプランナーという機能では各メンバーのタスクや負荷状況まで確認することが
できるので、タスクのひっ迫状況を説明するのにも役立てられそうです。

TimeTrackerNXでは**プロジェクトに関わる全ての人が主体となって
現場の改善につながる機能**がとても多いですね。

# 終わりに
１日に自分は何をしているのか。を意識することで残業やタスクの遅れ改善につながると
私は工数管理を続けて大きく感じました。
考えることは簡単でも、このようなツールを実際に利用することが大事だと
より実感します。

また、新入社員が入社した際にはOJTに工数入力を適用し、
プログラムの改修にも役立てられそうだなと感じました。

TimeTrackerNXはその要望に一番近く、叶えてくれるツールだと思います。
ぜひ、利用してみてください。

気になった方は以下ページよりご確認ください！:relaxed:

**[TimeTrackerNX(デンソークリエイト様ページ)](https://www.timetracker.jp/ "TimeTrackerNX")**

**[グローバル・アスピレーションズ様ページ](https://www.global-asp.co.jp/"TimeTrackerNX")**
VIVE リストトラッカーを用いてVRChatの指トラッキングでトリガーを楽にする

VIVE系のハンドトラッキング設定はこちら
「追加￥０でハンドトラッキングして指をワキワキ動かそう VIVE＆VRChat編」
https://qiita.com/mhoohmjwAsiya/items/83f05bcd929edb8b2007

　
**VIVE リストトラッカーとは**
 
VIVE リストトラッカーはVIVE Focus3と共に発売されたハンドトラッキング専用コントローラーです。
名前はトラッカーですがコントローラーとして認識されるので既存のコントローラーとの併用はできませんです。ハンドトラッキングに全振りしたニッチな製品ですね。
ニッチ過ぎて現在（2024年12月）は処分価格で売り切りされています。生産中止でしょうね...残念。
 
![PXL_20241229_023909143.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/6ffb6574-25d8-f22f-91b4-553c8744de61.jpeg)
 
 
**VIVE リストトラッカーのボタン**
 
コントローラーなのでｗ 申し訳程度にボタンがあります。今回はこれを利用してレーザーでポイントした後のトリガを代替します。
ハンドトラッキングで慣れても難しいのはレーザーでのポインティングとポインティングしたもののトリガです（個人の見解）
なかでもトリガが一番むずいです。この記事ではこれを解決します。
 
 
ボタンはシステムボタン（左右）と、Ｙキー（左手）、Ｂキー（右手）があります。

![1280-リストトラッカーのキー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/9a38119f-c48e-94fa-78ca-0f12ba2416e5.jpeg)
 
 
 
**キーバインドの編集**
 
今回は左手のYキーにトリガを割り当てます。

１）VRChatを起動する。
VRChatを起動した状態でキーバインドを編集します。

2)SteamVRのメニュー
三本線-->デバイス-->コントローラの設定
を開きます。
![SteamVRからのメニューの出し方.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/6ce86f16-13af-d41a-cadd-9494ac8bf20e.png)

3)SteamVR設定のメニュー
コントローラ-->バインド設定UIを表示
を開きます。
![メニュー バインドUIを表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/faaec18d-46e5-2387-905c-8c26f91c6a5d.png)

4)VRChatを選ぶ
常日頃遊んでいるゲーム類が出てきますのでVRChatを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/22772c36-f2b8-89ea-8f0c-e6bc0e3cd9f1.png)

5)キーバインドが表示される
![バインド画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/b6cdb48e-eaa1-0b5e-54b4-8ac0ec2e93b2.png)

左手Yキーの設定
以下のようにします。
![Yボタンバインド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/f0988b6e-9cbd-83fc-8b82-16ec42649745.png)

7)編集後に
”個人用バインドを保存”ボタンを押し分かりやすい名前（ここでは「TRIGER用に保存されたVRCHATの設定」）で保存します。

　
　
**完了**

これでリストトラッカーの左のキーを押すとトリガを握ったのと同じ動作を行えます。動画はリストトラッカーを付けてハンドトラッキングしながらYキーを押してトリガしてるものです。通常のコントローラと同じくスムーズにトリガできていると思います。

<iframe width="560" height="315" src="https://www.youtube.com/embed/tNVTZzjN30U?si=2dWC-5mf9pyaMhdK" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>



**問題点**

レーザーを当ててもポインティング（ボタンの色が白っぽくなる）されないことがあります。ポインティングされないとトリガも効かないのですが、これがどの状態でなぜ起こるかまだ究明できていません。
まだまだ調べますのでおまちくだいね。


**20241231 23:35 追記**

これで解決したかもしれません。確認中。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/0f8d2b2e-fa34-856c-68a1-3fe6a1314724.png)


**20250101 20:58 追記**

 上記修正でポインティングされるようになりました。

<iframe width="560" height="315" src="https://www.youtube.com/embed/PpG8iCsOnfI?si=TFam4N_q9KWy2slS" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
Rust+LLVMでコンパイラを作る：#6 エラー表示の整備

## 本連載のバックナンバー
 * [#1: 環境構築](https://qiita.com/_53a/items/de260505610256a00dbe)
 * [#2: 概要と方針](https://qiita.com/_53a/items/304f1562b3aa0cad616d)
 * [#3: 大枠づくり](https://qiita.com/_53a/items/d7d4e4fc250bfd945d9e)
 * [#4: 電卓づくり](https://qiita.com/_53a/items/843b7fa8328523c115cf)
 * [#5: ファイルの分割と単体テスト](https://qiita.com/_53a/items/bde614986696a9bddd23)
 * [#6: エラー表示の整備](https://qiita.com/_53a/items/5128dda042f38a893b73)

## はじめに
この連載も1年ぶりになってしまいました。
今回はリポジトリのメンテナンスも兼ねて、ちょっとした作業を行っておきます。
具体的には、今まではエラーを扱うために、定番である `anyhow` を使用していましたが、将来を考えて [miette](https://github.com/zkat/miette)というライブラリへの差し替えを行います。

`miette` は `thiserror` や `anyhow` との高い互換性があり、かつ美しくユーザフレンドリなエラー表示を行ってくれるライブラリです。

その前にまずは恒例となった、リポジトリが使用するLLVMの更新を行いましょう。

### （ほぼ）最新のLLVMへのアップデート


2024-12-31現在、LLVMは19が最新版ですが、使用しているLLVMラッパーであるinkwellが未サポートです。

LLVM19をサポートする[PR](https://github.com/TheDan64/inkwell/pull/557)が送られてはいるので、これがマージされるまではLLVM18を使用することにしましょう。

`Cargo.toml` の `inkewll` の行を以下のように変更します。

```toml
inkwell = { version = "0.5.0", features = ["llvm18-0"] }
```
また、LLVMのバージョンを上げたことにより、deprecation warningが発生しています。その対応として`codegen.rs` の 56行目の `.i8_type()` を行ごと消しておきます。

これが終わったら `miette` の追加です。

### `miette` の追加

`miette` は `anyhow` との高い互換性を維持しており、機械的な置き換えと多少の修正だけで `anyhow` からの乗り換えが完了します。

まず `Cargo.toml` の `anyhow` の行を消し、その代わりに以下の行を追加します。

```toml
miette = { version = "7.4.0", features = ["fancy"] }
```

また、すべてのコードの

```rust
use anyhow::{anyhow, Result};
```

という行（`anyhow`と`Result`が逆になっているところもあるかもしれません）を

```rust
use miette::{miette, Result, IntoDiagnostic};
```

に書き換えます。

次に、コード中の `anyhow` という文字列を `miette` という文字列に一括置換します。そして最後に、エディタ上でエラーになっている `?` を `.into_diagnostic()?` で置き換えるだけで、とりあえずの乗り替えが完了します。

## 終わりに

今回は久々ということで、リポジトリのメンテナンスだけに終始してしまいました。
次回以降で気が向いたら、エラー箇所の表示やそのための各　`Node` のコード上での位置の保存など、この `miette` の長所を生かすような変更をいれたいと思います。
サーボホーンを3Dプリント

サーボモータのサーボホーンを3Dプリンタで印刷できたら楽しいですよね。やってみましょう。

# サーボホーンとは

SG90などのサーボモータについているこれです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/e5ca409d-477f-201d-448c-32ca7fa902d3.png)

サーボモータの軸はギザギザになっていて、そこにはめて回転させます。
このギザギザの寸法がとてもシビアなのですが、もし3Dプリンタで作れたらいろんなものに組み込むのが楽になると思います。

# 正規品の寸法

こちらに測った人の記録がのっています。

https://community.robotshop.com/blog/show/modelling-a-servo-spline

外形4.9mm、内径4.4mmの円上に21個のギザギザを作っているようです。
当然この寸法通りにやってもはまるわけがありません。（超高性能な3Dプリンタならはまるかも？）

なので自分の3Dプリンタでうまく印刷できるように試行錯誤を重ねましょう。

# 3Dモデルを作る
外形を5.2、内径を4.2ぐらいで作り始めるといい気がします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/92351f53-7bf5-576d-55d3-56262b6e4ac3.png)
歯の数は21個です。Fusionの円形配置機能などを使うと楽に作れると思います。

設計して印刷し、大きかったら小さくして、小さかったら大きくしてというのを繰り返しましょう。

私は何度も印刷しなおすのが面倒なうえ、どれが大きかったのか小さかったのかが分からなくなってきたので一気にまとめて25個の穴を印刷しました。


https://x.com/shuji_4649/status/1871180532157223186



2,3回やってみてうまくいかなかったらこんな方法もありかもしれません。

使えるかわからないですが一応この3Dモデルのリンクを公開します。ご自由にお使いください。

https://a360.co/3ZWTdev
離散数学(超入門) - 論理学 - 1

この記事は離散数学シリーズとして続けていく予定です.


# 論理学とは

論理学とは, 物事を筋道立てて考え, 結論の正しさを確認するための方法を学ぶ分野です. 論理学はプログラムやアルゴリズムの設計において重要な役割を果たします. 命題や推論の構造を分析することで, コンピュータが誤りなく動作するようにはどうしたらいいかなどを考える時に役立ちます. 

今回は論理学を勉強するうえで重要な, 「命題」と 「推論」についてご紹介します.

# 命題について

命題とは, 「真か偽かが明確に定まる文」を指します. たとえば, 次の文を見てください.

(1) 富士山は日本で一番高い山である
(2) カエルは鳥類である
(3) コーヒーは好きですか？

この中に, 命題であるものとそうでないものが混ざっています.
これを区別するためには「真偽」がカギになります.
例えば(1)は周知の事実であり「真」です. (2)に関しては, カエルは両生類であるので「偽」です. (3)は質問であり, 「真」でも「偽」もありません.

このように, その文が事実である場合は「真」. 事実でない場合は「偽」と言います. そして, 真偽が明確に定まる文は命題というわけです.

上述した文について命題か否かを述べると以下のようになります.

(1) 富士山は日本で一番高い山である ⇨ 命題
(2) カエルは鳥類である ⇨ 命題
(3) コーヒーは好きですか？ ⇨ 命題ではない

(2)は命題であるという点に注意してください. この文は偽なので 一見 命題ではないように感じるかもしれませんが, 真か偽かが明確に定まる時点で命題です. (3)は単なる疑問文であり, 命題ではありません. 

あらゆる色の中で青色が一番美しいなど, 微妙なケースもありますが真偽の判定が難しいので, ここでは取り扱いません.

# 推論について

推論とは**既知の情報**（命題）をもとに, 新たな**結論**を導き出すことです. 
既知の情報のことを「前提」や「根拠」といったりします.
結論のことを「結論」もしくは「帰結」などといったりします.
有名な推論として以下に**3段論法**を挙げます.

```
P Q それゆえ, R 
```

記号だけでは分かりにくいので, 具体的な文にしてみます.

- **前提: P**  すべての犬は哺乳類である.
- **前提**: Q  ポチは犬である.
- **結論**: R  ポチは哺乳類である.

```
すべての犬は哺乳類である.ポチは犬である. それゆえ, ポチは哺乳類である.
```

3段論法の場合は前提が2つでしたが, 3つやそれ以上の場合もあります.

他にも例を挙げてみます

(1) Aさんは明日誕生日である. Aさんは現在50である. それゆえ, Aさんは明日51歳になる.
(2) Bさんのは私の父の息子である. それゆえ, Bさんは私の兄弟である.
(3) 地面が濡れている. それゆえ, 雨が降ったにちがいない.

この中で(1)と(2)は, 前提が真と認めると, 結論も必ず真だと認める必要が出てくる推論です. このような推論を「**演繹(えんえき)**」と呼びます. それに対して, (3)は前提が真であっても結論が真であるとは限りません. もしかすると, 水やりなどによって地面が濡れているのかもしれません. よって, これは演繹ではありません.

演繹の重要な注意点として,「演繹は, 前提が正しいと仮定した場合に, それに基づいて結論が必然的に導かれるかどうかに注目する」というものがあります. つまり, 前提に基づいて論理的な推論が行われていれば, それは演繹として問題ないということです. 演繹の正しさは前提自体の真偽には影響されないのです.

以下に例をあげます.

「すべての人間には空を飛ぶための翼がある. 私は人間である. それゆえ, 私は空を飛ぶことができる」  

これは, 一見めちゃくちゃな文ですが, 演繹としては正しい形式を持っています. ただし, 前提が現実とは異なっているため, 結論も現実的には成り立ちません. このように, 演繹の正しさは前提の真偽に依存しないことが重要なポイントです.


# 終わりに
今回のテーマは論理学の基礎として重要な「命題」と「推論」でした. 少しでも論理学の雰囲気が伝わったら幸いです.

# 参考書籍

[まったくゼロからの論理学 野矢 茂樹](https://www.amazon.co.jp/%E3%81%BE%E3%81%A3%E3%81%9F%E3%81%8F%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%81%AE%E8%AB%96%E7%90%86%E5%AD%A6-%E9%87%8E%E7%9F%A2-%E8%8C%82%E6%A8%B9/dp/4000248294)
main/master以外の不要なローカルブランチを掃除するワンライナー


# やりたいこと

ローカルブランチが溜まっているので掃除したいときがあります。

```sh
$ git branch
  foo
  fuga
  hoge
* main
  piyo
```

こんな感じになっていたら、mainブランチと必要なブランチだけを残してスッキリしたい…また、場合によってはmainブランチじゃなくてmasterブランチがデフォルトになっていることもあるので、main・masterどちらにも対応したワンライナーを書きたいなと思いました。

## 作成したワンライナー

`git branch | grep -v -E "main|master" | awk '{print $NF}' | xargs git branch -d`

このワンライナーを実行すると、ローカルブランチがmain（master）ブランチとマージができていないブランチだけが残ります。もし、fooブランチをマージしていない場合は、以下のようにエラーが発生します。

```sh
$ git branch | grep -v -E "main|master" | awk '{print $NF}' | xargs git branch -d
error: the branch 'foo' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D foo'
hint: Disable this message with "git config advice.forceDeleteBranch false"
Deleted branch fuga (was 97ef981).
Deleted branch hoge (was 97ef981).
Deleted branch piyo (was 97ef981).

$ git branch
  foo
* main
```

aliasを設定するなどとして、ピッと呼び出せるようにすると便利かなと思います。

# ワンライナーの解説

`git branch | grep -v -E "main|master" | awk '{print $NF}' | xargs git branch -d`を一段階ずつ分解して、コマンドが何をしているかをみていきます。

## `git branch`

ローカルブランチを表示します。

```sh
$ git branch
  fuga
  hoge
* main
  piyo
```

## `git branch | grep -v -E "main|master"`

`git branch`で出力したローカルブランチの一覧をパイプで受け取り、mainとmaster以外のブランチのみを表示します。

```sh
$ git branch
  fuga
  hoge
* main

$ git branch | grep -v -E "main|master"
  fuga
  hoge
```

### grepコマンドについて

`grep -E`では、拡張正規表現を使用して、結果の抽出ができます。

```sh
$ git branch
  fuga
  hoge
* main

$ git branch | grep -E "main|master"
* main
```

`-v` オプションをつけると、条件に一致しない行を抽出できます。

```sh
$ git branch | grep -v -E "main|master"
  fuga
  hoge
```

## `git branch | grep -v -E "main|master" | awk '{print $NF}'`

`awk '{print $NF}'`で各行の最終フィールドを表示します。

```sh
$ git branch | grep -v -E "main|master"
  fix-readme
  fuga
  hoge
$ git branch | grep -v -E "main|master" | awk '{print $NF}'
fix-readme
fuga
hoge
```

## `git branch | grep -v -E "main|master" | awk '{print $NF}' | xargs git branch -d`

`xargs`を使用して`git branch -d`コマンドに引数として抽出済みのブランチを渡します。
E系列で部品を決めよう

電子工作で抵抗やコンデンサなどの値を決めるとき、どの値なら売っているのか？どのような値がよく使われるのか？などと思ったことはありませんか。

今回は電子部品の値の基準として規格化されているE系列というものについてざっくり紹介します。


# E系列とは
抵抗やコンデンサ、インダクタ等の数値の基準となっているものです。
22uFや470Ωなどの数字は見覚えがあると思います。
これは適当に決まっているわけではなく、あるルールにのっとって決められているのです。
そのルールがE系列というものです。E系列はJIS C 5063で規格として定められています。

E系列の中にはE3系列からE196系列まであり、それぞれ1から10までの等比数列となっています。

E〇系列の〇の数字は等比数列の項数を表しており、例えばE3系列は1, 2.2, 4.7(, 10)となります。
別の表し方でいうと、E$n$系列の値は$\sqrt[n]{10} ^p (0\leqq p < n)$で表されます。

22や47という数字をよく見かけるのは一番粗い分け方であるE3系列の数字だからです。
E〇系列の〇の数字が大きくになるにつれて区切り方は細かくなっていきます。

ちなみにEというのは「Exponent（指数）」の頭文字だそうです。

# 数値
## E3系列
- 1.0
- 2.2
- 4.7

## E6系列
- 1.0
- 1.5
- 2.2
- 3.3
- 4.7
- 6.8

## E12系列
- 1.0
- 1.2
- 1.5
- 1.8
- 2.2
- 2.7
- 3.3
- 3.9
- 4.7
- 5.6
- 6.8
- 8.2

## E24系列
- 1.0
- 1.1
- 1.2
- 1.3
- 1.5
- 1.6
- 1.8
- 2.0
- 2.2
- 2.4
- 2.7
- 3.0
- 3.3
- 3.6
- 3.9
- 4.3
- 4.7
- 5.1
- 5.6
- 6.2
- 6.8
- 7.5
- 8.2
- 9.1

# 部品の選び方

さて、E系列がどのように重要になるのかというと、E〇系列の〇の数字が小さい部品ほど安く、多く流通している傾向にあるということです。
そのため、できる限り小さいE系列の表の中から部品を選ぶとよいです。
基板製造時に部品を実装してもらう時も、E3系列やE6系列の部品の方が実装費用が安い傾向にあります。

できる限りE12系列までの中から選び、どうしても正確な値のものが欲しいという時にはE48やE96を使うというものが良いと思います。

ただ、抵抗をいくつか組み合わせてほしい値を作るという方法もあります。
こちらのサイトがとても便利なので使ってみてください。


http://sim.okawa-denshi.jp/teikokeisan.htm
AWSでサーバー構築

# AWSでサーバーを構築するには

AWSでサーバー構築するための、ざっくり大まかな手順になります。

前提として、前回記事（[AWSでネットワーク構築](https://qiita.com/futeiki_kcm/items/bf946275c853b4207c95)）のような手順を踏み、ネットワーク構築してるものとします。

## ①EC2作成

仮想サーバーを構築するために必要なのがEC2の作成。

ここで作成した仮想サーバーのことを`インスタンス`という。
このインスタンスに作成したいサーバーソフトをインストールすることにより、サーバーとして機能するようになる。

インスタンスにはサブネット内で使用することが可能なプライベートIPアドレスを割り当てるが、インターネットとの接続においてはパブリックIPアドレスが必要なため、プライベートIPアドレスとは別にパブリックIPアドレスを設定すること。

#### AMIの選択

インスタンスを起動させるときに用いるイメージファイルのことをAMI
といい、ここにはOSがインストールされており、初期アカウントの設定まで済んだイメージが入ってる。

#### インスタンスタイプの選択

仮想マシンのスペックを決めるものをインスタンスタイプという。

#### キーペアの設定

キーペアはインスタンスにログインする際必要なキーで、これがないとログインできない。
※一度しかダウンロードできないため、安全な場所に保管しておくこと

#### セキュリティグループの設定

インスタンスのトラフィックを制御する一連のファイアウォールルールのこと。
詳細な設定は後ほど行う。

## ②EC2インスタンスSSH接続

インスタンスを起動したら下記のようなコマンドでSSH接続する。
```
ssh -i ~/.ssh/作成したキー.pem ec2-user@パブリックIPアドレス
```
他にもteratermなどのツールを使用して接続することも可能。

接続できたらこのような表示が出る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763202/6d44c7db-ab41-64af-d416-2d918d4ff946.png)

また、基本的にインスタンスに与えられるパブリックIPアドレスは動的だが、IPアドレスを固定化させたいときは`Elastic IP`という機能を使って固定させることもできる。

::: note warn
VPCやサブネット、ルートテーブル、インターネットゲートウェイなどがきちんと紐づいてないと接続できないためしっかり確認すること
:::

## ③ソフトウェアのインストール

Webサーバー等使用用途によりソフトをインストールしていくこと。

Webサーバーだと例としてApache、Nginxなど。

ログインしたインスタンスに必要なソフトをインストールしていくことで、インスタンスに機能を持たせることができる。

インストール後にサーバーを起動させ、ネットワークの待ち受け状態を確認すると、ポート80で待ち受けしていることがわかる。（TCP *:80表記）

```
sudo lsof -i -n -P
```

なお、IPv6で表示があった場合にも、IPv4互換アドレスで応答を返すように構成されているため正常に通信できる。

::: note 
ポート80はHTTPのウェルノウンポート。
ウェルノウンポートとはTCP/IPで使用されるポートのうち、慣例的に使用されている1024個のポートのこと。
:::

## ④ファイアウォールの設定

セキュリティグループ設定により、ポート80を通さないルールだった場合、ポートを通すようなファイアウォールを構成していく必要がある。

外側から入ってくるパケットのファイアウォールはインバウンドルールからポート80を通すようにルールを追加する。

下記にアクセスし、設定に問題なくブロックされていなければデフォルトページが表示される。

```
http://<パブリックIPアドレス>
http://<Elastic IPアドレス>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763202/240c8c99-f71e-9d6e-f422-4d61fb4dfbb8.png)

## ⑤ドメイン・DNS設定

IPアドレス入力でブラウザにアクセスできるが、一般的には「example.co.jp」のようなドメイン名を使ってアクセスすることが多い。

ドメイン名とはIPアドレスを人間が理解しやすい形にしたもので、IPアドレス同様一意性が保たれている必要がある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763202/a8ee7aa5-36db-1c31-f113-5e16a6832c4a.png)

とはいえ、相手先を確認するのはあくまでもIPアドレスであるため、ドメイン名でアクセスするときも最終的にはIPアドレスに変換して接続している。

その際に用いられる仕組みが`DNS（Domain Name System）`であり、ドメイン名からそれに対応するIPアドレスを引き出すことを`名前解決`と呼ぶ。

該当のVPCの「DNSホスト名を有効化」から有効化することでEC2の該当のインスタンスに対し、プライベートDNSに加えパブリックDNSが付与される。

割り当ててないときはプライベートDNSのみ設定されてない。

表示されたパブリックIPv4DNSからアクセスすると先ほどと同じデフォルトページがドメイン名表示アドレスでも接続することができる。

```
http://ec2-[パブリックIPをもとに自動生成].ap-northeast-1.compute.amazonaws.com/
```

独自ドメイン名を使用したいときはRoute53を通してDNSサーバーの構築し、EC2インスタンスと紐づける。

## まとめ

__①EC2作成__
インスタンスを作成し、AMIやインスタンスタイプ、キーペアの設定等行う。

__②EC2インスタンスSSH接続__
ssh接続し、作成したインスタンスのサーバーに入ることができるか確認する。

__③ソフトウェアのインストール__
用途に応じソフトウェアをインストールし、インスタンスに機能を持たせる。

__④ファイアウォールの設定__
セキュリティグループの設定を行い、ポートを通すようにする。

__⑤ドメイン・DNS設定__
DNSの仕組みを使用し、ドメイン名から対応するIPアドレスを引き出して接続。
コピペ作業が不要に！？VSCodeに生えたGitHub Copilotと作る自分だけのショートカット

# ショートカットを登録すると何ができるの？

例えば、開発工程で、コードのコメントに記載する文言がプロジェクトで決まっている場合、
その都度、別のコメントエリアから文字をコピーしたり、規約書を開いてコピーしていませんか？

そんな時、Ctrl＋P＋C（プロジェクトコメントの略のつもり）のショートカットキーで、
固定文言「ほげほげプロジェクトのほげほげ」をテキストに張り付けられたら便利じゃないですか？

あるんです！

# 公式サイト

こちらに手順があります。

https://code.visualstudio.com/docs/getstarted/keybindings#_keyboard-shortcuts-editor

以下操作で対象画面を開きます。

>[環境設定: キーボード ショートカットを開く] コマンド (Ctrl+K、Ctrl+S) 

以下ボタンで「keybindings.json」ファイルを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/baf6a55a-3c74-b371-3552-e02ac0bc6e72.png)

開かれたファイルに任意の設定値を登録します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/4173f749-acdd-6ddd-b661-605178562634.png)

公式サイトを確認しながらキーとバリューを登録すれば設定完了です。

# GitHub Copilot

手動作成が難しそうだったので、
VSCode上のGitHub Copilotを活用して設定していきましょう。

:::note warn
挙動が安定しないので、いったんインラインからCopilotを呼び出す手順を記載します。
本当はファイルを選択して編集モードで更新してもらった方が早いです。
ファイル選択がうまくいった場合は、そちらから同様の依頼文で更新してみてください。
:::

「keybindings.json」ファイル内を画像の通り改行してから、
右クリックし、「エディター内でのインライン　チャット」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/f095925b-b9b7-e300-2671-a0f26eb6d5a4.png)

以下のような任意の依頼文を入力すると、以下の通り設定値を作成してくれるので、同意でファイルを保存します。

>Ctrlを押しながら、PとCを押した場合は、
固定文字「ほげほげプロジェクトのほげほげ」を表示中のテキストファイルのカーソル位置に挿入する設定を記載してください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/2caea432-7581-bae0-859e-567c96d91883.png)

それだけ完了！

# まとめ

簡単にオリジナルショートカットが追加できます！
【C#】指定のファイルを特定の場所にコピーするサンプルコード

# 概要
指定のファイルを特定の場所にコピーする際のサンプルコードを記載しました。

# コード

```C#

        /// <summary>
        ///  指定されたファイルを特定の場所にコピーする
        /// </summary>
        /// <param name="srcFilePath">コピーするファイルのパス</param>
        /// <param name="outputDirPath">コピー先のフォルダまでのパス</param>
        private void CopyFileToDirectory(string srcFilePath, string outputDirPath)
        {
            try
            {
                string fileName = Path.GetFileName(srcFilePath);
                string outputPath = Path.Combine(outputDirPath, fileName);  // ファイル名はコピー元と同様にする

                while (true)
                {
                    if (File.Exists(outputPath))
                    {
                        // 既にファイル名がある場合はリネームして再チェック
                        string extension = Path.GetExtension(fileName);
                        fileName = Path.GetFileNameWithoutExtension(fileName);
                        fileName += "_Copy" + extension;

                        outputPath = Path.Combine(outputDirPath, fileName);
                        continue;
                    }

                    break;
                }

                CopyFile(srcFilePath, outputPath);

            }
            catch (UnauthorizedAccessException)
            {
                // ログ出力等のエラーハンドル処理 (省略)
            }
            catch(Exception)
            {
                // ログ出力等のエラーハンドル処理 (省略)
            }
        }

        /// <summary>
        /// ファイルをコピーする
        /// </summary>
        /// <param name="fromPath">コピー元パス</param>
        /// <param name="toPath">コピー先パス</param>
        private void CopyFile(string fromPath, string toPath)
        {
            var file = new FileInfo(fromPath);
            file.CopyTo(toPath, true);       
        }
```

### 補足
本コードでは、コピー先に同じファイル名がある場合にリネームする対応を行っています。
※同じファイル名が無くなるまで、ファイル名の末尾に「_Copy」という文字列を加えます。

### 注意点
`UnauthorizedAccessException`はファイルやディレクトリへのアクセス権限がない場合や、ファイルが読み取り専用モードになっている場合などに発生します。
特定のフォルダのアクセス権が有効かどうか、アクセスする前にあらかじめプログラムで計算するのはいろいろな考慮点が必要で、またアクセス権自体ももしかしたらアクセスの計算時に変わってしまう可能性もあります。そのため、上記のコードのような場合でアクセス権を調べる方法は実際にアクションを実行して、`UnauthorizedAccessException`がスローされた状況を処理する方法が安全らしいです。

## 終わりに
ファイルをコピーするだけでも同名ファイルやフォルダへのアクセス権など、注意すべきことがいくつかあることをしっかりと把握しておきたいと思いました。
React x shadcn/ui実装

## はじめに

Claudeを普段利用して開発をサポートしてもらっているが、適当に作成しているとshadcn/uiを妙に推してくることがある。

以前導入に失敗したものの、簡易的にコピペしつつ利用したところ結構使い勝手が良かったので改めて導入を頑張りたいと思う。

最近Reactで静的ホストを利用するのにはまっているのでNextjsではなくReactに導入する方法を探っていきたいと思う。

**基本的な手順：**

https://qiita.com/suiwave/items/a608893e896608508292

最後インストールする場所がずれる問題があったので、インストール部分だけ修正しようと思う。

## はまった場所

`components.json`をいったん削除する

```bash
pnpm dlx shadcn@latest init
```
これを実行すると、エイリアスのあたりでエラーになると同じ設定ミスをしている


**修正1：tsconfig.jsonの修正**

:::note warn
tsconfig.jsonにパスの設定を行わないと認識しない問題がある
nodeやappに記載していたため、認識されなかった。
:::

```json:tsconfig.json
{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}
```
再度開発サーバを立ち上げなおしてエラーが出なければ問題なし

**修正2：エイリアスの修正**
純粋にReactのエイリアスエラーなので以下のサイトを参考にするとよい

~~以前は、2個目で行けたがなぜか今回うまくいかなかったためもしかしたら設定関係で依存があるかも、、？~~

:::note warn
vsのTSがパスを認識しない問題があったが、そちらはappのほうを参照するようなので重複する内容であるが、そちらにも記載する必要がある。
:::


探すのが若干面倒臭いので今回は1個目でやりました。

https://zenn.dev/fugithora812/articles/825a3374c10e61
Ubuntu24.04上のvscodeで日本語入力できない件

## ubuntuで，なぜかvscodeだけ日本語入力ができない

日本語入力環境はできており，terminalやchromeなどでの日本語入力は問題なくできる．Emacsでも日本語編集ができるが，なぜかvscode上では日本語入力ができない（半角／全角キーが効かない），という状態．

## 既知の修正法

親切な先人たちがネットで情報を公開してくれている．例えば

- snap版のインストールでなく，vscodeのサイトからdebファイルをダウンロードしてインストールすべし [link](https://qiita.com/sunrise_lover/items/787f12c43839f8156296)
- Ubuntu24.04ではmozcでなくfcitx5を使用すべし [link](https://qiita.com/naohiro2g/items/21213d6f7deb648fa300)
- fcitx5の環境設定を修正すべし　[link](https://zenn.dev/kitsunecat/articles/29c48b0f26ff84)

このあたりは試したが，私の環境ではすべて不発だった．

## 実はvscodeの立ち上げ方の問題だった

私の環境では，結局上記のようなインストールや設定に問題があったのではなかった．

ファイルを編集する際に，コマンドラインから

```
code file.cpp
```

のように開いてしまうと，vscodeが立ち上がりはするのだが，日本語入力の切替（半角／全角キー）を受け付けない．

そうではなく，Ubuntuのアプリケーションメニューからvscodeのアイコンをクリックすることで立ち上げると，日本語入力ができた（半角／全角キーを受け付けた）．

ただし，これは**最初に**vscodeを立ち上げる時の話．一度アプリケーションメニューから立ち上げておき，その後に

```
code file2.cpp
```

のように新たな編集ファイルを開くことにすれば，問題は生じないことがわかった．
dbginfo.shスクリプトの実行の備忘録

## dbginfo.shスクリプトの実行

`dbginfo.sh`スクリプトは、デバッグのために様々なシステム関連ファイルを収集します。現在のシステム環境をキャプチャし、`.tar`ファイルを生成します。  
Linux®システムがz/VM®ゲストオペレーティングシステムとして実行されている場合、`dbginfo.sh`はz/VMゲストのセットアップに関する情報も収集します。

:::note info
参照：
https://www.ibm.com/docs/en/linux-on-systems?topic=tools-dbginfosh
:::

### 実際にdbginfo.shを実行してみましょう。

#### dbginfo.shの取得

```bash
[root@linux~]# dbginfo.sh

dbginfo.sh: Debug information script version 2.29.0-3.el8

Copyright IBM Corp. 2002, 2023

Hardware platform     = s390x

Runtime environment   = z/VM

Kernel version        = 4.18.0 (4.18.0-553.el8_10.s390x)

OS version / distro   = Red Hat Enterprise Linux 8.10 (Ootpa)

Date and time of info = 2024-××-××

1 of 18: Collecting sysfs

2 of 18: Collecting procfs

3 of 18: Collecting config files

4 of 18: Collecting command output

5 of 18: Collecting hyptop for z/VM - 5s output

6 of 18: Collecting z/VM output

7 of 18: Collecting network output

8 of 18: Collecting osa oat output

9 of 18: Collecting ethtool output

10 of 18: Skip Trafic Control: tc not available

11 of 18: Collecting bridge output

12 of 18: Skip OpenVSwitch: ovs-vsctl not available

13 of 18: Skip KVM: no virsh command

14 of 18: Skip container host: not found

15 of 18: Collecting NVME storage output

16 of 18: Collecting log files

 0 logfiles over 50 MB

17 of 18: Postprocessing

18 of 18: Finalizing: Creating archive with collected data

Collected data was saved to:

 >>    <<

Please review all collected data before sending to your service organization.

[root@linux ~]#

```
#tarファイルとして取得できたことを確認
ngx_http_limit_req_moduleメモ

nginxでrate limitをかけるめも

```
limit_req_status 503;
limit_req_zone  $binary_remote_addr  zone=minutely:10m  rate=100r/m;

server {
    location / {
    limit_req zone=minutely burst=10 nodelay;
    }
}
```

[ngx_http_limit_req_module モジュール](https://mogile.web.fc2.com/nginx/http/ngx_http_limit_req_module.html)

[ngx_http_limit_req_moduleに今度こそ入門する](https://ryuichi1208.hateblo.jp/entry/2021/10/26/000859)
【Atcoder自分用復習】ABC356_Masked Popcount

# ABC356_Masked Popcount
なるべく、数式とか使わずに直感でわかるように説明していきたいです。

### 問題文
リンク:https://atcoder.jp/contests/abc356/tasks/abc356_d
整数 N,M が与えられるので、 
∑｛K=0〜N｝　popcount(k&M) 
を 998244353 で割った余りを求めてください。
※& はビット単位AND演算を表します。

#### 制約
　0 ≦ N < 60
　0 ≦ M < 2^60
  
:::note info
popcount(k) 

kを2進数にしたとき、1が立っている桁は何個あるか？ということです。
:::

## 必要な知識
・進数計算(10→2)
・論理演算(AND)
・popcount公式


## 本解説
#### 問題文の要約
K＆Ｍにより、Mが0の桁は常に強制的に0にされてしまいます。
0にされるということはその桁の1が数えられることはありません。
毎回Mの＆演算が行われるのでΣにおける足し算すべてで同様です。

つまり、
①：まずはMは一切考えずに、Nまでの数において各桁ごとに　「1」　が出現する回数を求める。
②：Mで1が立っている桁に対応する箇所のみを足し合わせる。これが答え。

で求めることができます。

#### 検討：ブルートフォースでいけそうか
与えられる数は2^60なので無理でした。
最悪、足し算を2^60回することになりますからね。

#### popcountの公式を使う
突然ですが、1111(2)までを0000から順番に書き並べてみます。
```
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
```
各桁ごとに登場する 1 の回数を数えるとすべての桁で同じ　8個　です。
同様に、0から11111(2)までに各桁ごとに登場する1の回数はすべての桁で同じ数であり、その数は16個です。

:::note
**0から2^nで最上位桁を除く各桁ごとに１が登場する回数は2^(n-1)**　・・・①
:::

例えば0から2^100の数で最上位桁未満の各桁で1が登場する回数は2^99となります。
これを用いることで一気に計算量を減らして各桁ごとの「1」の出現回数を求めることができます。

Nを2進数にして最上位ビットから右に向かってそれぞれのビットに以下の操作を繰り返します。

・そのビットが1の場合→
　⭐︎そのビットに1が立つまでの下位ビットで1が現れる回数を①を用いて計算し、下位ビットそれぞれの「1」出現回数保持配列に足す。
　⭐︎そのビットに1が出現する回数は右のビットを10進数変換して+1した数に等しいので、それを計算して現在地点のビットの「1」出現回数保持変数に足す。

・そのビットが0の場合→何もしない。

言葉で説明すると難しいので具体例を考えてから一般化していきます。

#### 具体例で考える
N = 10 M = 3 とします。
Nb = 1010 、Mb = 0011 です。

各ビットごとに登場する１の回数を保持する変数を一番左を1として、A1,A2,A3,A4としましょう。

一番右のビットは1です。よって0〜111を①の公式で求めてA2〜A4に足します。
また、A1には、010を10進数に変換して+1したものを足します。

2番目のビットは0ですので何もしません。

3番目のビットは1です。よって0〜01を①の公式で求めてA4に足します。

4番目、つまり最後のビットは0です。よって何もしません。


これで各桁ごとの「1」の出現回数が求まりました。

Mは0011なのでこのうちA3,A4のビットだけが総和の対象となります。
よって、A3,A4を足して終わりです。

:::note
実際の問題ではmodで答えを出すので各操作ごとにmodで数を小さくするなどの工夫が必要です。
:::

#### 間に合う？計算量は？
Nは2^60なのでビット数は最大60です。
①の冪乗計算は繰り返し二乗法を使うことでlogに落とせます。(2^60程度ならば繰り返し2乗法使わなくてもいけます)
よってNの桁をdとして　Σlog(d) となります。
最大ケースのd=60でも大したことありません。

#### コード
上記を元にPythonで書いたコードになります。
少し冗長ですが可読性を意識して書いてます。

```ans.py
n,m = map(int, input().split())

n_b = format(n,'b') #Nの二進数
n_l = len(n_b)
m_b = format(m,'b') #Mの二進数
m_l = len(m_b)

# 各桁ごとに1が出現する回数を計算
pop_arr = [0]*n_l #各桁ごとの「1」の出現回数保持配列
for i in range(n_l):
  
  tmp_bit = n_b[i]
  if tmp_bit == '0':
    continue
  
  elif tmp_bit == '1':
    digit = n_l - i - 2 
    if digit < 0:
      pop_arr[i]+=1
      continue
    temp = 2**digit
    temp = temp % 998244353
    pop_arr[i+1:] = [x + temp for x in pop_arr[i+1:]]
    
    #現在のbitより右の部分を足す
    r_bit = n_b[i+1:]
    r_int = int(r_bit,2)
    pop_arr[i] += r_int + 1 #全て0のパターンも個数に含むので＋1

# mの1が立っている桁だけの総和を取る
total = 0
for j in range(m_l):
  
  if j > n_l - 1: #Nの桁数を超えたら終了(どうせ0)
    break
  
  maskbit = m_b[m_l - j - 1]
  if maskbit == '0':
    continue
  elif maskbit == '1':
    total += pop_arr[n_l - j - 1]
    total %= 998244353
  
#答えを出力
print(total)
```
Ktor/OAuth2 でGoogle認証[1]

# 概要
(日記)Google Driveアプリのデータを参照したいと思ったので、Google OAuth2で認証しアクセストークン取得まで

# 環境
- Google Cloud のプロジェクト
- Windwos 11
- Java 21 (for gradlew)

//# SpreadsheetのクラウドAPIを有効にする
//[Google Cloudのメニューから[APIとサービス]](https://console.cloud.google.com/apis/)
//➔ [APIとサービスを有効にする] ➜ [Google Sheets API]を選択 ➜ [有効にする]

# Google CloudでOAuthを設定
[Google Cloudのメニューから[APIとサービス]➜[OAuth同意画面]](https://console.cloud.google.com/apis/credentials/consent)
デベロッパーの連絡先情報以外はデフォルト値のまま[保存して次へ]
ここでは刷新されたUIを使ってみます[新しいページに移動]
[スコープを追加または削除]➜フィルタでGoogle Sheets APIを入力、今回は readonlyを指定。➔[SAVE]

# クライアント登録
[Google Cloudのメニューから[APIとサービス]➜[認証情報]](https://console.cloud.google.com/apis/credentials)➜[認証情報を作成]➜[OAuthクライアントID]➜デスクトップ クライアントを作成
GOOGLE_CLIENT_IDとGOOGLE_CLIENT_SECRETを入手

# コード
```build.gradle.kts
plugins {
    kotlin("jvm") version "2.1.0"
    application
}
repositories { mavenCentral() }
application { mainClass = "MainKt" }
dependencies {
    implementation("io.ktor:ktor-client-cio:3.0.3")
    implementation("io.ktor:ktor-server-cio:3.0.3")
}
```
```kotlin: src/main/kotiln/Main.kt ※一部略
suspend fun main() {
    val client = HttpClient(CIO)
    val redirectUri = "http://127.0.0.1:28080"
    val authorizationUrl = URLBuilder("https://accounts.google.com/o/oauth2/auth").apply {
        parameters.append("client_id", System.getenv("GOOGLE_CLIENT_ID")!!)
        parameters.append("redirect_uri", redirectUri)
        parameters.append("response_type", "code")
        parameters.append("scope", "https://www.googleapis.com/auth/userinfo.profile")
    }.buildString()
    println("ブラウザで以下のURLを開いて認証してください:\n$authorizationUrl")
    // 上で表示されるURLを利用者が開いたブラウザに入力し認証操作を続ける

    val authorizationCode = redirectReceiverServer()!! // ここで認証(リダイレクト)を待っている

    println("authorizationCode=$authorizationCode")

    val tokenResponse = client.submitForm(
        url = "https://accounts.google.com/o/oauth2/token",
        formParameters = Parameters.build {
            append("grant_type", "authorization_code")
            append("code", authorizationCode)
            append("redirect_uri", redirectUri)
            append("client_id", System.getenv("GOOGLE_CLIENT_ID")!!)
            append("client_secret", System.getenv("GOOGLE_CLIENT_SECRET")!!)
        }
    ).bodyAsText()
    println("accessToken:\n$tokenResponse")
    client.close()
}
```
[ソース](https://github.com/kyoya-p/samples/tree/master/2025/OAuth/Step11)

# テスト実行
```sh
export GOOGLE_CLIENT_ID='xxxxx......com'
export GOOGLE_CLIENT_SECRET='GO.....RH-2'
sh gradlew shadowJar
java -jar build/libs/Step1-1.0-SNAPSHOT-all.jar
# ターミナルに表示されるURLをブラウザで開きGoogleで認証
```
accessTokenが表示されればOK.

# 参照

https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets?hl=ja

https://qiita.com/7032/items/50fc96b6e8c9ac90c32f

https://github.com/ktorio/ktor-documentation/tree/3.0.3/codeSnippets/snippets/client-auth-oauth-google
超ひも理論

●起
2024年
ヴァーチァルアイドルが、世間に台頭する。
hololiveという、ヴァーチァルアイドル専門のタレント事務所も、大人気である。

我が秋葉原ロボットも、この流れに乗って、
アイドルをつくるべき、いや、作らないといけない！だろう。今回はそこを探る。

●承
　だが、ライバルは多いのである。量子力学の分野では、固体量子　という人気ライバルがすでに、人気を確立している。
 枝豆のずんだもん　も、闇歴史シリーズなど、あらゆるシリーズで人気である。
 後発の我々が入りこめる分野など、もはや無い、、、
 
 と、思いきやあった！あれがあった！理論物理のあれだ！

●転
ひも理論、超ひも理論　なら、誰もアイドルを作ってない！ゆえに、これで行こう！

ただし、一つ懸念がある。例えば、以下のような会話が生まれるだろう。

「秋葉原ロボット部って、ひも男が多いのですか？」
「普段、ひも男は消滅してます。ひも男は、スピン旋回で、消滅状態から、ときおり現れます。」
「私の前彼が、ひも男だったのですが、どう思いますか？」
「あなたは、かなり可愛いので、ロボット部のMilk-5基板をつかって痛車を実装して、ステェッカーにさせていただきます！」

●結
9次元だ！
ひも理論は、ドーナツ理論と仲良しだ。
ホモロジーだ。
とりあえず、逆行列の有無を調べたり、
基底変換をする。極みつけは、
射影だ！

すごい！すご過ぎる！超ひも理論！

Vtuberになりたい人、募集！

参考文献）
大坂市立科学館
https://www.sci-museum.jp/wp-content/themes/scimuseum2021/pdf/study/universe/2017/06/201706_04-09.pdf

固体量子
https://www.youtube.com/watch?v=M56fNwB7Y-Y
プログラミングを触ってみて

## 反省

udemyやプロゲートで勉強しましたが、自分のなかで受け身学習が多く、実際にアウトプットすると初歩的な文法を**忘れてしまいます....**
また、断片的な学習も多く結局開発物製作に入れてないのも懸念点です。

## 感想

数学に酷似してるなと思いました！
実際にコードを触れてみてみも、~~関数宣言でfnと置く時点で数学ですが~~、あらゆるモジュールをうまく利用して、１つの完成物につなげるところが特に数学！

## 課題点

反省にも記載してる通り、まだ断片的な学習が懸念点です。
~~早くudemy講座終わらせて、開発に入りたいです~~
先輩たちといろいろ相談して、これからも頑張れたらなと思いました！

## 追記

~~宣伝みたいになりますが~~先輩から教えていただいた初心者おすすめの書籍です！

**自分も実際に購入して読みました**が、図で分かりやすく、とても解説が丁寧なのでおすすめです！


この１冊で全部わかるWeb技術の基本[第２版」　
![81Oz6wWF+pL._SL1500_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3946156/3c72c305-b017-7dd5-d788-65cb26c621fc.jpeg)

https://www.amazon.co.jp/%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88%E5%9B%B3%E8%A7%A3%E5%BC%8F-%E3%81%93%E3%81%AE%E4%B8%80%E5%86%8A%E3%81%A7%E5%85%A8%E9%83%A8%E3%82%8F%E3%81%8B%E3%82%8BWeb%E6%8A%80%E8%A1%93%E3%81%AE%E5%9F%BA%E6%9C%AC-%E7%AC%AC2%E7%89%88-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/4815625948/ref=sr_1_1?adgrpid=125376924948&dib=eyJ2IjoiMSJ9.jXjLiu5Q9P12i2Rdr4sDsgwXe-p5WlQ1kxfCG0EE672TNQDUuMFkq8AkiiXll6A0_I2xVHMYMzzXR6mzTsA2cqcIWDKFXmIY97ufUnfc0FFNXZT69affReOww6F7CiRyOqMo4kPUT2XUYJ5nHNY8tirGWJmKF9p1oUu0R5bk8jniopNFga6dCdwofSxLg1oZ56Ovzqg0562wXOm40Ho6coSCIyVVGZ5qnolLMGOknY6oc128PKebtfv34aPlqaIouDgNOlgXV-PdNNbjGRf9ih10c_TjkLSQ1HUktG1ove2L1Grs0L8OZDMCaNfEJhzS5pmw_in6nf9Jcw1t0ImwxXobNLmgHXS2Msww0FvqLKz3RrvAGDIB1rT3JwdyT15V9K93XVDkMyp1qiWgjRWwGB-_QYWC48JVdgk0sUmnZhpXspCHzrdnwQWOdXHR2RGX.47BC-hmgmS_UeYMw8fH4RXpDXGLO93acg0o195J8eBo&dib_tag=se&hvadid=668336650995&hvdev=c&hvqmt=b&hvtargid=kwd-811307209612&hydadcr=2964_13696196&jp-ad-ap=0&keywords=web+%E6%8A%80%E8%A1%93%E3%81%AE%E5%9F%BA%E6%9C%AC&qid=1735644629&sr=8-1
What is Path PDF?

In the PDF industry, the Path PDF refers to the vector graphic elements in the PDF file and expresses graphic content by defining the path. It consists of a few concepts as below:

 

- Path: Defines boundaries for lines, filled areas, or clipping other images.
- Connection: 2 consecutive line segments where the endpoint of one connects to the start point of the other.
- Closure: Forms a closed path by linking the start and endpoint using the "h" operator.
- Current Clipping Path: Sets the page's clipping boundary to control the visible content area.
 

While these concepts may seem complex and can't be understood easily, a simple example can make them clear: imagine uploading a PDF to an editor and finding that the text cannot be edited or appears garbled. This issue could arise because some text in the PDF is drawn using paths, similar to outlines created with lines. These "paths" are versatile and can be used to create everything from shapes and dividers to text and images.
リアルタイム会議文字起こしで業務効率を最大化

会議やミーティングは、ビジネスにおいて重要な情報を共有するための場です。しかし、会議後に議事録を整理したり、重要な内容を見返す作業は意外と手間がかかります。特に、リアルタイムで議事録を取ることが求められる場面では、時間と手間が大きな課題です。そこで登場するのが「リアルタイム 会議 文字起こし」ツールです。

リアルタイムで会議を文字化
「リアルタイム 会議 文字起こし」は、会議中に話される内容を即座に文字化する技術です。これにより、会議が終了する前に議事録が完成するため、会議後の振り返りがスムーズになります。さらに、手動で議事録を取る必要がなくなり、会議に集中できるため、時間を有効に活用できます。

多くの企業やチームが、会議後に議事録を整理する時間を削減したいと考えている中で、このリアルタイム転写ツールは非常に有効です。特に、オンライン会議やリモートワークが増える中、リアルタイムでの議事録作成はますます重要になっています。

高精度の文字起こしツールでより効率的に
最新のAI技術を活用した会議文字起こしツールでは、音声認識の精度が非常に高く、複雑な会話や専門的な用語も正確に文字化できます。例えば、Soro.jpのようなプラットフォームを活用すれば、AIが会話の内容をリアルタイムでスムーズにテキスト化し、後から内容を見返すのも簡単になります。AI技術を駆使することで、会議内容の記録はさらに効率化され、情報漏れや誤解を防ぐことができます。

使い方は簡単
「リアルタイム 会議 文字起こし」のツールは、簡単な操作で使用できます。会議の開始時にツールを立ち上げ、会話を録音するだけで、自動的に文字化されていきます。複雑な設定や手間のかかる操作は不要で、誰でも簡単に利用できる点が魅力です。

また、会議後には自動で整理された議事録が提供されるため、後処理の時間を大幅に削減できます。特に、忙しいビジネスマンやチームメンバーにとっては、時間を無駄にせずにすぐに仕事に取り掛かれる点が非常に便利です。

日本のビジネスシーンに最適
日本の企業では、正確で迅速な議事録作成が求められます。会議の内容が正確に記録され、共有されることで、チーム全体の理解度が高まります。特に、Soro.jpのようなツールは、日本語に特化した高精度な音声認識技術を搭載しており、日本語の会話に対応するための機能が充実しています。これにより、日本のビジネスシーンでも高い信頼性を誇ります。

結論
リアルタイム会議文字起こしは、効率的な会議運営に欠かせないツールです。会議中の重要な内容を即座に文字化し、後からの整理作業を省略することができます。Soro.jpのようなAIベースの文字起こしツールを導入すれば、時間の無駄を省き、ビジネスの生産性を大幅に向上させることができます。会議の効率化を目指す企業や個人にとって、リアルタイムでの文字起こしは今後ますます重要な役割を果たすことでしょう。
【React】 #6 金額計算機アプリを作成

# はじめに
現在、Reactを習得するために、23種類のReactアプリ開発に取り組んでいます。
今回はその第6弾として、Reactで金額計算機アプリを作成しました。

https://qiita.com/xYasi/items/0e223b8be80006ef9933

# 要件
以下の要件を満たすことを目指しています：

- ユーザが「商品名」「金額」「消費税率」を入力可
- 消費税を計算して、税込み金額を表示
- 複数の商品をリストに追加し、最終的な合計金額を算出
- 日本円から他の通貨（USD, EUR など）への換算

# 作成したアプリのイメージ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3947973/eeaa2256-c3ff-fb48-df13-77563edbce8d.jpeg" width=80%>

# アプリ紹介動画
<iframe width="200" height="400" src="https://www.youtube.com/embed/VlH8lIuvFpQ" title="React Amount Calculator" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# 利用技術
- React
- TypeScript
- Vite
- Tailwind
- zod
- react hook form
- Bitifinex API

# 意識したポイント
## 為替レートの取得は`Bitifinex`の公開APIを利用
```typescript:fetchExchangeRate.ts
export const fetchExchangeRate = async (from: string, to: string) => {
  const url = `/api/v2/calc/fx`;
  const headers = { "Content-Type": "application/json" };
  const body = JSON.stringify({ ccy1: from, ccy2: to });

  try {
    const response = await fetch(url, {
      method: "POST",
      headers: headers,
      body: body,
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    return data[0];
  } catch (error) {
    console.error("Fetching error:", error);
    throw error;
  }
};
```
今回は税抜、税込金額だけでなく、為替レートを取得する外部APIを利用し、
アメリカドルとユーロを金額計算時に変換できるように実装しました。
[Bitifinex API](https://docs.bitfinex.com/reference/rest-public-platform-status#rest-public-calc-foreign-exchange-rate)

## CORS問題をプロキシで解決
```typescript:vite.config.ts
export default defineConfig({
  plugins: [react()],
  server: {
    proxy: {
      "/api": {
        target: "https://api.bitfinex.com",
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ""),
      },
    },
  },
});
```
当初、データフェッチ時にローカルサーバとBitfinexのオリジンが異なるため、
CORSポリシーでブロックされてしまいました。
そのため、プロキシサーバを介してフェッチするようにしました。
Viteでは、コンフィグに設定を追加し、`npm run`で実行するだけで
プロキシを簡単に設定できるため、非常に便利だと感じました。

# Github
GitHubにコードをアップロードしていますので、よかったら確認してみてください。

https://github.com/yasi1989/react-amount-calculator
Unityで作ったゲームをスマホでプレイするまで

この記事は東京海洋大学NePPのAdvent Calendar 2024の21日目です
# はじめに
今回はUnityで作ったゲームをADB（Android Debug Bridge）を利用してスマホにインストールし、実際にプレイするまでの手順を最近知ったので備忘録という意味合いもかねて記事にします
筆者の環境はWindows 11 HomeでGooglePixel4aを使っています

# ADBのインストール
まず[ADBの公式ページ](https://developer.android.com/tools/adb?hl=ja)からコマンドツールをインストールします。zipファイルがインストールされるのでこれを展開して好きなフォルダに保存します。
C直下に配置してしまうのがわかりやすいと思います。次に環境変数を設定するのでこのフォルダのパスをコピペしといてください
![スクリーンショット 
2024-12-31 194200.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620913/f8aea4b8-6ca9-ed7e-726e-8d298f40cd12.png)

# 環境変数の設定
次にユーザー環境変数画面のpathをダブルクリック→新規→先ほどのパスをペーストしてOK押下、ここまでやったら一度パソコンを再起動します

# コマンド
ターミナルを起動、adbと打つとなんやらいろいろでてきてそれっぽいメッセージがたくさん出てきます
![スクリーンショット 2024-12-31 195549.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620913/5134ba7d-53dc-4a49-6498-e87671bdeaba.png)
ここでパソコンとスマホをコードで接続します。自分はTypeCとTypeAのコードで接続しました

    adb devices
これがパソコンと接続されているデバイスのIDを調べるコマンドなのでこれを打ってスマホのIDを調べます
次にUnityのプロジェクトで作成したビルドファイル（ビルドの仕方については割愛）を保存しているフォルダまでcdコマンドで移動し

    adb -s [さっき調べたスマホのID] install [Unityで作成したビルドファイル名]
でビルドファイルをスマホにインストールします
少し時間がかかりますがコマンドラインの方にSucceessみたいなメッセージが出たら成功です
そうするとスマホにアイコンが表示されるのでそこからファイルを開くと作ったゲームで遊べます

# 終わりに
エディター上では問題なくても実機で挙動を確認してみるとなんかバグってる！みたいなことは割とあるのでたまに実機の方で挙動を見ておくのも必要なのかなと思います
メモリ vs 速度 vs 可読性、設計のトレードオフに向き合った経験

# Pythonのコレクション型、多すぎ...???

新卒入社1年目の2月。私はとあるシステムの開発にメンバとして入っていました。このシステムは実行時間とメモリ使用量がギリギリになることが当初から想定されており、データをlistで持つかdictにするかという設計のトレードオフに (個人的に) 直面していました。

## 悩んだトレードオフ

ここでは、listとdict、その他の選択についての具体的なトレードオフの悩みを掘り下げていきます。  

### メモリと計算時間を確保するならlist

- **メリット**: listはPythonの中でも単純な構造でメモリ使用量を抑えられます。またインデックスアクセスはO(1)で可能です。  
- **デメリット**: インデックスでアクセスする場合、後から見たときに可読性が低く、「なんのデータがどこに格納されてるんだっけ？」となりがちです。またリストの要素数が大きくなるとreallocateが時々発生します。とはいえ1要素ごとに起こるわけではなく、実測的にはそこまで大きな問題にはならないことが多いです。

### 可読性と柔軟性を確保するならdict

- **メリット**: dictはキーによるアクセスが可能なため、コードの可読性が大きく向上します。キーによるアクセスも通常O(1)で、要件次第ではlistとほぼ同等のパフォーマンスが期待できます。またPython 3.7以降では挿入順序を保持するため、順番が重要なデータでもある程度制御しやすくなりました。今回の実装の他の部分でdictの挿入順序が維持されることは使った記憶があります。
- **デメリット**: 内部的にハッシュテーブルを用いるため、要素数が同じでもlistよりもメモリ消費が高くなり2〜3倍以上かさむことも珍しくないとされているらしいですね (ChatGPT談)。

### Array, NamedTuple, dataclassの可能性

- **Array**  
  - メリット: メモリ効率が非常に高く、固定長＆同じ型の数値データなどには最適。  
  - デメリット: 異なる型を混在させることはできません。今回のケースでは数字と文字列を混在させる必要があり不向きでした。  

- **NamedTuple**  
  - メリット: listと同様にメモリ効率が良く、名前付きフィールドで可読性が向上します。多分これが最善でした。
  - デメリット: イミュータブル（変更不可）であり、特に現状のコードはミュータブルであることを使っていた記憶があるため、今からのリファクタは下手すると処理全体を書き直す必要があります。

- **dataclass**  
  - メリット: 名前付きフィールドがあり柔軟に扱えます。可読性も保たれます。  
  - デメリット: NamedTupleや純粋なlistに比べてメモリ消費が大きくなりがちです。イミュータブルにしてメモリ消費量を抑える場合は`frozen=True`オプションを使う方法もあるらしいです (ChatGPT談)。  

## 実際の選択とその理由

結局私はlistを選択しました。理由はメモリ制約と納期です。dictで実装してメモリが足りなかったときのやり直しコストが高すぎると判断しました。

## 結果と教訓

- システム自体はちゃんと動いたので大きな失敗にはなりませんでしたが、可読性に関してはどうしても犠牲になってしまいました。後任者がコードを読む際に苦労するのを目の当たりにして「もう少しコレクション型について知識を持っておくべきだった、特にdictやNamedTupleを試してみるべきだったかも」と振り返っています。  

大きな教訓としては以下の通りです。

1. **優先順位を明確にする**: メモリか速度か可読性か、それとも別の要素を重視するのか。  
2. **トレードオフをドキュメント化する**: なぜその選択肢を選んだか、後から説明できるようにまとめておく。  
3. **未来の拡張性を考える**: 今は要らないかもしれないが、後々の仕様変更や運用を見越して設計する。  
4. **多様なコレクション型を学ぶ**: listやdictだけでなく、NamedTupleやdataclassなどを知っておくと選択の幅が広がる。

## 参考文献

- [Pythonでリストを多用しがちな新人に贈りたい、array/tuple/set/queueの魅力と使い分けフローチャート](https://qiita.com/fujine/items/42cddf1cd13aedc6c4b8)
- [Choosing between List, Tuple and Dictionary](https://medium.com/swlh/choosing-between-list-tuple-and-dictionary-2fcb6d73cb60)
- [Python.org TimeComplexity](https://wiki.python.org/moin/TimeComplexity)
GitFlowについて今一度考える

年末最後に記事の投稿です。
毎回プロジェクトを立ち上げる際に考えるgitリポジトリの運用について。
プロジェクトの要件によって臨機応変に変えたいと思っているのですが、
なかなかうまくいかず...
いつも悩みの種となります。

今年も大きなプロジェクトを一つ立ち上げました。
そのgitリポジトリの運用についてまとめてみました。
来年、実際に稼働していってどう変わっていくかわかりませんが備忘録に残していきたいと思います！

## 前提
開発するものは下記になります。
- Webアプリ
- API

今回のプロジェクトは開発が下記の２チームに分かれています。
- **フロントデザイン反映チーム（略称：デザインチーム）**：Storybookを用いて画面のデザインのみ反映するチーム
- **フロントエンドロジック＆バックエンド実装チーム（略称：開発チーム）**：React＆APIを実装して、画面に動きをつけていく＆機能を追加していくチーム

今回のプロジェクトの性質上、開発中にデザイン変更がどんどん入っていくというところがあり、
**デザインと開発を分けて並行に作業が進められるようにしていきたい**
という意図からこのプロジェクト構成が生まれました。

また、１週スプリントでスクラムを進めるということで、
毎週、PO・ステークホルダーが開発した機能を確認して、細かい仕様修正・改善を決めていくことになります。
なので、必要な環境としては
- **開発環境(dev)**
- **PO・ステークホルダーが確認する検証環境（stg）**
- **実際に運用していく本番環境（prod）**

の**３環境**が必要となります。

そして、１つ大きな課題としては
- **リリースしたい機能を選んで本番環境にあげたい**

ということです。
上記を踏まえて、git運用を考えていきました。

## 基本のGitFlowを確認
よく記事にあるGitFlowを参考にしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396492/c818a3ff-3fcb-1833-bca6-8d7056724679.png)
ここで問題となるのは、
- 複数チームの並行開発はどうする？
- 機能を選んでリリースをしたい場合どうする?
になりました。

このGit-Flowをもとに、今回のプロジェクト構成に合わせた運用に変えて考えてみます。

## プロジェクトに適用したgit運用①
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396492/f3e347b5-924f-bfee-f237-50fdcbc898bc.png)

- featureブランチ（図のオレンジ色、紫色のブランチ）：
    - デザインチームがdevブランチからブランチを切り、仮デザインを反映
    - デザイン反映されたブランチから、開発チームがブランチを切り、ロジックを反映
    - 開発チームがロジック実装中に、デザインチームが仮デザインから本デザインを反映
    - 開発チームの成果とデザインチームの成果をまとめてdevelopブランチに反映 
        → この際に **squshマージを実施する！** 
        　※１機能分の成果物を１コミットにまとめるため

- developブランチ：
    - 開発した機能をここにまとめる
    - 開発環境とする
    - mainからブランチを切ります

- releaseブランチ：
    - mainブランチから切る
    - developブランチのcommit履歴からリリースするべきcommitをcherry-pick
        ※ ただし、この運用だと、どのcommitをリリースしたか、表にまとめておく必要がある
    - ブランチ名にリリース番号をつける
    - ここを検証環境とする
    - ここでテストを行い、アプリ動作に問題がなければmainにマージをする

- hotfixブランチ：
    - Issue番号をhotfixブランチ名とする
    - releaseブランチ・mainブランチにて修正が発生したら、それぞれのブランチからhotfixブランチを切ります
    - 修正したものは、最新のreleaseブランチにマージをして動作を確認します

- mainブランチ：
    - relaseブランチで動作が問題なければこちらのブランチにマージをします
    - こちらにマージをした時点で、developブランチを、mainブランチの最新へrebaseします

## プロジェクトに適用したgit運用②
開発を進める上で課題が出てきました。
デザインチームも開発チームも人数が１人以上いるため、
１機能を全員で開発するより、複数機能を並行で開発したほうがいいということになりました。
①の運用だと、１機能ができるまでdevelopにマージされないため、待ちが発生してしまいます。
そこで、featureブランチの運用方法を変えました。
各担当者がdevelopブランチからブランチを切り、
開発・デザイン反映をしてdevelopブランチにマージをしていく従来の方法です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396492/e78e8896-41d0-42ec-763f-1b7c53e14aa0.png)

## 今後の懸念点&課題
- developからリリースするものをピックアップする際に、もれなく機能ごとにピックアップできるのか
- mainブランチにリリース成果物をマージした際に、developブランチのrebaseがうまくいくのか

## まとめ
まだリリースをしていなので、来年どのようにこのgit運用の方法が変わっていくかわかりませんが、
今のところこのような形で動かす想定をしています。
commit履歴に沿ってリリースできればいいのですが、なかなか開発側にビジネス側が合わせることってできませんよね...
まだ課題もあるので、
両者が円滑に作業を進められるように、慎重に試していきたいと思いました。

駆け足で備忘録失礼しました...!
もし、ベストプラクティス等あれば共有いただけると幸いです！

もう今年もあと少しですね。
みなさん良いお年をお過ごしください！:hand_splayed:
paiza 勉強記録【残り物の量】【Java】

paizaでの勉強記録です。
今回は下記のレベルアップ問題集のCランク問題の「残り物の量」を実施しました。

``` java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
//        仕入れ量
        int purchaseQuantity = sc.nextInt();
//        生のまま売れた割合
        double saledRatioOfRaw = sc.nextDouble()/100;
//        惣菜にして売れた割合
        double saledRatioOfDishes = sc.nextDouble()/100;
//        生のまま売れた量（kg）
        double saledQuantitiyOfRaw = purchaseQuantity * saledRatioOfRaw;
//        惣菜にして売れた量（kg）
        double saledQuantitiyOfDishes = (purchaseQuantity - saledQuantitiyOfRaw) * saledRatioOfDishes; 
//        売れ残りの量（kg）
        double leftoverStock = purchaseQuantity - (saledQuantitiyOfRaw + saledQuantitiyOfDishes);
        
        System.out.println(leftoverStock);
        
        sc.close();
    }
}
```