OmniAICreator/Qiita-1.07M huggingface dataset:
Power Apps複数行テキストの改行や空白をPower Automateで保持する方法

## やりたいこと
下図のような複数行テキスト(リッチテキストではなくプレーンテキスト)をPower Automateを使ってメールやTeamsで改行や空白を保持したままにしたい！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/2888d03b-b0de-3e9f-6e21-ab8aade0cd99.png)

## 方法
例えば下図のようなフローで、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670355/e8c0fc64-f3a2-f3a5-bd15-cadc0d138a62.png)

`Compose`アクションで↓をすればOK。
```
uriComponentToString(
    replace(
        replace(
            replace(
                uriComponent(triggerBody(['text']),
                '%0D%0A','<br>'
            ),
            '%0A','<br>'
        ),
        '%0D','<br>'
    )
)
```

コピペ用
```
uriComponentToString(replace(replace(replace(uriComponent(triggerBody()['text']),'%0D%0A','<br>'),'%0A','<br>'),'%0D','<br>'))
```

`%0D%0A`、`%0D`、`%0A`の改行コードをHTMLの改行コード`<br>`に変換している。

最後にメールやTeams等へ出力する際に`<pre> </pre>`で囲んであげると空白も保持される。

## 謝辞
[こちらの記事](https://qiita.com/h-nagao/items/af18eb357bc7c8bec3a2)を参考にさせていただきました。ありがとうございます！
【AWS】Glacierの種類・覚え方についてまとめてみました

# 1.はじめに
どうも、ARIの名古屋支社に勤務している愛知県民こと、
新藏（にいくら）と申します♪
(/・ω・)/

引き続きSAAのお勉強をしていますが、
3年前と比べるとGlacierの名前が微妙に変わっている部分がありました。

そこで**今回はGlacierの種類について**記事にしたいと思います！
AWSやSAAを勉強中の方の参考になれば幸いです。
(*^^)v

# 2.Glacierとは
まず初めにGlacierとは何かですが、
**GlacierはS3のストレージクラスの1つで、
データのアーカイブを主としたストレージとなります。**

厳密には以下の3種類があり、この後の節で説明します。
- **S3 Glacier Instant Retrieval**
- **S3 Glacier Flexible Retrieval**
- **S3 Glacier Deep Archive**

:::note info
ちなみにGlacierは「グレイシア」と読み、日本語にすると「氷河」です。
**氷河のイメージから、データを凍らせて長期保存しておく**
と覚えています。

氷タイプのポケモン、グレイシアも同じ語源な気がします♪
:::

また、AWS公式には以下の記述があります。

>Amazon S3 Glacier ストレージクラスは、データアーカイブ専用に設計されており、
>クラウドで最高のパフォーマンス、最高の検索の柔軟性、最低のコストのアーカイブストレージを提供します。

>すべての S3 Glacier ストレージクラスは、事実上無制限のスケーラビリティを提供し、
>データの耐久性が 99.999999999% (11 ナイン) を実現できるように設計されています。

>S3 Glacier ストレージクラスは、アーカイブデータへの最速のアクセスとクラウド内の最低コストの
>アーカイブストレージのためのオプションをもたらします。

引用：https://aws.amazon.com/jp/s3/storage-classes/glacier/

## 2.1.S3 Glacier Instant Retrievalとは
S3 Glacier Instant Retrieval とは、
以下の特徴を持つストレージクラスとなります。

|項目|説明|
|---|---|
|保存したデータへのアクセス頻度 | 3か月に1回ほど |
|保存したデータの取り出し速度 | ミリ秒単位 |
|料金 | Glacierの中では一番高い |

料金はGlacierの中では一番高いですが、すぐにデータを取り出せるので、
アーカイブしておきたいが取り出しも必要なデータを保存するストレージとなります。

:::note info
「Instant」なので
インスタントラーメンは素早く作れるが、袋麺よりも高いことをイメージして、
**S3 Glacier Instant Retrievalは素早くデータを取り出せるが、
(他のGlacierよりも)料金が高い**と覚えています。
:::

## 2.2.S3 Glacier Flexible Retrievalとは
S3 Glacier Flexible Retrievalとは、
以下の特徴を持つストレージクラスとなります。

|項目|説明|
|---|---|
|保存したデータへのアクセス頻度 | 1年に1,2回ほど |
|保存したデータの取り出し速度 | 数分から数時間、迅速・大容量取り出しも可能|
|料金 | Instant Retrievalより安く、Deep Archiveより高い |

アーカイブはするが、稀に取り出しが必要なデータを保存するストレージとなります。
また、迅速・大容量取り出しの両方が可能なので汎用性も高いです。

:::note info
3年前は名前が「Glacier」だったストレージクラスとなります。
:::

## 2.3.S3 Glacier Deep Archiveとは
S3 Glacier Deep Archiveとは、
以下の特徴を持つストレージクラスとなります。

|項目|説明|
|---|---|
|保存したデータへのアクセス頻度 | 1年に1回未満 |
|保存したデータの取り出し速度 | 数時間から数日、大容量取り出しも可能|
|料金 | Glacierの中では一番安い |

料金は安いのですが、取り出すのに数時間から数日かかるため、
長期保存してほとんど取り出されないデータを保管するストレージとなります。

:::note
「Deep」なので深海にある氷河をイメージして、
**長期保存するのに適しているが、氷河(データ)を引き上げるのに時間がかかるイメージ**
で覚えています。
:::


# 3.おわりに
ここまで読んで下さり、ありがとうございます！！！
(^^)

今回はGlacierについてまとめてみました。
次回も何かしら記事にしたいと思います♪
(:3_ヽ)_
【Next.js】シンプルなタブ切り替えの実装

## はじめに
1画面に複数コンテンツがあり、タブをクリックすると選択中のタブと配下のコンテンツが切り替わる機能を実装していきます。

（前提条件）
・Next.jsのプロジェクトを作成済みであること

## 実装
### ディレクトリ構成

     (プロジェクトのルート)
     ┣━ app
     ┃  ┗━ page
     ┃    ┗━ page.tsx (表示ページ)
     ┣━ components
     ┃   ┗━ tab
     ┃     ┣━ wrapper
     ┃     ┃  ┗━ Menu.tsx (タブ)
     ┃     ┃  ┗━ Contents.tsx (コンテンツを表示するエリア)
     ┃     ┗━ contents
     ┃        ┣━ Content1.tsx (コンテンツ)
     ┃        ┣━ Content2.tsx (〃)
     ┃        ┗━ Content3.tsx (〃)
     ┗━ styles
        ┗━ tabstyle.css (css)
     
### プログラム
```tsx:page.tsx
'use client';
import Contents from '@/components/tab/wrapper/Contents';
import Menu from '@/components/tab/wrapper/Menu';
import { createContext, useState } from 'react';

export const TabContext = createContext(
  {} as {
    tabIndex: number;
    setTabIndex: React.Dispatch<React.SetStateAction<number>>;
  },
);

export default function Page() {
  const [tabIndex, setTabIndex] = useState(0);

  return (
    <>
      <TabContext.Provider value={{ tabIndex, setTabIndex }}>
        <Contents />
      </TabContext.Provider>
    </>
  );
}
```

```tsx:Menu.tsx
import { useContext } from "react"
import  "@/styles/tabstyle.css"
import { TabContext } from "@/app/page/page"

export default function () {
  const  {tabIndex, setTabIndex } = useContext(TabContext)
  return (
    <>
    <div style={{display: "flex"}}>
      <div onClick={() =>setTabIndex(0)} className={`tab ${tabIndex === 0 && "selected"}`}>tab1</div>
      <div onClick={() =>setTabIndex(1)} className={`tab ${tabIndex === 1 && "selected"}`}>tab2</div>
      <div onClick={() =>setTabIndex(2)} className={`tab ${tabIndex === 2 && "selected"}`}>tab3</div>
    </div>
    </>
  )
}
```
```tsx:Contents.tsx
import { useContext } from 'react';
import Menu from './Menu';
import { TabContext } from '@/app/page/page';
import Content1 from '../contents/Content1';
import Content2 from '../contents/Content2';
import Content3 from '../contents/Content3';
export default function () {
  const { tabIndex, setTabIndex } = useContext(TabContext);
  return (
    <>
      <Menu />
      {tabIndex === 0 && <Content1 />}
      {tabIndex === 1 && <Content2 />}
      {tabIndex === 2 && <Content3 />}
    </>
  );
}
```
※Contents2, Content3は数値部分を変えるのみなので省略
```tsx:Content1.tsx
export default function Content1() {
  return <>content1</>;
}
```
```css:tabstyle.css
.tab {
  padding: 0px 10px
}
.tab.selected {
  background-color: lightblue;
  text-decoration:underline;
}
```
## 画面イメージ
タブを押すと選択中のタブとコンテンツが切り替わります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410887/d364be1e-2967-249f-6c3d-02bafac09be6.png)

## 最後に
選択中のタブを状態管理する`useState`を親要素にて定義し、子に`props`で`state`をセットする関数を渡す方法もあります。

拡張性も考えると孫要素でも`props`のバケツリレーをせずに`state`を使用できるこちらの方が優れているため`useContext`を採用しました。

ご指摘、コメントあれば是非よろしくおねがいします m(_ _)m
登録セキスペ オンライン講習 2023 参考資料備忘録 #2

この記事は、#1に引き続き、登録セキスペ オンライン講習で取り上げられている資料の中で、後日時間を取って再度目を通したいと思う物のリンクを忘れないようにまとめておくことを目的としています。

https://qiita.com/y-vectorfield/items/92e22ee6a09c66c0c96d

# セキュリティ・バイ・デザインガイドライン
セキュリティはアドオンではなく、設計の初期段階から考慮して開発を進めるという考えに則ってセキュリティ・バイ・デザインで開発を進めることが近年求められています。これはデジタル庁が公開している指針なので参考になると思います。

https://www.digital.go.jp/assets/contents/node/basic_page/field_ref_resources/e2a06143-ed29-4f1d-9c31-0f06fca67afc/2a169f83/20220630_resources_standard_guidelines_guidelines_01.pdf

# セキュリティ・バイ・デザイン指南書
実際にセキュリティ・バイ・デザインで開発を進めるにしてもどうやって進めたら良いのだろうと困った時に、この資料を参照することで、各工程で必要となるプロセスが簡潔に説明されています。

https://www.ipa.go.jp/jinzai/ics/core_human_resource/final_project/2022/ngi93u0000002kef-att/000100451.pdf

# ゼロトラストアーキテクチャ適用方針
またまたデジタル庁公開資料。ゼロトラストアーキテクチャ適用する意義についてまとめられている。

https://www.digital.go.jp/assets/contents/node/basic_page/field_ref_resources/e2a06143-ed29-4f1d-9c31-0f06fca67afc/5efa5c3b/20220630_resources_standard_guidelines_guidelines_04.pdf

# ゼロトラスト導入指南書
指南書シリーズは図表入りで詳しく説明されていてガイドラインとは大きく異なります。ガイドラインはどちらかと言うとお役所の書類、指南書は専門書の様な見た目です。筆者もゼロトラストについてこれらの資料を再読して、より理解を深めたいです。

https://www.ipa.go.jp/jinzai/ics/core_human_resource/final_project/2021/ngi93u0000002klo-att/000092243.pdf

# 非機能要求グレード
非機能(特にセキュリティ)は”暗に要求”されている仕様なのが厄介。。。その設計には機能設計とはまた違った難しさが。。。

https://www.ipa.go.jp/archive/digital/iot-en-ci/jyouryuu/hikinou/ent03-b.html
無料の生成AI,Liamaをコーチングに使ってみた結果

### 生成AIをコーチングに使ってみた理由

最近読んだビジネス書に、生成AIはコーチングにも使えるということとその具体例が載っていたためやってみたいと考えた

### Liamaを選んだ理由

無料で使用できる高性能な生成AIのため。また、LPI-Japan様の理事長でいらっしゃる成井先生の
講義でLiamaのお話をされており、一度使ってみたいと考えていたため

### Liamaをどのように始めたか

始め、LiamaをWSLにインストールしようとしたが、Linux初心者で英語も不得手のため失敗してしまったので、手続きなしでLiamaを使用できるこちらのサイトで実施した

https://labs.perplexity.ai/

### コーチングの結果

①最初の質問
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533750/aae83068-38fd-f6b1-d34e-546db784d48a.png)

②Liamaがくれた回答

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533750/8f8f6326-3026-15fe-c30b-e51b9260d84a.png)

コーチングを受けるメリットやコーチングの効果などについて答えてくれる

③自分の強みを出してみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533750/64537e88-a9e7-6424-eb08-692fd37c6840.png)

強みを磨き活かし続けるためには何をすればいいか教えてくれる

④自分の課題を出してみた、その1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533750/3f64283f-66a6-8c47-3566-bb3b9d19c275.png)

プロンプトが悪かったのか、前とほぼ同じ回答を返してきた

⑤自分の課題を出してみた、その2

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533750/a739369b-0521-85d1-ad20-830ca2ed9aa6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533750/e9b50572-0d30-66c3-94a6-50cce8b3485c.png)

まだ少し強みの時の話を続けているものの、課題に対しての解決方法をいくつか教えてくれた

### 今後検証したいこと

・文章が英語の直訳のように見えるため、英文で質問すれば回答の精度が上がるのかやってみたい

・何回ぐらい、どんなプロンプトで聞くと完全に答えてくれるかやってみたい

### 参考文献

「キーエンス思考」×　ChatGPT時代の付加価値仕事術　田尻望　日経BP　2023
vim.keymap.setでマッピング対象に関数を使う

```vim.keymap.set```はLuaでNeovimのキーバインドを記載するためのユーティリティとして知られているが、マッピング対象に関数を使うときは、関数を直接呼び出すのではなく、関数自体が帰るように書く必要があるようである。

- vim.keymap.setについて

https://neovim.io/doc/user/lua.html#vim.keymap.set()

例えば、以下のようにカーソルの位置を取得する関数```func()```をマッピング対象とすることを考える。
```vim.keymap.set```から関数を直接呼び出しても、関数が正しく評価されない（常に0が帰ってくる）

```lua
local function func()
  return tostring(vim.api.nvim_win_get_cursor(vim.fn.win_getid())[2])
end

-- 現在のカーソル位置を正しく取得できない
vim.keymap.set('i', '^', func(), {expr = true})
```

関数```func()```が正しく評価されるためには、関数自体を返す必要があるようである。
以下のように書くことで、カーソル位置が正しく取得できるようになった。

```lua
local function func()
  return function()
    return tostring(vim.api.nvim_win_get_cursor(vim.fn.win_getid())[2])
  end
end

vim.keymap.set('i', '^', func(), {expr = true})
```

またはインライン的に書くこともできる。

```lua
-- 式を埋め込むと正しく取得できる
vim.keymap.set('i', '^',
  function()
    return tostring(vim.api.nvim_win_get_cursor(vim.fn.win_getid())[2])
  end,
{expr = true})
```
OSSに初めてコントリビュートした話

## なぜコントリビュートしたのか？
普段色々なOSSにお世話になっているので、コントリビュートで貢献したい！と考え始めたことがきっかけです。

## 今回コントリビュートしたOSS
openEMRという電子カルテの管理などの医療業務系のOSSです。
公式サイト：https://www.open-emr.org/

## コントリビュートの流れ
ざっくりこんな感じです。
OSSごとに個別のルール・手順などがあるので、行ってみる場合はリポジトリのREADMEやInsightsなどのコントリビュート関連のドキュメントをまず確認してください。

・やりたいIssueを取る
・リポジトリをFork
・ブランチを切る
・対応してPR作成
・レビュー
・マージ（レビューでフィードバックがあれば対応）

## コントリビュートの概要
今回コントリビュートで修正したのは[こちらのIssue](https://github.com/openemr/openemr/issues/7393)で、新しいユーザーを追加する際に、emailログイン項目で入力した値が反映されない、というものでした。
これくらいの内容ならできるかも、と思ったので他のIssueの様子を見つつ、やってみてもいいか聞きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951281/66eb4781-c1db-cc5a-d06d-3aa4f6a9fbe1.png)

もちろんいいよ！（意訳）と言っていただけたので業務後や休日に取り組みつつ、5日ほどで動作確認までできたのでPRを出しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951281/461a6adb-3e8c-a7fa-3d42-600e3a93ca3f.png)

PRは[こちら](https://github.com/openemr/openemr/pull/7472)です。
修正内容は、Insert処理内にemail用のものを追加してあげるというもの。
レビューしていただいてOK&マージしてもらったので、今後のパッチでリリースされるとのことです🙌

## コントリビュートしてみて
英語でのやり取りになるのでハードルが高いなと感じていましたが、意外と何とかなるんだなーと思いました。
翻訳ツールも優秀かつ色々あるので、大まかに内容は掴めますし、伝えたいこともある程度組み立てられます。
細かいニュアンスは自分で色々調べつつ、というのも知らないことが多くて楽しかったです！
また、レビューでこういう書き方もできるけどどう？という風にフィードバックいただけたのもありがたかったです。
普段業務で関わっているチーム外の方からレビューしてもらうのはすごく貴重な経験でした。

## 参考
今回取り組むにあたってIssue探しなど下記の記事・サイトを参考にさせていただきました！
[初めてOSSにコントリビュートしました](https://qiita.com/yutotakakura/items/29b643c851e6ad01c7c8)
[PHPの業務経験6ヶ月で初めてOSSにContributeした話](https://zenn.dev/y640/articles/qiita-20210909-66cd4f362d3e2106c628)

### 下記のサイトでIssueを探すことができます！
[Let's Contribute!](https://lets-contribute.netlify.app/)←日本語でコントリビュート出来るので言語面でのハードルは低いかも
[Good First Issue](https://goodfirstissue.dev/)←初心者向けのIssueを見つけられます🔍
KotlinのコルーチンにおけるFlowについて

Kotlinのコルーチンにおける`Flow`, `SharedFlow`, `StateFlow`は、それぞれ異なるリアクティブなデータストリームを表現するためのツールです。それぞれの使い方と用途について詳しく説明します。

### Flow

`Flow`は非同期データストリームを表現するために使用されます。これはCold Streamであり、コレクションが開始されるとデータの生成が始まります。

#### 基本的な使い方

```kotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun simpleFlow(): Flow<Int> = flow {
    for (i in 1..3) {
        delay(100) // 模擬的な非同期操作
        emit(i)   // データを発行
    }
}

fun main() = runBlocking {
    simpleFlow().collect { value ->
        println(value)
    }
}
```

### SharedFlow

`SharedFlow`はHot Streamであり、複数のコレクターが同じデータストリームを共有します。`SharedFlow`はイベントを共有するために使用され、通常、複数のリスナーが存在する場合に利用されます。

#### 基本的な使い方

```kotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun main() = runBlocking {
    val sharedFlow = MutableSharedFlow<Int>()
    
    launch {
        sharedFlow.emit(1)
        sharedFlow.emit(2)
        sharedFlow.emit(3)
    }
    
    sharedFlow.collect { value ->
        println("Collector 1: $value")
    }

    sharedFlow.collect { value ->
        println("Collector 2: $value")
    }
}
```

### StateFlow

`StateFlow`は`SharedFlow`の特殊な形で、現在の状態を保持し、状態が変わるたびに更新を通知します。これもHot Streamであり、状態管理に適しています。

#### 基本的な使い方

```kotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun main() = runBlocking {
    val stateFlow = MutableStateFlow(0)
    
    launch {
        repeat(3) {
            delay(100)
            stateFlow.value = it
        }
    }
    
    stateFlow.collect { value ->
        println("Collector: $value")
    }
}
```

### Flow vs SharedFlow vs StateFlow

1. **Flow**:
   - Cold Stream。
   - コレクションが開始されたときにデータの生成が開始される。
   - 各コレクターは独自のデータストリームを受け取る。

2. **SharedFlow**:
   - Hot Stream。
   - 複数のコレクターが同じデータストリームを共有する。
   - データの履歴を保存するため、遅れてコレクトを始めた場合でも過去のデータを受け取れる。

3. **StateFlow**:
   - `SharedFlow`の特殊な形で、状態を保持するために使用。
   - 常に最新の状態を保持し、その状態が変わるたびに通知を送る。

### 使用例

#### 状態の管理

`StateFlow`は、状態を管理するのに非常に便利です。たとえば、UIの状態を管理するために使われます。

```kotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

class ViewModel {
    private val _state = MutableStateFlow("Initial State")
    val state: StateFlow<String> = _state

    fun updateState(newState: String) {
        _state.value = newState
    }
}

fun main() = runBlocking {
    val viewModel = ViewModel()
    
    launch {
        viewModel.state.collect { value ->
            println("State: $value")
        }
    }
    
    delay(1000)
    viewModel.updateState("New State")
}
```

このように、`StateFlow`を使ってUIの状態をリアクティブに管理することができます。`SharedFlow`はイベントストリームの共有に、`Flow`は非同期データストリームの処理にそれぞれ適しています。用途に応じて適切なツールを選択することで、Kotlinのコルーチンをより効果的に活用できます。
LeetCode挑戦日記：Day6

# はじめに

最近、業務で実装する時間よりも資料作成やレビューをする時間が多くなってきました。
このままでは自身のコーディング能力が落ちそうで怖いので、LeetCodeを始めてみました。

自身の学習の記録 & LeetCodeに興味のある人が挑戦しやすいように、記事に残していきます。
このような競技プログラミングをした経験がないので、ひよってEasyからやっていきます...

# [Medium] 151. Reverse Words in a String

インプット：文字列
アウトプット：文字列

インプットの文字列が文章になっているので、単語単位で逆順にしたものをアウトプットとして返す。
余分はスペースが入っている場合は、削除して返す。

## 素直に解いてみる

### 考え方

1. インプットの文字列から単語を取得する
1. 取得した単語をスペースで連結する

### コーディング

```typescript
function reverseWords(s: string): string {
    return s.split(' ').filter((c) => c !== '').reverse().join(' ');
};
```

### 結果

Runtime：50ms
Beats 91.96% of users with TypeScript

Memory：51.96MB
Beats 31.76% of users with TypeScript
【Powershell】コマンドに別名を付ける

# はじめに

Linuxだと`alias`コマンドを使って、コマンドの別名を登録することが出来るので、以下のように`vi`コマンドを`vim`に変えることがあります。
このような仕組みがWindowsに存在するのか調べたところ、簡単に利用できる方法があったので備忘録として記事をまとめてみました。

```shell:
alias vi='vim'
```

# 別名を付ける方法

* `Set-Alias -Name {別名} -Value {コマンド名}`という構文で、簡単に別名を付けることが出来ます。
  * 簡単とは言っても、`alias`に比べたらちょっと長い構文ですが...
* 以下は`findstr`コマンドに対して、Linuxのように`grep`という名前を付けて実行した結果ですが、本来の名前でも別名でも同じ結果が得られていることが分かります。
* `Set-Alias`で付けた別名は、「現在のPowerShellセッション」でしか使えない点に注意が必要です。

```powershell:実行結果
# findstrコマンドにgrepという別名を付ける。
Set-Alias -Name "grep" -Value findstr

# findstrコマンドを実行する。
dir | findstr Pict
d-r---        2023/12/23      0:34                Pictures

# grepという別名でfindstrコマンドを実行する。
dir | grep Pict
d-r---        2023/12/23      0:34                Pictures
```

# 参考URL

* [Set-Alias - Microsoft Learn](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/set-alias?view=powershell-7.4)
構造体とインデクサ

## はじめに
classとstructの違いをきちんと意識せずに使ってたらエラーが出たよ、というだけの話です。常識と言えば常識な感じのネタなので、こんなの常識、と思う方はスルーしてください😅
* こんなの何に使うの？
使いたい時もあるんです。
* 構造体はイミュータブルが常識では？
それは知ってる。
* ただの配列のほうがいいんじゃ？
話せば長くなるので。

## ことの発端
パフォーマンスが気になる用途で、構造体のList<>を使おうとした時でした。
```cs
// 再現例
List<Point> points = new List<Point>();
points.Add( new Point( 0, 0 ) );
points[ 0 ].X++;  // エラーCS1612
```
このコードは、コンパイルエラーになります。
> エラーCS1612 変数ではないため、'List<Point>.this[int]' の戻り値を変更できません

## 何が起きてる？
簡単なコードで再現してみましょう。
```cs
// あくまで再現例
class Points {
    private Point[] points = new Point[10];

    public Point this[int index] {
        get {
            return points[index];
        }
        set {
            points[index] = value;
        }
    }
}

Points points = new Points();
points[0].X = 1;  // エラーCS1612
```
Pointは構造体(struct)なので、値型です。インデクサのgetは、int型２個分、合わせて８バイト分のメモリ領域を、points配列の中から**コピーして**直に戻してきます。
コピーしてきた戻り値を変更しても無駄なのは、お気づきの通り。それを指摘しているのが、この、エラーCS1612です。

## さてどうする - その１
パフォーマンスを犠牲にして、新しいPointを作って差し替えます。これなら構造体もイミュータブルでいられます。素晴らしいね！
```cs
points[0] = new Point( points[0].X + 1, points[0].Y );
```
## さてどうする - その２
パフォーマンスを犠牲にして、構造体をあきらめてクラスにします。クラスなら参照型なので、自由に変更できます。
```cs
class MyPoint {
    public int X;
    public int Y;
}
```

## 結局どうした？
パフォーマンスを犠牲にしたくなかったので、独自のListモドキを実装しました。その中で使ったのが**参照戻り値**というやつ。
```cs
// あくまで再現例
class Points {
    private Point[] points = new Point[10];

    public ref Point this[int index] {
        get {
            return ref points[index];
        }
    }
}

Points points = new Points();
points[0].X = 1;  // エラーにならない！
points[1] = new Point( 1, 1 );  // まるごともいけるよ！
```
こうすることで、getインデクサは、points配列の中の一つの要素の**参照（ポインタ）** を返すようになります。これによって、参照型の場合と同じように、メンバ変数を自由に変更できるようになります。
またこの場合、setインデクサは必要ありません。代入式の左辺に書かれた場合は、getインデクサが返す参照先のメモリ領域に、直にコピーされます。

今回はインデクサ絡みの問題でこの問題に気付いたのですが、構造体を返すプロパティでもよくあるケース、みたいですね。
GitHubリポジトリのライセンスの違い

# はじめに

GitHubでリポジトリを公開したことがある方は多いと思いますが、ライセンスの設定はちゃんとできていますか？
そもそも各ライセンスの違いを理解していますか？
恥ずかしながら僕はよくわかっていませんでした。。。

そこで代表的なライセンスの違いを整理しました。
理解が怪しかった方はご確認ください。

# ライセンス

以下に、代表的なライセンスを記載しています。
それぞれの特徴を理解しましょう。

## Apache License

誰でもソフトウェアの使用や頒布、修正、派生版の頒布をしてよい。
著作権表示と本許諾表示は、ソフトウェアに記載しなければならない。
ソフトウェアになんらかの修正が施された場合は、その旨を追加で記載する必要がある。
作成者や著作権者は、ソフトウェアに対してなんら責任を負わない。

## BSD License (3-clause BSD license)

著作権表示と本許諾表示は、ソフトウェアに記載しなければならない。
作成者や著作権者は、ソフトウェアに対してなんら責任を負わない。
書面上の許可なく開発者の名称を派生物の宣伝や販売促進に使用してはいけない。

## GNU Generic Public License

著作権表示と本許諾表示は、ソフトウェアに記載しなければならない。
作成者や著作権者は、ソフトウェアに対してなんら責任を負わない。
ソフトウェアになんらかの修正が施された場合は、その旨を追加で記載する必要がある。
GPLライセンスを利用して作成されたソフトウェアは、頒布時にソースコードを公開しなければならない。


## MIT License

誰でも無償かつ無制限に扱ってよい。
著作権表示と本許諾表示は、ソフトウェアに記載しなければならない。
作成者や著作権者は、ソフトウェアに対してなんら責任を負わない。

# おわりに

各ライセンスの違いは理解できましたか？
自分が書いたコードを公開するときには、適切なライセンスを付与するようにしましょう！
batの構文

### はじめに
最近batを作ったので、自分用にbatの構文をまとめておきます。
随時更新するかも？

### 基本的なbatの構文
#### **1. set 変数**
1)set [\<variable>=[\<string>]]
2)set [/p] \<variable>=[\<promptString>]
3)set /a \<variable>=\<expression>

| パラメーター | 説明 |
|:-----|:----|
| \<variable> | 環境変数の指定  |
| \<string>　  | 指定された環境変数に関連付ける文字列  |
| \/p  | \<variable> の値をユーザーが入力した入力行に設定 |
| \<promptstring>   | 入力をユーザーに入力を求めるメッセージを指定。このパラメーターは、/p パラメーターと共に使用の必要あり。  |
| /a | \<string> を評価される数値式に設定します。  |
| \<expression>　  |  数値式の指定 |
|  /? | コマンドプロンプトにヘルプの表示  |

```
1) set [<variable>=[<string>]]
```
```bat:例1
set x=3
set y=%x%+5
echo %y%
3+5
```
文字列の連結になってます。
```bat:例2
hoge.bat <引数入力>

set /a count=%1
echo 作成数：%count%
```
cmdでbatの後に数値を入力すると、上記の変数countに追加される。


```
2) set [/p] \<variable>=[\<promptString>]
```
```bat:例
set /p again=繰り返しますか？(y/n)：
if /i "%again%"=="y" (
echo.
goto loop
) else if /i "%again%"=="n" (
echo.
echo バッチを終了します。
) else ( echo yまたはnを入力してください。
goto loop
```
上記は、繰り返しをy/nの入力で制御しています。
y = loop、n = bat終了
実は、自分で作成したbatの抜粋です。
loopの定義はここには記載していないので、お好みの処理で使用してください。

```
3)set /a \<variable>=\<expression>
```
```bat:例
set x=3
set /a y=%x%+5
8
echo %y%
8
```
/aを外すと、文字列の連結になります。
1)の内容ですね。

#### **2. for 構文**
・for /L %%変数名 in (初期値,増値,終了値) do コマンド名
```bat:例
for /l %%i in (1,1,%count%) do (
 type NUL > %folder%\nul_testfile_%%i.txt
)
```
初期値を1として、1ずつ増加させていき、%count%まで、nul_testfile_<変数>.txtを作成する
※数値は整数の必要あり（負の値も使用可）

#### **3. loop 構文**
・:loop ~ goto loop
```bat:例
:loop
echo 使用する番号を選択してください。
set /p x="1.hoge1 2.hoge2 3.hoge3 :"

if "%x%" == "1"(
 echo 1.hoge1 が選択されました。
) else if "%x%" == "2"(
 echo 2.hoge2 が選択されました。
) else if "%x%" == "3"(
 echo 3.hoge3 が選択されました。
) else (
 echo 有効な値を入力してください。
goto loop
)

echo.
set /p again=繰り返しますか？(y / n)：
if /i "%again%"=="y" (
echo.
goto loop
) else if /i "%again%"=="n" (
echo.
echo バッチを終了します。
) else ( echo yまたはnを入力してください。
goto loop
```
【C#】WPFで簡素なC言語用のエディタを作ってみる

# はじめに
WPFの学習の一環として，C言語プログラムのコンパイル・実行をボタンクリックで行えるような簡素なテキストエディタを作った.

Javaの学習に使った「JCPad」が，使い方もシンプルで簡単にコンパイル・実行ができてとても使いやすかった. そのため今回は，シンプルなうえ，ボタンクリックによってコンパイル・実行が簡単にできるような，gcc用のエディタを目指した.

---
JCPadはこちらから入手できます. フリーソフトです.

https://hp.vector.co.jp/authors/VA017148/

---
# 画面
![editor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627120/7e4f0dbd-fa66-2d34-4366-bb0915133569.png)

メニューバーの構成は，
- File 
- - 新規作成
- - 開く
- - 名前を付けて保存
- - 上書き保存
- Edit
- - カット
- - コピー
- - ペースト
- build
- - コンパイル
- - コンパイル&実行

ツールバーは，左から
- 新規作成
- 開く
- 保存
- コンパイル
- コンパイル&実行

となっている.
行番号がふられているテキストボックスでファイルの編集を行い，コンパイルの標準出力・標準エラー出力は，下のテキストボックスに表示されるようになっている. 実行ボタンを押すとコマンドプロンプトが開き，実行結果が表示される.

今回，ファイルの編集を行うテキストボックスには`AvalonEdit`を利用した. シンタックスハイライトや行番号などの機能が搭載されているため，とても簡単に実装ができる.

---
ツールバーのアイコンはこちらのサイトを利用しました.
コンパイルのアイコンは自分で作ったので，異様にガビガビです.

https://icon-rainbow.com/

---

# 課題
### コンパイルのコマンドがいじれない

コンパイルプロセスの内容は以下のようになっている.

```C#: C#
// filePath: コンパイル対象のファイルのpathを表すstring型変数
string exeFileName = Path.ChangeExtension(filePath, ".exe");
ProcessStartInfo compileStartInfo = new ProcessStartInfo
{
    FileName = "gcc",
    Arguments = $"-finput-charset=UTF-8 -fexec-charset=UTF-8 \"{filePath}\" -o \"{exeFileName}\"",
    RedirectStandardOutput = true,
    RedirectStandardError = true,
    UseShellExecute = false,
    CreateNoWindow = true
};
```

`gcc -finput-charset=UTF-8 -fexec-charset=UTF-8 hoge.c -o hoge.exe`というコマンドしか実行できない.
例えば，他ファイルの関数を使うようなプログラムや，MakeFileを使ったコンパイルを実行することはできない.

まだ，気づいていないだけでもっと問題があるかもしれないという不安を抱えたプログラムである.

### 括弧・引用符の補間が使いづらい
```C#: C#
private void EditorTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
    string? insertText = null;

    if (e.Key == Key.D8 && (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
    {
        insertText = "()";
    }
    else if (e.Key == Key.D2 && (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
    {
        insertText = "\"\"";
    }
    else if (e.Key == Key.OemOpenBrackets)
    {
        insertText = "[]";
        if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
        {
            insertText = "{}";
        }
    }
    else if (e.Key == Key.D7 && (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
    {
        insertText = "\'\'";
    }

    if (insertText != null)
    {
        int selectionIndex = textEditor.CaretOffset;
        textEditor.Document.Insert(selectionIndex, insertText);
        textEditor.CaretOffset = selectionIndex + 1;
        e.Handled = true;
    }
}
```

ファイルの編集を行うテキストボックスEditorTextBoxのPreviewKeyDownイベントで，括弧・引用符の判定を行い，該当したら両側を挿入し，カーソルを間にもってくる処理が行われる.

改行を行わない場合，例えば,`printf("hoge\n");`と打つときは問題ない. しかし，改行を行いたいとき，例えば，
```text: 現実
カーソルを"|"で表す

int main(void)
{|}

↓ Enterで改行する

int main(void)
{
|}
```
このような場合は，改行を行った後に結局カーソルを上の行に戻して再び改行を行い，タブを入力する必要がある.

```text: 理想
int main(void)
{|}

↓ Enterで改行する

int main(void)
{
    |
}
```

VSCodeなどのように，Enterで改行をしたらすぐにコードを打ち始められるようにしたい.

# 感想
難しい．複数ファイルの同時編集や，置換機能など実装したい機能はもっとあったが，一気に実装しようもんなら確実に頭がパンクするだろう. 既存のソフトの凄さ・ありがたみを実感できた.
Qiita記事を携帯で見れるようにしたい！！

Qiitaの記事ってみなさんどうやってご覧になっておりますか？
またどんな時にご覧になられますか？？

私の場合ノートPCを使用して見ることが多いです。
（携帯で見るのは対応とか見るまでがめんどくさそう・・・と思ってました笑）

でもQiitaを見る時は、
- 何かトラブルがあって解決方法知りたい時
- ちょっと仕事ひと段落したなぁって時
- こういう勉強したいなって思い立った時
 
みたいな感じかなと思います。

仕事以外の時（例：通勤中）も見れたらいいなあ・・・と思い、
今回携帯でも閲覧できるようにしよう！と動き出しました。
皆さんにも共有したら全国のエンジニアの方が今まで蓄えた知識をもっと気軽に見れるようになるなと思い、記事として投稿してみます！

## Qiitaを見るために作成されたアプリ
iPhoneのApp Storeで検索してみると、エンジニアの方によって作成されたアプリがちらほら見受けられました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631802/0002c7f9-1a5f-e583-a97a-501e4cd199c4.png)

## 私が実施した方法
いくつかアプリを見てみましたが、個人的にPCと同じ仕様で見たい！と思いました。
またすきま時間で見るだけでなく投稿もできるようにしたいなと考え、
今回はQiitaのブラウザをアイコンとして登録し、ホーム画面に作成する方法を共有します。

### メリット
ほぼ上記に書いていることですが、メリットとしては以下が挙げられます
- 手軽に見れる
- すきま時間の活用（個人的に1番でかい）
- PCと同じだから操作しやすい
- 記事も書ける
- 通知を携帯のバナーやロック画面で受け取れるようになる
- Qiitaに投稿するネタをメモメモできる

などなど

### 作成手順（iPhoneの場合）
私が使用している携帯がiPhoneなのでiPhoneでの作成手順を記載します
1. SafariでQiitaと検索
2. 自分のアカウントにログイン
3. 下のバーにある共有ボタンを押下し「ホームボタンに追加」を押下
4. 「追加」を押して完了

## 最後に
実際にこの記事も携帯で作成してみましたがいかがでしょうか？
PC画面のようにプレビューと一緒に見れない分、確認には時間がかかってしまいましたが、
思いついた時に書ける分だけ書けるので、個人的にはすごいやってよかったです！

①携帯で思いついた時にメモ、要点だけ書く
②PCで本書き＆修正
が一番使いやすいと思います。

ぜひみなさんも携帯上にQiitaの追加してみてください✨
PSR-12ガイドライン: PHPファイルの終わり方とその重要性（Unix LF）

PSR-12の
> [全ての PHP ファイルは、Unix LF（ラインフィード）の行末のみを使用する必要があります。](https://www.ritolab.com/posts/208#:~:text=%E5%85%A8%E3%81%A6%E3%81%AE%20PHP%20%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AF%E3%80%81Unix%20LF%EF%BC%88%E3%83%A9%E3%82%A4%E3%83%B3%E3%83%95%E3%82%A3%E3%83%BC%E3%83%89%EF%BC%89%E3%81%AE%E8%A1%8C%E6%9C%AB%E3%81%AE%E3%81%BF%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E5%BF%85%E8%A6%81%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82)

ってなんぞや、開発にどういう使われ方をするのか、これをすることでどんな効果があるのか？
というかUnix LFって何よと思ったので少し深堀りしたいと思います。


:::note 
<details><summary >AI要約</summary>

- PSR-12の目的: PHPのコーディングスタイルを標準化し、コードの一貫性と可読性を向上させる
- Unix LFとは: LF（ラインフィード、\n）は、Unix系システムで行の終わりを示す改行コード
- PSR-12での改行コード: 全てのPHPファイルは、UnixスタイルのLF（\n）を使用する必要がある
- 重要性: 可読性の向上とツール・バージョン管理システム（例：Git）との互換性確保のため
- VSCode設定: VSCodeで改行コードをLFに設定し、一貫したコードスタイルを維持する
</details>
:::

## そもそもPSR-12とは？
PHPのコーディングスタイルを標準化するためのガイドラインです。
これに従うことでコードの一貫性と可読性が向上し、さまざまな開発者がプロジェクトで共同作業を行いやすくします。
プロジェクト独特のルールではなく、広まっているガイドラインなので知っている人であれば開発へのアサインも容易になります

## Unix LFとは 
LF（ラインフィード、LineFeed）は、文字列の終わりを示す制御文字で、Unix系システム（LinuxやMacOS）では行の終わりを示すために使用されます。具体的には、文字コードとして`\n`と表現されます。
いわゆる改行コードですね
改行コードの種類に関してはコチラ↓

https://www.tohoho-web.com/wwwxx011.htm

## PSR-12の「Unix LF」とはどういうことか？
PSR-12では、すべてのPHPファイルは改行する際に改行コードとしてUnixスタイルのラインフィード（LF）を使用する必要があります。
これは、WindowsのCRLF（キャリッジリターンとラインフィード、`/r/n`）とは異なります。
PSR-12に従うことで、コードの一貫性と移植性が向上し、異なる開発環境間でファイルをやり取りする際に発生する問題を防ぐことができます。

PSR-12で定められた改行コードを使いましょうということですね

## なぜUnix LFが重要なのか？
- 可読性
    - 一貫した改行コードを使用することで、コードの可読性が向上します
- 互換性
    - 多くのツールやバージョン管理システム（例えばGit）は、ファイルの最後が単一のLFで終わることを前提としています。これに従うことで、ツール間の互換性が保たれ、問題を回避できます

## 実際の開発での使用例
開発者がコードを書く際に、全てのPHPファイルがLFで終わるように設定します。これにより、チーム全体で一貫したコードスタイルを維持できます。

良い例
```php
<?php

echo "Hello, World!";
```
最後の行にはコードがあり、その後に単一のLFで終わっています

悪い例1: 最後の行が空白だけ
```php
<?php

echo "Hello, World!";
    // ここ
```
最後の行が空白（スペースやタブ）だけで終わっています

悪い例2: 最後の行にLFがない
悪い例3: 最後の行が複数のLFで終わる

（ソースコードでは実現できないため割愛）

## VSCodeでの設定
VsCodeでは、ファイルの改行コードを設定することができます
以下の手順で設定を変更できます

1.  画面右下のステータスバー
    - 「LF」または「CRLF」と表示されている部分をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282722/cc3b1a34-9ae0-8885-8bd0-5ac370a4a81b.png)
1.  改行コードの選択
    - メニューが表示されるので、「LF」を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282722/1e9f2a76-a832-5ffc-4f53-8aa0611782e5.png)
1. デフォルト設定の変更
    - 設定ファイル（`settings.json`）に以下の設定を追加して、すべてのファイルでデフォルトの改行コードをLFに設定します
```json
{
    "files.eol": "\n"
}
```
これにより、新規に作成されるファイルや既存のファイルを保存する際に、LFが自動的に使用されるようになります


## おわりに
おそらくGit上で開発されているプロジェクトを`clone`なり`pull`なりしていればOS問わず問題ない解釈です
だから今まで疑問視してなかったのかぁと感じました
他の言語はわかりませんが、改行コードに関してはPSR-12に限らず`LF`がデファクトスタンダードになりそうですね
ゴルーチン（goroutine）について_1

# ゴルーチン（goroutine）
goの基本構文を学んでいくうえで今一つイメージが掴みづらかったゴルーチンについてまとめてみた。

● ゴルーチン（goroutine）は、Go言語で並行処理を実現するための軽量スレッドである。
● ゴルーチンは、通常のスレッドよりも低コストで作成され、数千〜数百万のゴルーチンを簡単に起動できる。
● ゴルーチンは、キーワード「go」を使って関数呼び出しの前に指定することで作成される。
以下がコード例である
```diff_go
func main() {
    go hello()
}

func hello() {
    fmt.Println("Hello, goroutine!")
}

```
このコードでは、hello 関数が新しいゴルーチンとして実行される。main 関数が終了しても、ゴルーチンは実行を続ける。

ゴルーチンは、Goのランタイムによってスケジュールされ、複数のゴルーチンが同時に実行されることがある。Goのランタイムは、マルチコアプロセッサの利用やブロッキングIOの効率的な管理など、ゴルーチンを効果的に処理する。ゴルーチンは通常、共有メモリへのアクセスを同期するためにチャネル（channel）などの同期プリミティブと組み合わせて使用される。これにより、データ競合や同期の問題を回避しながら、効率的な並行処理が可能になる。

上記がぱっと調べてみてヒットした内容だが、理解がイマイチな言葉もあったりするので一通りまとめてみる。

### スレッドにとは

そもそもスレッドとは何か理解があいまいなので概要を以下に書き記しておく

● スレッドは、プログラム内での実行の基本単位であり、プロセス内での実行の流れを表す。
● 通常、プロセス内で複数のスレッドが同時に実行され、それぞれが独自の処理を行う。
● スレッドはプロセス内の資源を共有し、同じプロセス内の他のスレッドと同じメモリ空間を共有する。

スレッドの特徴には以下があげられる。

1. 軽量性: スレッドはプロセスよりも軽量であり、スレッドの切り替えにかかるコストが少ないため、効率的に多数のスレッドを作成できる

2. 並行性: 複数のスレッドが同時に実行されることがあります。これにより、複数の処理を同時に行うことが可能になる

3. 共有メモリ: 同じプロセス内のスレッドは同じメモリ空間を共有します。このため、スレッド間でデータの共有や通信が容易に行える

4. プログラムの並列化: 複数のスレッドを使用することで、プログラムを効率的に並列化し、複数の処理を同時に実行することができる

ただし、スレッドを使用する際には、データ競合や同期の問題に注意する必要がある。複数のスレッドが同時に同じデータにアクセスしようとすると、予期しない結果が発生する可能性があるため、適切な同期手法を使用してこれらの問題を回避する必要がある。

さらによく分からない言葉でてきたのでいかに記してゆく、、、(CS教養無男)

### 実行の基本単位とは
実行の基本単位は、プログラムが実行される際に分割される最小の単位を指し、これにはいくつかの概念があるが、その中で最も一般的なものは命令、プロセス、スレッドの３つ。

命令 (Instruction):
命令は、プログラムが実行される際にプロセッサが解釈し、実行する個々の操作を表す。命令は機械語の形式で表され、プロセッサによって直接実行される。

プロセス (Process):
プロセスは、実行中のプログラムのインスタンスである。プロセスには、実行中のプログラムのコード、データ、および実行状態に関する情報が含まれる。プロセスは、オペレーティングシステムによって管理され、独自のメモリ空間を持つ。

スレッド (Thread):
スレッドは、プロセス内で実行される実行の流れの単位。スレッドは軽量であり、複数のスレッドが同時に実行されることができる。スレッドはプロセス内のリソースを共有し、同じプロセス内の他のスレッドと同じメモリ空間を共有します。

## まとめ
・・・とのことだった。つまりスレッドを上手く利用することで処理速度が速くなるのだろうということは何となく分かった。なるほど、非同期処理はこれを利用していたのか（今更）

ということでjavaでは「Thread」クラスを使って非同期処理（つまりスレッドによる並行処理）を実現していたが、goではゴルーチンで実現しているということのようだ。
関数呼び出しの前に「go」を指定するというのは「今から呼び出す関数は別スレッドを使いますよ」と宣言するようなものなのかもしれない、、、

他にもいくつか理解があいまいな言葉があったため以下に記しておく

● 共有メモリ・・・複数のプロセスやスレッドが同じメモリ領域を参照すること。プロセスやスレッド間でデータを共有するために使用される。

● 同期プリミティブ・・・マルチスレッドやマルチプロセスの環境で、複数のスレッドやプロセスが共有リソースにアクセスする際に、そのアクセスを制御し同期させるための基本的な仕組みやツールのこと。次回確認予定のチャネルもこれに該当する
画像を使ったアウトプットが早くなる！素早く画像を載せるコツ

# はじめに
今回は、Mac 系の PC で技術ブログのアウトプットを素早くするコツを紹介していきます。

技術系のブログでは画面のスクリーンショットを範囲指定で撮影して添付したくなる場面が多いかと思いますが、自分は Mac 系の PC でこんな悩みを抱えていました。

「画像を一回保存してからアップロードするのめんどくせぇ...」

# Mac ならではの悩み

というのも、Mac 系の PC でスクリーンショットを撮ると、デフォルトでクリップボードに保存されず、一度ローカルに保存してからコピー/ペーストをすることになります。

https://support.apple.com/ja-jp/102646

これはスクリーンショットをたくさん貼り付ける人からするとかなりの時間ロスになると思いますが、以下の方法で解決できました。

**「control キーを長押ししながらスクリーンショットを撮る」**

この方法を使うと、取得したスクリーンショットがクリップボードに保存されるため、そのまま command + v で画像を貼り付けることができます。

# まとめ
Mac 系の PC で画面のスクリーンショットをそのままコピペするには、control キーを長押ししたままスクリーンショットを撮ることで解決します。

Windows 系の OS では、"Windows キー + Shift + s" などで範囲を指定して画面キャプチャーを取得すると、デフォルトでメモリ上のクリップボードに保持されます。
そのため、一度ローカルに保存することなく直接コピペできるため「なんで Mac はできないんだ...」と思っていました。

余談ですが、Qiita では「画像をアップロード→写真を選択→貼り付け」という手順を踏まなくても「画像をコピー→ペースト」だけで済むので非常に楽ですね...
Proxmoxの古いバージョンのISOを入手する

## TL;DL

- https://enterprise.proxmox.com/iso/ にありました。

## 概要

本家のDLページではISOが更新されると古いバージョンのISOがダウンロードできなくなり、地味に困っていました。
※メジャーアップの評価したいなとか。

ですが、この度見つけました。

https://enterprise.proxmox.com/iso/

## URLまでの導線

本家DLサイト https://www.proxmox.com/en/downloads からスタート。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459468/68fb7cc9-f089-705b-32e6-bd8dcc409e77.png)

からの…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459468/51947156-af4f-4cbe-be90-0d0814c5a16d.png)

からの…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459468/ae2f2842-096c-a1de-3ec2-1ec18571efed.png)



## そもそもWikiにはちゃんと表示されてた。
そもそもなんですが、Wikiのサイドバーにもあるし、トップページにもありますね…
本家LPからWikiへの導線がまぁまぁ弱いというのはあると思います！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459468/d70a7b2c-7f5d-767f-6d3c-69b6978d9bd6.png)



## URLがエンタープライズリポジトリっぽいけど大丈夫なの？
ISOが格納されている https://enterprise.proxmox.com/iso/ は特に認証など求められませんが、
エンタープライズリポジトリが格納されている https://enterprise.proxmox.com/debian/（プロダクト名） ではちゃんと認証要求されるので大丈夫だと思います。
WSL環境と実機の時間を合わせる

# はじめに
WSL上で`sudo apt update`を実行すると以下のエラーが表示されました。

```
E: Release file for http://security.ubuntu.com/ubuntu/dists/jammy-security/InRelease is not valid yet (invalid for another 1h 10min 15s). Updates for this repository will not be applied.
```

ググってみた結果、どうやらWSLの時間をシステムの時間を合わせる必要があるようです。

# やったこと

hwclockコマンドを使用してWSLの時間をシステムの時間に合わせました。
ちなみに以下のコマンドで、時間を確認することができます。

```bash
date
```

23時に実行して、20時が返ってきたのでWSLが3時間遅れていました。

WSLの時間がハードウェアクロック、PC本体の時間がシステムクロックです。
ハードウェアクロックをシステムクロックに合わせたいので以下のコマンドを実行しました。

```bash
sudo hwclock --hctosys
```

ちなみにシステムクロックをハードウェアクロックに合わせたい場合は`hctosys`を`systohc`に置き換えればよいです。

# hwclockコマンド参考

https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-configuring_the_date_and_time-hwclock
【VSCode】タブの高さを低くする方法

`window.density.editorTabHeight` を `conpact` に設定することでタブの高さを低くできます。

```settings.json
{
  "window.density.editorTabHeight": "conpact",
}
```

![editor-tab-height-compact.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/c7fbfbe4-39fc-bfa5-172a-eef361f9aea2.png)
fessで少しハマった

個人的「質はともかく継続する」25日目です

## fessで少しハマった

fessを少し使う機会があったのですが、
少しハマったことがありました。

## 検索結果を全て消したい

お試しでジョブを実行していたりするときに、
一度全部の検索結果を消したくなるときがあります。

そんなときは管理メニューの「システム情報」ー「検索」を開き、
検索ボックスに.*と入れて全検索し、画面右下の削除を押せば完了です。

```
.*
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/afc4cf4f-b993-27ff-bd2b-1fc8642bee1f.png)

## ファイルクロールがうまくいかない

これは私がドキュメントをちゃんと読んでなかったせいだと思いますが、
ファイルクロールの設定項目に「クロール対象とするパス」という項目がありますが、
ここに書かれたパスがクロール対象になるわけではありません。
いや、なるんですけど、「パス」で設定された部分のうち、
クロールしたい対象を正規表現で絞り込むときに使います。
私は名前の通り受け取って、普通にファイルパスを入れていました。
そうすると全然クロールしてくれず。。
初心者には日本語がややこしくて間違えやすい感じです。

## まとめ

急がば回れ、公式ドキュメントを読むことが大切ですね。。
AWSコスト管理しくじりと対策

# コスト管理してますか
AWSのほとんどのサービスは従量課金制です。
月初の請求書を見るのにドキドキしていませんか？
AWSコスト管理でのしくじりにはパターンがあると思います。
パターン別にどのような対策をすればいいか考えてみましょう。

## 1. なんとなく立ち上げたリソースを放置
個人でAWSを利用して検証環境を作ったりするとありがちなパターンです。
コンピューティングリソースだけを使用しているとAWSのコンソール画面を使用せずコストの確認が低頻度になることはよくあることですが、コストが予想より大きく超えてしまっていては後の祭りです。(先月やってしまったばかりとは言えない)

### 1. 対策
このパターンで必要なのは通知です。
[AWS Budget](https://aws.amazon.com/jp/aws-cost-management/aws-budgets/)は予算を超えるコストを検出するとメールで通知してくれます。
ここで忘れていけないのはきちんと届くメールアドレスを設定する事、フォルダを分けるなどしてメールに目を通せるようにしておくことです。
リソースごとに通知したりSlackやTeamsなどに送信したい場合はCloudWatchとSNS、Lambdaなどを組み合わせてカスタムの通知用リソースを作ります。

## 2. 料金体系を知らなかった
例えばEC2では手軽にインスタンスタイプを変更することができるのですが、料金体系を知らずに不必要にスペックの高いタイプを選んでしまうことがあります。
オンデマンドEC2の[インスタンスタイプ](https://aws.amazon.com/jp/ec2/pricing/on-demand/)はサイズを1つ上げる度に料金が2倍に跳ね上がるので油断は禁物です。
また、データI/Oやストレージ料金が別に加算されるリソースはデータを頻繁に入出力していると知らないうちにコストが跳ね上がってしまう事もあるので気を付けましょう。

### 2. 対策
リソースのコストは事前に計算しましょう。
[AWS Pricing Calculator](https://calculator.aws/)は現行のAWSの料金で期間ごとの請求の目安を計算することができるツールです。
とはいっても、全部を計算し尽くすことは難しいので1.の対策と組み合わせて見通しをもって利用することが大切です。そろばんが苦手な方は、[AWS Cost Optimizer](https://docs.aws.amazon.com/ja_jp/compute-optimizer/latest/ug/what-is-compute-optimizer.html)などのレコメンデーションツールを使用して最適なパフォーマンスに調整していくのが良いと思います。

## 3. 推奨されない再帰的処理を使ってしまった
再帰的処理というものは、無限ループを発生させるリスクをはらんでいます。
たとえば、S3のオブジェクトがアップロードされたことをトリガーにオブジェクトを生成する処理を作ったとします。
この生成処理をアップロードされたオプジェクトと同じバケットで実行するとどうなってしまうでしょうか。
もちろん鼠算式にオブジェクトが増えていってしまい、収拾がつかない事態になってしまいますよね。
早期に気づけばよいのですが、長時間放置すると万円以上の単位で請求が来ることを覚悟しなければなりません。

### 3.対策
コードレビューをしましょう。
そして、実行結果は必ず確認しましょう。
最近はLambdaが再帰的処理を永久ループしていることを検知して自動的に停止する機能もあるようなので、このようなミスを犯しても過大な請求が来るリスクは低くなっているといえます。
[[アップデート] Lambda 関数が再帰ループを検出して停止するようになりました](https://dev.classmethod.jp/articles/detecting-and-stopping-recursive-loops-in-aws-lambda-functions/)


## 4. セキュリティでミスしてしまった
これもやってはいけないパターンをやってしまった例です。
よくあるのはアクセスキーなどのAPIキーを外部に公開してしまうミスです。
これによって悪意のある仮想通貨マイニング実行の被害者になってしまったり、情報漏洩による損害を被ってしまいます。
※情報漏洩自体はコストの管理に直接関係ありませんが、個人情報を収集するサービスでは損害賠償請求など間接的にコストがかかるケースもあるため記載させていただきました。

### 4. 対策
何度も口酸っぱく言われていることだとは思いますが、一番有効なのはリソースに対するアクセスは最小権限にとどめておくことです。
これによってたとえクレデンシャル情報が漏洩したとしても被害を最小に抑えることができます。
また、[Systems Manager Parameter Store](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html)、[Secrets Manager](https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/intro.html)などを活用してクレデンシャルの直書きをしないことも有効な手段です。


# まとめ
コスト管理は1日にしてならずです。
AWSはコスト削減の手段をたくさん用意してくれていますので、これをきっかけにコスト管理を意識していただければ幸いです。
ターミナルでコマンドラインを使うと、何ができてどんなメリットがあるのか

# この記事を書くきっかけ

Webアプリケーションを作成してデプロイしてから数ヶ月が経ちました。開発した後も、SSH接続、nginxの起動・停止、gitの操作など、ターミナルでのコマンド操作の機会が何度もありました。Linuxの知識が全くないままターミナルを操作し続けていたのですが、希望通りのコマンド操作をできるようになりたいと思い、Linuxの勉強を始めました。

しかし、実のところ、
「Linuxで具体的に何ができるのかわからない。」
「Linuxやコマンドライン操作を勉強する意味があるのか。」など、
勉強する以前にいろいろ疑問に思うことがありました。

ターミナル操作で何ができるのか、できるとどんないいことがあるのかを理解できれば、勉強する理由になると思います。また、できることがはっきりすれば勉強のモチベーションも上がります。今回は、ターミナルでコマンドラインを使うと何ができて、どんなメリットがあるのかを簡単に調べてみました。

ターミナル初心者の方は是非この記事を読んでみてください。


# できること
## 1. 日常的なファイル操作が便利になる
ファイルをコピーする、移動させる、削除するなどの日常的なファイル操作は、コマンドラインを使用すると簡単に行うことができます。大量のファイルを手作業でコピーしたり、ドラッグ&ドロップをするのは、結構手間がかかります。下記のような簡単なコマンドで、大量のファイルを一気にファイル操作することが可能です。

例：複数のファイルを一度にコピーする
`cp *.txt *.html File/`
- File/はターゲットディレクトリのパスに置き換えてください

また、シェルスクリプトと呼ばれるファイルプログラムに、実行するコマンドを保存しておけば、後から何度も呼び出して使うこともできます。
シェルスクリプトとは、一連のコマンドを自動で実行するためのファイルです。


## 2. Webサーバーなどのシステムの設定が可能
ApacheやNginxなどのWebサーバーは、管理するためのGUIアプリケーションが用意されていません。設定や起動をコマンドラインユーザーインターフェース（CUI）のコマンドラインで行う必要があります。使えるようになれば、Webサーバーの管理も簡単にできます。コマンド操作はWebアプリケーション開発には欠かせないスキルなのです。

Apacheの設定ファイルを編集する
`sudo nano /etc/apache2/apache2.conf`

Nginxを再起動する
`sudo systemctl restart nginx`

## 3. サーバーのリモート管理を行うことができる
Webサーバーなどのインターネットサーバーの管理は、別のマシンからネットワークを介してリモート管理することが多いです。その際、SSH接続というリモートログインソフトを使用してサーバーを管理するのが一般的です。SSHでは通信の内容が暗号化されるので安全な操作ができます。

SSHでリモートサーバーに接続する
`ssh username@remote_host`


## 4. Pythonなどのプログラム開発に使用できる
macOSにはPythonなどのスクリプト言語の開発実行環境が用意されています。Pythonをマシンにインストールするするだけで、ターミナルを開いてpythonコマンドを入力するだけでpythonを使うことができます。

Pythonスクリプトを実行する
`python3 script.py`


## 5. カレンダー、計算、辞書などの機能が使える
カレンダーを表示する
`cal`

計算
`echo $((1 + 1))`

辞書
`open dict://"森羅万象"`
openコマンドで自動的に辞書アプリが起動します

実はできることがたくさんあるんですね。

# コマンドラインのメリット
## 1. 効率性とスピード

コマンドを入力するだけで多くのタスクを迅速に実行できます。特に複数のファイルを一度に処理する場合やバッチ処理を行う場合に非常に効率的です。

## 2.スクリプトの自動化

コマンドをスクリプトにまとめることで、タスクの自動化が可能になります。これにより、定期的な作業を自動化し、手作業の手間を減らすことができます。
## 3 .リモート操作

SSHなどを使用してリモートサーバーにアクセスし、コマンドラインから操作することができます。これにより、物理的に離れた場所からでもサーバーの管理や操作が可能です。
## 4. リソースの少ない環境での利用

GUIに比べてシステムリソースの消費が少ないため、リソースが限られている環境でも効率的に操作できます。
## 5. 柔軟性

コマンドラインは非常に柔軟で、パイプ (|) を使用してコマンドを連結し、複雑な操作を簡単に実行できます。例えば、ls -l | grep "pattern" のようにコマンドを組み合わせることができます。
## 6. 学習と知識の向上

コマンドラインの使用を通じて、システムの内部構造や動作についての理解が深まります。これは、トラブルシューティングやシステム管理のスキル向上に役立ちます。

# まとめ
Linuxの勉強やコマンド操作を覚えることで、
- Web開発に必要なスキルが身に付く
- ファイル操作を効率的に行うことができる（時短！）
- 実はできることがたくさんある！

ということがわかりました。
自分に関わるところでは、やはりWeb開発でよく使うコマンド（Webサーバーの起動、SSH接続など）と、効率的なファイル操作ためのコマンド（lsコマンドなどの基本コマンド）の習得が目標となりそうです。一度覚えれば、使える場面もたくさんあるので、モチベーションを維持して勉強を続けたいと思います。
Trust Region Policy Optimization (TRPO). ニッチな読み物

# はじめに.
本記事は Trust Region Policy Optimization (TRPO) [cite:https://arxiv.org/abs/1502.05477] の Appendix に関する細々とした記事になります．

# Appendix A.
### ・目的
本節では，TRPO 技術の根幹をなしている「ある更新幅内で上手く更新すれば良い方向に改善される」という考えの証明を行っています. つまり，方策変化によるパフォーマンス変化 $|\eta(\tilde{\pi)} - \eta(\pi)|$ のずれがどのように分解され，bound に影響を与えているかを考えます．
本節の目的は，
```math
\eta(\tilde{\pi}) = \eta(\pi) + \mathbb{E}_{\tau\sim\pi} \left[ \sum_{t=0}^\infty \gamma^t \bar{A}(s_t) \right]
```
を示し，本論文 Eq.(3) を得て$\color{red}{(前半)}$，surrogate 関数が $\eta(\tilde{\pi})$ とある程度近いこと$\color{red}{(後半)}$を示すことにあります(各記号定義は以降か元論文参照)．$\tau$ はエージェントの軌道(推移の履歴) $=(s_0,a_0,s_1,a_1,...)$ です．$\color{red}{s_0~は初期状態確率に従うため，方策~\pi,\tilde{\pi}~に対して独立です．}$

### ・準備，定義

 本論文で用いられている surrogate (代理) 損失関数は，
```math

　L_{\pi}(\tilde{\pi}) = \eta(\pi) + \sum_s \rho_\pi(s) \sum_a \tilde{\pi}(a|s)A_{\pi}(s,a),
 
``` 
ここで，$A_\pi, \rho_\pi$ の定義は通常の RL と同様です．
本論文における報酬関数の設定と $\eta(\pi)$ はやや特殊(?)で，
```math
\eta(\pi) = \mathbb{E}_{s_0,a_0,...} \left[ \sum_{t=0}^\infty \gamma^t r(s_t) \right],\\
s_0 \sim \rho_0(s_0), a_t\sim\pi(a_t|s_t), s_{t+1} \sim P(s_{t+1}|s_t,a_t)
```
となっています．報酬関数は状態のみからのマッピング$:\mathcal{S} \rightarrow \mathbb{R}$ です．(おそらく，$a_t\sim\pi$ で期待値を取るため省略しているのかと思うのですが，$a_t$ が報酬構造に含まれないような限定した表現は奇妙な気がします．) この影響を受けて，状態価値関数 $V_\pi$，行動価値関数 $Q_\pi$ の定義も変わってます．

### ・解説(前半)
Advantage 関数から，
```math
\begin{align}
&\mathbb{E}_{\tau|\tilde{\pi}}\left[\sum_{t=0}^\infty \gamma^t A_{\color{red}{\pi}} (s_t,a_t) \right] \\
&= \mathbb{E}_{\tau|\tilde{\pi}}\left[\sum_{t=0}^\infty \gamma^t (r(s_t) + \gamma V_\pi (s_{t+1}) - V_\pi(s_t))\right] \qquad \because A_\pi(s,a)\\
&= \mathbb{E}_{\tau|\tilde{\pi}}\left[ \sum_{t=0}^\infty \gamma^t r(s_t) - V_\pi(s_0) \right] 
\quad \because [\color{red}{\gamma V_\pi (s_{1})} - V_\pi(s_0)] - \gamma[\color{blue}{\gamma V_\pi (s_{2})} - \color{red}{V_\pi(s_1)}]...
\\
    &=  \mathbb{E}_{\tau|\tilde{\pi}} \left[\sum_{t=0}^\infty \gamma^t r(s_t) \right] -\mathbb{E}_{s_0}[V_\pi(s_0)] \qquad \because V_\pi(s_0),\tau|\tilde{\pi}~は独立 \\
&= \eta(\tilde{\pi}) - \eta(\pi)
\end{align}
```
となります．よって，
```math
\eta(\tilde{\pi}) = \eta(\pi) + \mathbb{E}_{\tau|\color{blue}{\tilde{\pi}}} \left[\sum_{t=0}^\infty \gamma^t A_{\color{red}{\pi}} (s_t,a_t) \right] 
```
です．$\tau$ が状態を要素に持つため，状態が $\color{blue}{\tilde{\pi}}$ に依存します．このままでは本論文 Eq.(2) と同様に $\color{blue}{\tilde{\pi}}$ の処理が面倒です．そこで，
```math
\bar{A}(s) = \mathbb{E}_{a\sim\color{blue}{\tilde{\pi}}(\cdot|s)} \left[A_\pi(s,a) \right] 
```
と advantage 関数の期待値を定義し，代理関数 $L_\pi$ を導入することで対処を試みます．
```math
L_\pi(\tilde{\pi}) = \eta(\pi) + \mathbb{E}_{\tau\sim\pi} \left[ \sum_{t=0}^\infty \gamma^t 
 \bar{A}(s) \right] 
```
これこそ本論文の Eq.(3) です．

### ・解説(後半)

準備中...
AtCoder 勉強記録[C++] その8

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)
# 本日解いた問題
## B - Go Straight and Turn Right
[B - Go Straight and Turn Right](https://atcoder.jp/contests/abc244/tasks/abc244_b)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n;
  cin >> n;
  string t;
  cin >> t;
  vector<char> dir = {'E', 'S', 'W', 'N'};
  ll tmp = 0, resx = 0, resy = 0;
  for(int i = 0; i < n; i++){
    if(t[i] == 'R') tmp++;
    else if(dir[tmp] == 'E') resx++;
    else if(dir[tmp] == 'S') resy--;
    else if(dir[tmp] == 'W') resx--;
    else if(dir[tmp] == 'N') resy++;
    if(tmp >=4) tmp = 0;
  }
  cout << resx << " " << resy << endl;
}
```
### 解法
配列dirを用意して'E','S','W','N'を入れておき、場合分けして処理した。よくよく考えてみたら0~3の数字でも同じことができたので配列を用意した意味はあまりなかった。
## B - Mex
[B - Mex](https://atcoder.jp/contests/abc245/tasks/abc245_b)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n;
  cin >> n;
  vec a(n);
  rep(i, n) cin >> a[i];
  vector<bool> jud(2001);
  rep(i, n) jud[a[i]] = true;
  rep(i,2001){
    if(jud[i] == false) {
      cout << i << endl;
      exit(0);
    }
  }
}
```
### 解法
2001までのbool型配列を用意しておき、入力された数値をtrueにしていく。その後、初めにfalseになる値を出力し、終了する。
## C - Final Day
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n, k, p;
  cin >> n >> k;
  vec sum(n);
  rep(i, n){
    rep(j, 3) {
      cin >> p;
      sum[i] += p;
    }
  }
  vec ssum = sum;
  sort(ssum.rbegin(), ssum.rend());
  rep(i, n){
    if(sum[i] + 300 >= ssum[k-1]) cout << "Yes" << endl;
    else cout << "No" << endl;
  }
}
```
### 解法
ある1人の生徒が300点を取り他の人が0点の場合にK位以上かどうかを考える。入力された点数の合計値を入れる配列sumと、その配列を降順にソートした配列ssumを用意する。ssumでk-1の値よりもsumに300を加えた値のほうが大きければYes、そうでなければNoを出力する。
## C - Cheese
[C - Cheese](https://atcoder.jp/contests/abc229/tasks/abc229_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n, w, a, b;
  cin >> n >> w;
  vector<pair<ll,ll>> c(n);
  rep(i, n) {
    cin >> a >> b;
    c[i].first = a;
    c[i].second = b;
  }
  ll res = 0;
  sort(c.rbegin(), c.rend());
  rep(i, n){
    res += c[i].first * c[i].second;
    w -= c[i].second;
    if(w<0){
      while(w<0){
        res -= c[i].first;
        w++;
      }
    }
  }
  cout << res << endl;
}
```
### 解法
チーズの重さとおいしさを入れておくpair型の配列を用意する。おいしさの値で逆順ソートし、最終的なおいしさを入れる変数resにおいしさ×重さを入れ、wから重さを引く。その後wが0未満となったら1つずつresからおいしさを引き、wに重さを1グラムずつ足していく。
【Rust】RC、Arc、RefCell等の用途が分からなくなるからまとめた

著者は最近(2024/07/02時点)、Rustに触れ始めた初学者です。
Rustにおける値の扱い方でヒープメモリを用いる『Box』や、共有参照を扱う『RC』と『Arc』などで何を使えばよいか迷うことが多いため、自分なりの理解でまとめています。
# ヒープメモリの使用(Box)
## Box

```rust
let a = Box::new(5);
```

### 特徴

- 単一の所有者。
- 値をヒープに確保し、そのポインタを持つ。
- コンパイル時に所有権借用のルールを守る。

### 用途

- 値のヒープ確保が必要な場合。
- サイズの異なる型を同一のコレクションに格納する場合。
- 再帰的なデータ構造を作成する場合

# 所有権の共有(RC, Arc)

## RC

```rust
let a = Rc::new(5);
let b = Rc::clone(&a);
```

### 特徴

- 単一スレッド内での共有所有権。
- 不変の値に対する参照カウント。
- スレッドセーフではない。

### 用途

- 単一のスレッドで複数の所有者が必要な場合。
- ツリー構造やグラフ構造など、複数の部分が同じデータを参照する場合。
- 

---

## Arc

```rust
let a = Arc::new(5);
let b = Arc::clone(&a);
```

### 特徴

- 複数のスレッドでの共有所有権。
- 不変の値に対する参照カウント。
- スレッドセーフ。

### 用途

- マルチスレッド環境で複数の所有者が必要な場合。
- スレッド間で安全にデータを共有する場合。

# 単一スレッドでの内部可変性(Cell, RefCell)

## Cell

```rust
let a = Cell::new(5);
a.set(10);
```

### 特徴

- 単一スレッド内での内部可変性を提供。
- 値を借用せずに変更可能。
- コピー可能な型に対して使用（`Copy`トレイト）。

### 用途

- 簡単な内部可変性が必要な場合。
- 参照を取らずにデータを変更する必要がある場合。

---

## RefCell

```rust
let a = RefCell::new(5);
*ref_cell.borrow_mut() = 10;
```

### 特徴

- 単一スレッド内での内部可変性を提供。
- 実行時に借用ルールをチェック（コンパイル時ではなく）。
- `Ref`と`RefMut`で不変および可変借用を管理。

### 用途

- 複雑な内部可変性が必要な場合。
- ライフタイムや借用チェッカがコンパイル時に許可しないが、論理的には安全な場合。

# マルチスレッドでの内部可変性(Mutex, RwLock)

## Mutex

```rust
let a = Mutex::new(5);

{
    let mut b= a.lock().unwrap();
    *num = 10;
}
```

### 特徴

- マルチスレッド環境での排他制御を提供。
- データへのアクセスを一度に一つのスレッドに限定。
- `lock`メソッドでデータへの排他アクセスを取得。

### 用途

- スレッド間でデータの一貫性を保つ必要がある場合。
- 同期が必要な場合。

---

## RwLock

```rust
let a = RwLock::new(5);

{
    let b = rw.read().unwrap();
    println!("{}", *b);
}
{
    let mut c = rw.write().unwrap();
    *c = 10;
}
```

### 特徴

- マルチスレッド環境での排他制御と共有読み取りを提供。
- 複数のスレッドが同時に読み取り可能。
- 書き込みは一度に一つのスレッドのみ。

### 用途

- 読み取りが多く、書き込みが少ない場合。
- 読み取りと書き込みの操作が明確に区別できる場合。

# よく使う組み合わせ
## **`Rc` + `Cell`**
- 単一スレッド内で、参照カウントされたデータの内部可変性が必要な場合に使用されます。
- `Rc`はデータの共有所有権を提供し、`Cell`は内部可変性を提供します。
## `Rc` + `RefCell`
- 単一スレッド内での複数所有者によるデータの共有と内部可変性を提供するために使用されます。
- `Rc`は参照カウント型のスマートポインタで、`RefCell`は実行時に借用チェックを行う可変データを提供します。
## `Arc` + `Mutex`
- マルチスレッド環境で、共有データに対する排他アクセスを提供するために使用されます。
- `Arc`はデータの共有所有権を提供し、`Mutex`はデータへの排他アクセスを管理します。
## `Arc` + `RwLock`
- マルチスレッド環境で、複数のスレッドがデータを読み取り可能で、書き込みは排他制御したい場合に使用されます。
- `Arc`はデータの共有所有権を提供し、`RwLock`は複数の読み取りと単一の書き込みを管理します。
特定の条件レコード作成を防ぐ方法～フロー編～

本橋孝昭です

今回は特定のレコード作成を防ぐ方法として重複ルール・一致ルールを作成して対応する方法をご説明します


今回は例として以下のような設定です


前提1 取引先責任者には「test01」という選択リスト項目がある

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/ecf58188-251a-8e49-7e58-47fe342328f4.png)


前提2 同じ取引先には複数の取引先責任者が紐づくが、同じ取引先にはtest01項目が同一のレコードがあってはいけない

例として株式会社Aに紐づく取引先責任者について

・田中太郎　test01項目A
・鈴木次郎　test01項目B
・佐藤三郎　test01項目C

と異なるtest01項目が紐づくのはいいのですが、株式会社Aに紐づく取引先責任者について

・田中太郎　test01項目A
・鈴木次郎　test01項目A
・佐藤三郎　test01項目B

と、test01項目が1つでも同じデータがある場合重複を許さない　という設定です
（これは田中太郎と鈴木次郎が同じAなのでNG）


前回は一致ルール重複ルールで対応しました

https://qiita.com/Takaa/items/c8dbbbfd567c9f67acf9

しかし一致ルール重複ルールでは欠点があります

## 欠点1 商談など一部標準オブジェクトでは使えない
そもそも商談オブジェクトなど一部オブジェクトは重複ルールが作成できないのでこの方法は使えない

## 欠点2 同一名称の取引先名レコードがある場合、同一名レコードも重複判定してしまう


今回はこの欠点をなくしたフローでご紹介します


## フロー全体像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/22a9a171-3a4b-3d38-62ad-c9b218342e03.png)

フロー詳細

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/6e3e49dc-ed20-636b-5891-1085e50e011a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/4eecb92f-368e-77e9-8267-295c8737f942.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/32024a9a-714b-086d-0a19-4f2a10ef0d70.png)

こちらのフローを有効にすると重複判定のレコードがある場合このようにエラーで対応できます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/8145b703-27e2-e118-aec6-ee2f21999d03.png)



このフローは商談など重複ルールで使用できないオブジェクトでも使えます
またレコードIDで見ているのでレコードごとに重複を防ぐことが可能です
【CSS】要素の高さを横幅と同じにしたい

こんにちは！
今回はCSS編になります。

高さを横幅の長さに応じて、高さを揃えたい時ありますよね？
つまり、要素を正方形に表示したい時です。

## aspect-ratio
これを使えばOK。

```html
<section>
    <div
      style="width: 30%; aspect-ratio: 1; background-color: aquamarine"
    >
    横幅30% x 高さは横幅と同じ
    </div>
</section>
```

<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522989/263e6870-cdeb-7287-e254-2d86711c8f1d.png">

## JavaScript版

リサイズイベントを設定して、正方形にしたい要素の横幅を取得して、そのまま高さに設定する方法です。
```javascript
<script>
    window.addEventListener('resize', function() {
        const square = document.getElementById('正方形にしたい要素')
        const width = square.offsetWidth
        square.style.height = width + 'px'
    });

    // ページがロードされた直後にリサイズイベントを手動で発生させる
    window.dispatchEvent(new Event('resize'))
</script>
```

備忘録 😁