OmniAICreator/Qiita-1.07M huggingface dataset:
ABC300Eを解いた【動的計画法,メモ化再帰】


筆者はレート800前後の茶～緑コーダ

ABC300のE問題を解いていく

https://atcoder.jp/contests/abc300/tasks/abc300_e

# 実装コード

公式解説によると、動的計画法を再帰関数で行うようだ。

つまり、メモ化再帰の出番であり、今回もdefaultdict君に頑張ってもらおう。

```python:main.py
import sys
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rI1(): return (int(sys.stdin.readline().rstrip())-1)
def rLI1(): return list(map(lambda a:int(a)-1,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)

class ModInt:
    def __init__(self, x, mod = 998244353):
        self.mod = mod
        self.x = x.x if isinstance(x, ModInt) else x % self.mod
    __str__ = lambda self:str(self.x)
    __repr__ = __str__
    __int__ = lambda self: self.x
    __index__ = __int__
    __add__ = lambda self, other: ModInt(self.x + ModInt(other).x)
    __sub__ = lambda self, other: ModInt(self.x - ModInt(other).x)
    __mul__ = lambda self, other: ModInt(self.x * ModInt(other).x)
    __pow__ = lambda self, other: ModInt(pow(self.x, ModInt(other).x, self.mod))
    __truediv__ = lambda self, other: ModInt(self.x * pow(ModInt(other).x, self.mod - 2, self.mod))
    __floordiv__ = lambda self, other: ModInt(self.x // ModInt(other).x)
    __lt__ = lambda self, other: self.x < ModInt(other).x
    __gt__ = lambda self, other: self.x > ModInt(other).x
    __le__ = lambda self, other: self.x <= ModInt(other).x
    __ge__ = lambda self, other: self.x >= ModInt(other).x
    __eq__ = lambda self, other: self.x == ModInt(other).x
    __ne__ = lambda self, other: self.x!= ModInt(other).x

class mint(ModInt):
    pass

mod = 998244353
inv = lambda x: pow(x, -1, mod)

from collections import defaultdict
m = defaultdict(lambda: -1)
sys.setrecursionlimit(10**7)

def main():
    N = rI()
    
    d = mint(inv(5))
    
    def dp(n):
        # err(n,len(m))
        if n > N:
            return mint(0)
        elif n == N:
            return mint(1)
        elif m[n]==-1:
            p = mint(0)
            for i in range(1,6):
                p += dp(-~i*n)
            m[n] = p*d
        return m[n]
    print(dp(1))
    
if __name__ == '__main__':
    main()

```

# まとめ

ABC300Eを解いた、実装にはメモ化再帰と動的計画法を組み合わせた実装を行った。

最近学んだメモ化再帰と、典型アルゴリズムの定番ともいえる動的計画法の組み合わせて解くのは何かしらのエモーショナルを感じた。

また、この問題みたいに、典型アルゴリズムを2つ組み合わせて実装する必要があるというのがE問題の基本的なスタンスなのかと思えてきたのが感想。
React学びメモ

今日学んだこと。

findIndexを使うには()の中に関数が必要。
→入れたアロー関数には引数が必要。

文字の入力は<input>
placeholderで薄い文字をテキストボックスにいれられる。

思ったのはReactはとにかくUseState使う回数多い印象。

あとChatGptには答えかかせるなら、問題形式にして、少しでも頭のフックを作ろう。
day9 『超入門 失敗の本質』日本軍と現代日本に共通する23の組織的ジレンマ

## はじめに
　日本企業の体質の中には軍隊色が強く残っています。本書は、転換期となる今、その悪習に対して、日本軍の失敗と同じ間違いしているから学んで修正しよう！と伝えています。

![「超」入門 失敗の本質 目次2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533414/1ae43e48-ceae-d051-0b85-6ee15558602d.png)



## ポイント
### 第１章 戦略性 
- **大きく考えることが苦手**。俯瞰的な観点から最終目標への道筋作りに失敗。
- 「目標達成につながる勝利」を選ぶこと。目標達成に繋がらない勝利が存在する。
- 戦略のミスは戦術ではカバーできない。
- 指標こそが勝敗を決める。日本は指標が間違っていた。

### 第２章 思考法
- **革新・変化が苦手**。鍛錬が得意。改善が得意。
- 型を反復練習するが、型を超えられない。
- 「売れないのは努力が足りないからだ！」は本当か？
- 目標のための組織ではなく、組織のための目標を作ってしまう。
- 戦局を変えるxxx（例、新技術）がカギだった。

### 第３章 イノベーション
- **ルールを作ることが苦手**。ルールを習熟することが苦手。
- 技術進歩だけではイノベーションは生まれない。
- 効果を失った同じ指標を負い続けるといずれ敗北する。しかし、離れられなかった。

### 第４章 型の伝承
- **方法に依存する**。
- 型の伝承を優先してしまう。
- 成功の本質ではなく、型と外見だけを「虎の巻」として伝承してしまう。
- 過去の成功体験のコピー・拡大だけを求める。
- 経験の伝承ではなく、「勝利の本質」を伝えていく。
- イノベーションの目は組織が奪う。

### 第５章 組織運営
- **現場活用が下手**。
- 司令部が「現場の能力」を活かせない。
- 現場、最前線をまったく理解できない中央部。
- 米軍が追求した、戦果につながる人事システム。
- 新戦略が生まれる場所とは。。。

### 第６章 リーダシップ
- **環境変化を乗り越えることが苦手**。
- 自分の目と耳で確認したいと、耳障りの良い、脚色された情報しか入らない。
- 正確な情報はトップには届かない。
- リーダが組織の限界を作ってしまう。
- 間違った勝利の条件を組織に強要する。
- 居心地の良さが問題解決能力を破壊する。

### 第７章 日本的メンタリティ
- **空気**への集団感染。
- 厳しい現実から目を背ける思考。
- 間違ったリスク管理。
- 場の「空気」が白を黒に変えてしまう。
- 都合の悪い情報を封殺しても問題自体は消えない。
- リスクを隠すと悲劇は増大する。
- 耳に痛い情報を持ってくる人物を絶対に遠ざけない。

## 書誌情報
- 書籍名：「超」入門 失敗の本質　日本軍と現代日本に共通する23の組織的ジレンマ
- 著者：鈴木 博毅
- 出版社：ダイヤモンド社
- ISBN：987-4-478-01687-9

## 参考
-
足が腰について離れない！(FootIK暴発の原因と対処)


## はじめに

UnityではAnimationによってアバターにさまざまなポーズを取らせることができます。しかし、次のような状態になったことはありませんか？

この事象、FootIKが原因であることが多いです。この記事ではFootIKの無効化方法を紹介します。

## 環境

- UnityEditor：Unity2022.3.22f1
- アバター：『ライム』-Lime-【オリジナル3Dモデル】

## FootIKの有無でアニメーションが異なる

こちらのアニメーションで試してみています。

https://booth.pm/ja/items/3793632

FootIKなし
![alt text](https://github.com/fukuda-A-HU/zenn-books/blob/main/images/footik-error-unity/image-3.png?raw=true)

FootIKあり
![alt text](https://github.com/fukuda-A-HU/zenn-books/blob/main/images/footik-error-unity/image-4.png?raw=true)

そもそもFootIKって地面に足がつくようにするための機能なのに、なぜ...？ってなりますよね。

しかし、こちらのアニメーションはどうでしょう？

https://necocoya.booth.pm/items/1634088

FootIKなし
![alt text](https://github.com/fukuda-A-HU/zenn-books/blob/main/images/footik-error-unity/image-8.png?raw=true)

FootIKあり
![alt text](https://github.com/fukuda-A-HU/zenn-books/blob/main/images/footik-error-unity/image-9.png?raw=true)

こちらです！我々が求めていたのはこれのはずです。

## FootIKが正常に動くアニメーションとは

二つのアニメーションの違いは、「animationの設定にFootQ, FootTがあるかどうか」でした。これらを使ってFootIKは動いているようです。これらのキーフレームがないアニメーションについては、前述のような現象が起きてし舞います。

![alt text](https://github.com/fukuda-A-HU/zenn-books/blob/main/images/footik-error-unity/image-10.png?raw=true)


FootIKについては公式のドキュメントに記載があります。

https://docs.unity3d.com/ja/2022.3/Manual/class-State.html

    このプロパティは、ヒューマノイドアニメーションを持つステートにのみ適用されます。これを有効にすると、このステートの Foot IK を尊重します。

FootIK については八つ橋まろん先生のこちらの記事が詳しいです。

https://qiita.com/Maron_Vtuber/items/9c12d45cfb4cae11a83f

## まとめ

FootIKの暴発する場合は一旦FootIKをOFFにしておいて、もしFootIKが必要な場合は、FootQ, FootTがあるかどうかを確認し、自分でキーフレームを打つなど

## 【おまけ】アニメーションの修正...に失敗した話

下記のように、AnimatonウィンドウのAddPropertyを押し、FootQ, FootTを追加してみました。
![alt text](https://github.com/fukuda-A-HU/zenn-books/blob/main/images/footik-error-unity/image-33.png?raw=true)

こんな感じで、成功？
![alt text](https://github.com/fukuda-A-HU/zenn-books/blob/main/images/footik-error-unity/image-44.png?raw=true)

かと思いきや一度停止してもう一度再生してみると...

![alt text](https://github.com/fukuda-A-HU/zenn-books/blob/main/images/footik-error-unity/image.png?raw=true)

　足が頭について離れない！お後がよろしいようで（よくない）
基礎すぎるPythonの文法

アウトプット用です。
とある問題集を解いて私が苦手だと思った部分を紹介します。
## sorted & lambda関数
これは第三位ですね
### 例題 以下の辞書のValueを降順にソートするプログラムを作成

※使用する辞書 :
d = {'B': 222, 'A': 111, 'D': 333, 'C': 444}

▼期待する出力
Valueでソートした辞書 : {'C': 444, 'D': 333, 'B': 222, 'A': 111}

ソートってことは`sorted(d)`だよね！
って最初は思ってたんですが、これだとキーでソートしてしまうんですよ...

ってことで結論の回答です。
```Python
d = {'B': 222, 'A': 111, 'D': 333, 'C': 444}
d2 = sorted(d.items(), key=lambda x:x[1], reverse=True)
print(f"Valueでソートした辞書{dict(d2)}")

# 実行結果
Valueでソートした辞書{'C': 444, 'D': 333, 'B': 222, 'A': 111}
```

ここのミソはsortedの引数3つです
①d.items()
これによってキーと値の両方を取得しています。
```Python
d = {'B': 222, 'A': 111, 'D': 333, 'C': 444}
d2 = sorted(d.items())
print(f"キーと値の両方をソート\n{d2}")

# 実行結果
キーと値の両方をソート
[('A', 111), ('B', 222), ('C', 444), ('D', 333)]
```

②key, lambda
これによってキーではなく値でソート可能
```Python
d = {'B': 222, 'A': 111, 'D': 333, 'C': 444}
d2 = sorted(d.items(), key=lambda x:x[1])
print(f"値でソート\n{d2}")

# 実行結果
値でソート
[('A', 111), ('B', 222), ('D', 333), ('C', 444)]
```
そして第二引数で使われているlambdaです。

これは無名関数と言われており簡単な処理の関数を引数として持ってくる際に使うことが多いです。

解説は以下です。
```Python
def func(引数):
  return 戻り値

# ↓lambda関数化↓
lambda 引数: 戻り値

# 例で使われている部分
lambda x:x[1]
```
今回は渡された要素の2番目の要素である値を返す無名関数となっています。

③reverse
第三引数で`reverse=True`とすることで
降順にすることができます。
## リストのスライス
これは第二位ですね
### 例題 以下のリストでインデックス番号が奇数の要素だけを出力するプログラムを2行で作成

※使用するリスト :
l = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']

▼期待する出力
偶数のインデックス番号 : ['B', 'D', 'F', 'H', 'J']

2行というのにビックリ
for文+if文を複数行書いて実行することはできません。

結論、以下が答えです。

```Python
l = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
print(f"偶数のインデックス番号:{l[1::2]}")

# 実行結果
偶数のインデックス番号:['B', 'D', 'F', 'H', 'J']
```
簡単に表すと`start:stop:step`という表し方です。
何回も解いて慣れることが一番です。
以下が一例です。
```Python
num_list = list(range(10))
# 全て
print(num_list) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 先頭から5つ
print(num_list[:5])  # [0, 1, 2, 3, 4]

# 末尾から5つ
print(num_list[5:])  # [5, 6, 7, 8, 9]
print(num_list[-5:])  # [5, 6, 7, 8, 9]

# 先頭から偶数のインデックス番号
print(num_list[0::2])  # [0, 2, 4, 6, 8]

# 末尾から奇数のインデックス番号
print(num_list[::-2])  # [9, 7, 5, 3, 1]
```

## リスト内包表記
これが第一位で一番厄介でした。例題と一緒に解説します。
### 例題 以下の二次元リストを一次元にするプログラムを3行以下で作成
※使用するリスト：
l = [[1, 2, 3],[4, 5, 6],[7, 8, 9],[10, 11, 12]]
▼期待する出力
一次元にしたリスト:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
```Python
l = [[1, 2, 3],[4, 5, 6],[7, 8, 9],[10, 11, 12]]
new_l = [x for n in l for x in n]
print(f"一次元にしたリスト:{new_l}")

# 実行結果
一次元にしたリスト:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
```
初めて解説を見た時は驚きました。
![スクリーンショット 2024-12-05 20.26.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3918502/e4bdbab1-5bea-7805-8cbb-2620ceea9492.png)
この場合の順序は上の画像のようになります。
1. 赤のfor文
1. 青のfor文
1. 黄色のxをxに格納

これを略さず書くと以下のようになります。
```Python
l = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
new_l = []

# 外側のループ: l の各要素（内側のリスト）を順番に取り出す
for n in l:
    # 内側のループ: n（内側のリスト）の各要素を順番に取り出す
    for x in n:
        # 取り出した要素xをnew_lに追加する
        new_l.append(x)

print(f"一次元にしたリスト:{new_l}")

# 実行結果
一次元にしたリスト:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
```
こっちの方がわかりやすい！
確かにぱっと見はそうかもしれません。

ただ、リスト内包表記には処理時間が短いというメリットがあるのです。また、コードが短くて済むので簡潔になります。
##
元エンジニアのPdMが陥ってしまうやらかし

この記事は [プロダクトマネージャー Advent Calendar 2024](https://adventar.org/calendars/10453) 6日目の記事です。

https://adventar.org/calendars/10453

前日は Taro Yoshioka さんによる [PdMの介在価値ってなんだろう？](https://note.com/taro_yoshi/n/nf0760930fd33) のお話でした。

https://note.com/taro_yoshi/n/nf0760930fd33

プロダクトマネージャー（PdM）がいなくてもプロダクト開発は進むよね、私たちPdMの存在意義は何だろう、と考えることがしばしばあります。この記事では、プロダクトやチームにとってのPdMの価値が分かりやすくまとめられていて、とても参考になりました。

# はじめに

@oyngtmhr です。
ECサービスのプロダクトマネージャーをしています。
キャリアとしては金融系システムの開発からスタートし、クラウドインフラ構築のエンジニアやプロジェクトマネージャーを経験。現在はプロダクトマネージャーとして、プロダクトマネジメント業務を4割、プロジェクトマネジメント業務を6割程度の割合で担当しています。



私のようにエンジニアやプロジェクトマネージャーからプロダクトマネージャーへキャリアチェンジするケースは多いと思います。

この記事では、私自身の経験から、エンジニアやプロジェクトマネージャーがプロダクトマネージャーになって直面した課題とあるべき姿と思うものについて共有します。自分自身の振り返りでもあり、同じようなキャリアチェンジを考えている方の参考にもなればと思います。

なお、ここでいう「エンジニア」とは、Webシステムやエンタープライズ基幹システムの上流から下流工程まで携わるシステム開発者およびプロジェクトマネージャーを含む、広義の意味で使用しています。

# エンジニア意識が引き起こすやらかし

エンジニアとしての知識や経験があるがゆえに、ついエンジニアの領域に踏み込んでしまいます。

- プログラムロジックの細部にまで質問する。なんなら修正案まで提案してしまう
- システムのバグ解消について具体的なログの確認方法を提案する。なんなら自ら調査まで始めてしまう
- 過去の現場での開発手法にこだわる。なんならチームに押しつけようとしてしまう

これらの行動は、前職や現職の初期に経験した失敗です。結果として、エンジニアとの関係を悪化し、本来注力すべきプロダクトマネジメントやプロジェクトマネジメントの時間も削られてしまいました。これは明らかなやらかしでした。

# あるべき姿だと思うもの

これらのやらかしを経て、現在はエンジニア領域はエンジニアに任せ、ビジネスとエンジニアの橋渡し役に徹すること、そしてエンジニアリングが円滑に進むよう、黒子として支援することを意識しています。

- ビジネス側とのコミュニケーションに注力する。ミーティングやチャットを通じて要件を文書化し、システムの実現可能性やコストの検討ができるレベルまで具体化する。
- システム開発で生じる課題について、ユーザーとビジネスの視点から想定される影響を整理し、ビジネス側への説明と交渉を行う。
- ビジネスとエンジニアの間で責任範囲があいまいなボールを拾い上げ、整理した上で適切な担当者に投げる。

とはいえ、エンジニアとしての知識や視点が必要なシーンも多くあるため、そのバランスを意識しながら日々の業務に取り組んでいます。

# エンジニアがプロダクトマネージャーになるメリット

もちろんエンジニア出身でプロダクトマネジメントを実践する際には、数多くのメリットがあります。これらの強みを意識的に活用することで、プロダクトの品質向上とプロジェクトの円滑な進行に貢献できます。

- ソフトウェアの品質に関する理解がある。品質の問題発生時には適切な対策を講じることができる
- 企画段階からセキュリティなどの非機能要件を考慮した要件策定ができる
- データへの理解が深く、データの保管場所や処理フローを把握し、効果的な収集・分析を行える

# 最後に

エンジニアからプロダクトマネージャーになると、エンジニアとしての知識や経験が強みとなる一方で、エンジニアとしてのバックグラウンドをどこまで出していくかのバランスが難しいです。

まだまだ学ぶべきこと、実践すべきことはたくさんありますが、プロダクトを成功に導き、収益を上げること、そしてビジネスとエンジニアを含めたチーム全体が良好な関係を保ちながらやっていけるよう、2025年も挑戦していきたいと思います。
FigmaでVariablesを使って文字数ごとの見た目の違いを素早く検証する

## この記事の概要

UI Stackのような概念が当たり前になりつつある今、Figmaでモックアップを作る際も「ちょうど良い文字数での表示」だけを検証することは少ないと思います。

短いものから長いものまで、色々なパターンを検証するでしょう。

ただ、その際に毎回ダミーテキストを考えるのも面倒です。

というわけで、Variablesを使ってあらかじめダミーテキストを定義しておき、時短を図るための記事です。

## 今回作るもの

見本として、以下の2つのコンポーネントを作成します。

| UserInfo | ArticleCard |
| --- | --- |
| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/8b98bb84-94bb-1fb3-63d2-c580d529a4d3.png) | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/4d5dd8ba-7b0c-c467-b8ab-b73f34cd9763.png) |
| ユーザーアイコン + ユーザー名を表示する | 記事タイトル + ユーザー情報 + 投稿日を表示する |

ArticleCardの中でUserInfoを使用しています。

## Variablesの設定

このようなVariablesを登録します。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/fec83a8f-8e64-9706-fbbd-a37f5853848f.png)

* Collectionを別途作成する
    * 今回は`Dummy text`という名前で作成
    * 他のデザイントークンとは役割も必要なModeも違うので、別のCollectionにしておいた方が良い
* Modeを登録する
    * 今回はPlaceholder, Short, Medium, Longの4つ
    * ProfessionalとOrganizationプランはMode数が4つという制限があるので、このあたりがちょうど良いバランスと思われる
    * 空文字列もあり得る場合、Shortに半角スペースを入れるのも良さそう
* Variableを登録する
    * 今回は具体的な役割のテキストを登録している
    * 汎用的なダミーテキストを用意しておいて、Modeをデータベースの文字数制限に揃える（31文字, 255文字など）と揃えておくのも良い

## Componentsの作成

通常通りComponentを作成した上で、PropertyにVariableを適用するだけです。

1つ目のModeをPlaceholderにしておくことで、Variableの選択時や単にコンポーネントを配置したときに、そのテキストの意味が分かりやすくなります。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/d0d4457f-9914-4bda-71e4-592170e39bac.png)

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/da0731cc-dee5-613b-4125-73e36f4495ba.png)

## ダミーテキストの検証

Componentを配置しているFrame、もしくは1つ1つのComponentを選び、AppearanceからVariableのModeを選択します。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/64bb3465-727b-cc0a-e9c1-fd254db23254.png)

このように選ぶだけで、Variableを適用している箇所の見た目が変わります。
ネストされたComponent（ここではUserInfo）の中身も問題なく変化します。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/ac836ed4-0e6b-c73b-d909-45f044d8df03.png)

これらを実施すると、このようなパターン違いの検証をすぐにできるようになります。
「記事一覧」のようなページであれば、ArticleCardコンポーネントを20個くらい並べて親FrameのAppearanceを切り替えることで一気に色々な場合の見た目を見れます。

| 種別 | 画像 |
| --- | --- |
| プレースホルダー状態での表示 | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/e89572c6-748b-b8fc-2ad7-57b64296dbb8.png) |
| 短いテキスト | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/f5f96431-878a-9dae-b1cc-45cb7d4fbcfc.png) |
| ちょうど良いテキスト | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/a60d7c9a-df82-fa6d-f550-dd61bf8fb682.png) |
| 長いテキスト | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/28714ae1-77e6-32e9-1494-9fd2355f0ffb.png) |

## 注意点

この手法をとった場合、決まったテキストではなく好きなテキストを流し込みたい場合はVariableをdetachしないといけません。

ただ、今回の記事カードのコンポーネントのように「具体的なテキストが必要なわけでも本番データと同期したいわけでもなく、Figmaデータとしてはすべてダミーテキストで構わない」というものもあると思います。
そういう場合はdetachする必要もないので、特にデメリットになることもないかと思います。

常にこのテクニックを使うというよりは、都度テキストを変える必要がある要素は都度変えて、すべてダミーテキストでも構わないようなものならこのテクニックを使う、と場合わけできると良いと思います。
Laravelのマイグレーション：Railsのマイグレーション機能との比較

### はじめに
プログラミング初学者の方にとって、フレームワークの選定は学習の方向性を大きく左右します。LaravelとRailsは、それぞれのエコシステムで高い人気を誇るフレームワークですが、その中でも特に重要な機能の一つが「マイグレーション」です。本記事では、LaravelとRailsのマイグレーション機能を比較し、それぞれの特長を整理します。

### マイグレーションとは？
マイグレーションとは、データベースのスキーマ（テーブルの構造など）をバージョン管理する仕組みです。これにより、開発チーム全員が同じデータベース構造を共有し、変更を適用する手間を省けます。

### Laravelのマイグレーション

#### 基本的な仕組み
Laravelでは、マイグレーションファイルはPHPのスクリプト形式で作成されます。このファイルはデータベースの変更を記述するためのもので、artisanコマンドを使って生成および実行します。

**マイグレーションファイルの生成**

```bash
php artisan make:migration create_users_table
```
上記コマンドを実行すると、以下のようなマイグレーションファイルが生成されます。

```php:php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
}
```

**マイグレーションの実行**

```bash
php artisan migrate
```

**ロールバック**

```bash
php artisan migrate:rollback
```

### Railsのマイグレーション

#### 基本的な仕組み
Railsでは、マイグレーションファイルはRubyのスクリプト形式で記述されます。railsコマンドを用いてファイルを生成し、適用します。

**マイグレーションファイルの生成**

```bash
rails generate migration CreateUsers
```

生成されるファイルの例：

```ruby
class CreateUsers < ActiveRecord::Migration[6.1]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email, unique: true
      t.timestamps
    end
  end
end
```

**マイグレーションの実行**

```bash
rails db:migrate
```

**ロールバック**

```bash
rails db:rollback
```

### LaravelとRailsの比較

| 項目           | Laravel                              | Rails                                |
|---------------------|--------------------------------------|--------------------------------------|
| マイグレーション言語               | PHP                                  | Ruby                                 |
| コマンド   | `php artisan`            | `rails`                          |
| デフォルトでの型        | 明示的に指定                       | 暗黙的に指定                       |
| ロールバック    | `migrate:rollback`                 | `db:rollback`                   |


### 具体例：`users`テーブルの作成
LaravelとRailsで同じテーブルを作成する例を比較します。

#### Laravel

```php:php
Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email')->unique();
    $table->timestamps();
});
```

#### Rails
```ruby:ruby
create_table :users do |t|
  t.string :name
  t.string :email, unique: true
  t.timestamps
end
```

### 初学者におすすめの選び方
**Laravelを選ぶ場合：** PHPに馴染みがある、またはシンプルで直感的なコードを好む場合におすすめです。

**Railsを選ぶ場合：** Rubyのエコシステムを活用したい、または「書きやすさ」を重視する場合に適しています。

### まとめ
LaravelとRailsのマイグレーション機能は、基本的な目的は同じですが、記述言語やコマンド体系に違いがあります。どちらも強力なツールであり、公式ドキュメントを参考にしながら再現性のあるコードを書けるよう練習していきましょう。

公式ドキュメント：

[Laravel Migrations](https://laravel.com/docs/11.x/migrations)
[Rails Migrations](https://railsguides.jp/active_record_migrations.html)

初心者の方でも、この記事が参考になれば幸いです！
エンジニアはすべて知っているようですべては知らない

## 就活が終わっている時期に対して、エンジニアになりたい就活生に向けた記事
エンジニアって全部知ってるんだぁ！
パソコンをｶﾀｶﾀｯﾂｯﾀｰﾝをしなきゃいけないんだ！っていう人たちに向けた記事。


## 何でもは知らない。知ってることだけ
例えば、このような経験はないだろうか？
「私の所属している案件は主にpythonを使ってるんだよね～」
「え、じゃあ。pythonで他アプリのAPIとか使って、統計取ってるの？」
「...いや。そんなことは？」

そう、例え所属している案件が特定の言語を用いていたとしても、その言語の知見は凡人以上あるが、ないに等しい。
では、どのようにしてコーディングをしているのだろうか？では、何故そんな綺麗なコードが書けるのか？

## A.ネット上で調べているから
答えは意外と単純なのだよ。調べているから。

例えば君が
「webサイトを作成してみて！」
という依頼をされてたら、どのようなコードを書くのだろうか。

~~~
<h1>Hello,World!!!</h1>
~~~

素晴らしい。このようなコードを書くなんて。

急にこんなコードを書いてきてもいきなり叱ってはいけないんだぞぉ。
仮にお遊びで作成するならば別に上記のコードでも構わない。
だけど、君はWorkをしている
仕事において、このコードは可用性や保守性は全くないものである。
加えて言うと、固定長の文字列を埋め込んでいるのもナンセンスかもしれない。

### じゃあ、どうすればいいんですか？
## A.ネットで調べましょう！

仮にこれがHTMLという言語が初めて生まれて赤ん坊のころであれば、HTMLを綺麗に書くという情報はどこにも載っていない。だが、時代は変わった！いくらでも情報はこの海の中にあるんだ！
さがせぇ！この情報の海にすべておいてきた！って感じ。

## おしまい
SPMのパッケージ内でRegexが使えない問題

## 概要
SPM（Swift Package Manager）で分割したパッケージ内でRegexを使った正規表現を記述しようとしたところ、以下のエラーが発生しました。

```
'/' is not a prefix unary operator
```

この問題とその解決策について備忘録として記録します。

なお、コード自体はPlaygroundsなどで正常に動作することを確認しており、コードそのものに問題はありませんでした。


## 原因
このエラーの原因は、SPMではデフォルトで`bare-slash literal syntax`（スラッシュ区切りの正規表現リテラル構文）が無効になっているためです。

この構文は、スラッシュ（/）を正規表現リテラルの開始として解釈しますが、既存コードとの互換性を保つためにデフォルトでは無効化されています。例えば、/はコメントや除算演算子としても使われていますが、それらが正規表現として解釈されてしまう恐れがあります。

## 解決策
この問題を解決するには、以下の2つの方法があります。それぞれのメリットや適したケースを解説します。

### 方法1: try Regex()を使用する
1つ目の解決策は、`try Regex()`を使って明示的に正規表現を初期化する方法です。これは、`bare-slash literal syntax` を使用せずに正規表現を記述できるため、設定変更なしで利用可能です。

**サンプルコード**
``` Swift
let runtimeString = #"\d+"# // 正規表現パターンを文字列として定義
let digits = try Regex(runtimeString) // パターンから正規表現を初期化
```
#### メリットと注意点
- **メリット**: 設定変更不要で、正規表現をシンプルに利用可能。既存のプロジェクトやライブラリに影響を与えない。

- **注意点**: 初期化時にエラーハンドリングが必要なため、少し冗長。

この方法は、アプリ内で正規表現の利用頻度が低い場合や、設定を変更したくない場合に適してると思います。

### 方法2: Package.swiftに-enable-bare-slash-regexを追加する
2つ目の解決策は、Package.swiftに`-enable-bare-slash-regex`フラグを追加し、SPMでスラッシュ区切りの正規表現リテラルを有効化する方法です。

**設定方法**
以下のコードをPackage.swiftに追加してください
```Swift
for target in package.targets {
    target.swiftSettings = target.swiftSettings ?? []
    target.swiftSettings?.append(
        .unsafeFlags([
            "-Xfrontend", "-warn-concurrency", 
            "-Xfrontend", "-enable-actor-data-race-checks",
            "-enable-bare-slash-regex",
        ])
    )
}
```

#### メリットと注意点
- **メリット**: スラッシュ区切りで正規表現を記述できるため、より簡潔でエラーハンドリングも不要。特に正規表現を頻繁に利用する場合に便利。

- **注意点**: .unsafeFlagsを使用するため、慎重に使う必要がある。

この方法は、正規表現を頻繁に使用する場合や、コードを簡潔に保ちたい場合に適しています。

### どちらを選ぶべきか？

- **正規表現を少しだけ使う** → 方法1: `try Regex()`
- **正規表現を多用する** → 方法2: `-enable-bare-slash-regex`

利用頻度やプロジェクトの方針に応じて適切な方法を選ぶといいと思います。

## 参考文献
- https://stackoverflow.com/questions/75573646/does-the-swift-package-manager-support-regex-literals
- https://forums.swift.org/t/regex-literals-in-xcode-14-1-packages-swift-5-7/61416
UbuntuでDBBrowser for SQLite

# SQLiteの導入
## バージョン
```cmd:ubuntu
lsb_release -da
Description:    Ubuntu 22.04.5 LTS
```
## ここから
```cmd:ubuntu
sudo apt update
```
```cmd:ubuntu
sudo apt install sqlite3
```
## バージョン
```cmd:ubuntu
sqlite3
>SQLite version 3.37.2 2022-01-06 13:25:41
...
```
# DBBrowserの導入
```cmd:ubuntu
sudo apt install sqlitebrowser -y
```

# DBBrowserの設定

まずはGUIを開きます
```cmd:ubuntu
sqlitebrowser
```
初期状態だと英語で日本語もフォントで文字化けしているので直していきます

## 日本語に対応しているフォントをインストール

```cmd:ubuntu
sudo apt-get install fonts-noto-cjk
```

もしかしたらもっといいフォントがあるかもしれませんが...

## DBBrowserへ

- 画面上部のEdit -> Preferences -> Data Browserでフォントの部分をNoto Sans CJK JPに変更
- DataBaseのText encodingはUTF-8
- GeneralのLunguageをjapaneseに変更
- 最後にGUIを再起動
day8 『アルゴリズム＋データ構造＝プログラム』

## はじめに
　書名を知るだけで、本質を伝える物凄い書籍です！

![アルゴリズム＋データ構造 目次2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533414/974bfa42-dd64-c148-1873-28c2e93e894a.png)



## ポイント
### [ニクラウス・ヴィルト（Niklaus Wirth）](https://ja.wikipedia.org/wiki/%E3%83%8B%E3%82%AF%E3%83%A9%E3%82%A6%E3%82%B9%E3%83%BB%E3%83%B4%E3%82%A3%E3%83%AB%E3%83%88)
- プログラミング言語 PascalやModula-2の設計もしている

### １章 基本データ構造
- （略）

### ２章 ソーティング
- （略）

### ３章 再帰的アルゴリズム
- （略）

### ４章 動的データ構造
- （略）

### ５章 言語構造とコンパイラ
- ここで、コンパイラを作る。当時の私にとって衝撃だったのは、文法定義をして、それを規則的にプログラムに変換する過程を通して、コンパイラが作れてしまうこと。
- プログラミングの文法は BNF(Backus-Naur-Form)で書き起こす。すると、言語処理のパーサが簡単に作れてしまういます。
- 当時は、プログラミング言語を設計することが多くの研究者によって行われていて、その後Lex/Yaccを知るまで、しばらくこの手法に頼ってました。

### （雑記）タイトルが心に響いたその他の著作
- 本書とは離れてしまいますが、タイトルのインパクトという意味で印象に残ったのは、本書の他に『タテのものを、ヨコに見る！』（bit 共立出版）でした。こちらは、構造化プログラミング時代からオブジェクト指向時代にかけて書かれたもので、タイトルいいなぁ～、と思いました。
　この２つは後々、『クラウド＋メディア処理＝◯◯』と、『タテの棒をナナメにした』とで、自分の論文紹介として使うことに繋がりました。

## 書誌情報
- 書籍名：アルゴリズム＋データ構造＝プログラム
- 著者：Niklaus Wirth
- 出版社：日本コンピュータ協会
- ISBN：(日本導入前?)

## 参考
-
Laravel11のルーティングの書き方

# はじめに
Laravel9までは触ったことがあるのですが、そこから時が止まっているので最新バージョンではどれくらい書き方が変わっているのかをまとめたものです。

# ルーティングの書き方
## 基本的な書き方

```PHP: コールバックに直接処理を書く場合
use Illuminate\Support\Facades\Route;
 
Route::get('/greeting', function () {
    return 'Hello World';
});
```

```PHP: コントローラーを指定する場合
use App\Http\Controllers\UserController;
 
Route::get('/user', [UserController::class, 'index']);
```

## 利用可能なHTTPメソッド

```PHP
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
```

複数のHTTPメソッドに対応したい場合、一部を指定する場合は`match`メソッド、全てを使用する場合は`any`メソッドが使える。

```PHP
// getとpostのみ対応
Route::match(['get', 'post'], '/', function () {
    // ...
});

// 全てに対応
Route::any('/', function () {
    // ...
});
```

## リダイレクトルート

```PHP
// /hereから/thereへリダイレクト
Route::redirect('/here', '/there');
```

上記の場合、ステータスコードは302になるので別のステータスコードを設定したい場合は以下のように書ける。
```PHP
// /hereから/thereへ301リダイレクト
Route::redirect('/here', '/there', 301);
```

また、301の場合は以下のようにも書ける。
```PHP
// /hereから/thereへ301リダイレクト
Route::permanentRedirect('/here', '/there');
```

## Viewルート

```PHP
// /welcomeに来たらwelcome.blade.phpを返す
Route::view('/welcome', 'welcome');

// welcome.blade.phpに変数を渡す場合
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
```

## 名前付きルート
```PHP
Route::get(
    '/user/profile',
    [UserProfileController::class, 'show']
)->name('profile');
```

## ルートグループ
### ミドルウェア

```PHP
Route::middleware(['first', 'second'])->group(function () {
    Route::get('/', function () {
        // Uses first & second middleware...
    });
 
    Route::get('/user/profile', function () {
        // Uses first & second middleware...
    });
});
```

### コントローラー

```PHP
use App\Http\Controllers\OrderController;
 
Route::controller(OrderController::class)->group(function () {
    Route::get('/orders/{id}', 'show');
    Route::post('/orders', 'store');
});
```

### サブドメイン

```PHP
Route::domain('{account}.example.com')->group(function () {
    Route::get('/user/{id}', function (string $account, string $id) {
        // ...
    });
});
```

### ルートプレフィックス

```PHP
Route::prefix('admin')->group(function () {
    Route::get('/users', function () {
        // Matches The "/admin/users" URL
    });
});
```

### ルート名プレフィックス

```PHP
Route::name('admin.')->group(function () {
    Route::get('/users', function () {
        // Route assigned name "admin.users"...
    })->name('users');
});
```

# まとめ
書き方という点ではそんなに変わっていないかなという印象でした。

# 参考

https://laravel.com/docs/11.x/routing#main-content
Vercel Functionsでpingとtracerouteが使えなかった

net-pingを使うと、 “Operation not permitted” って表示されたり、pingとtracerouteのコマンドが入ってない

Lambdaの設定の問題だと思う

https://support.glitch.com/t/net-ping-operation-not-permitted/942/3

https://stackoverflow.com/questions/75757759/bash-usr-bin-ping-operation-not-permitted-on-ubuntu-22-04-1-lts-containerd
エラー(未解決)　NoMethodError in Reserves#index

# はじめに

ありふれたアプリですが勉強として床屋(TOKOYA)の予約アプリを作っています。
実行したら以下のようなエラーが出ました。
```エラー
NoMethodError in Reserves#index
Showing /home/projects/tokoya_reserve/app/views/reserves/index.html.erb where line #2 raised:

undefined method `datetime' for #<ActiveRecord::Relation []>
Extracted source (around line #2):
1 <h1>TOKOYA</h1>
2 <%= @reserves.datetime %>
3 <%= @reserves.name %>
4 <%= @reserves.course%>
```

```app/views/reserves/index.html.erb 訂正前
<h1>TOKOYA</h1>
<%= @reserves.datetime %>
<%= @reserves.name %>
<%= @reserves.course%>
```
上記のビューでは、@reservesを単一のオブジェクトとして扱っているが@reservesが配列（複数のレコード）を含む場合、繰り返し処理が必要なので以下に訂正が必要。
```app/views/reserves/index.html.erb 訂正後
<h1>TOKOYA</h1>
<% @reserves.each do |reserve| %>
  <p>日時: <%= reserve.datetime %></p>
  <p>名前: <%= reserve.name %></p>
  <p>コース: <%= reserve.course %></p>
  <hr>
<% end %>
```
## おわりに
とりあえず上記までやって、明日以降ルーティング設定をしたいと思います。
021 AI屋さんの　LLMに２００万トークン全文入力　野良右衛門＋ブログ編02



021 AI屋さんの　LLMに２００万トークン全文入力　野良右衛門＋ブログ編02




-----

https://st.bono0.com/nora01

と言うことで、早速サーバーレスにネットワークストレージをマウントしてアプリを動的に更新できる　webアプリの完成です。
詳細は、下記参照。

-----


前回の　ブログの続きです。
サーバーレスのcloudrun　と　docker仮想環境で
データーを保存するために
ボリュームをマウントします。

設定は簡単です。
cloud storageにバケツを用意したら
あとは、そこに書き込みます。

docker側のパスはdockerfileと　アプリの内容で多少変わりますが
今回は、　/app/data　としておきます。

完成すると
ファイルの保存や、DBの作成、csvファイルの読込みなど
クラウドのサーバーレスでも　なんとかなります。
見かけ上ファイルシステムにマウントしてるので
　pd.read_csv()
もそのままで動きます。
裏では、大変そうですが・・


https://cloud.google.com/blog/ja/products/serverless/introducing-cloud-run-volume-mounts





設定は、二箇所です
上図は、バケツ向けの設定
下図は、docker向けの設定





![スクリーンショット 2024-12-05 21.32.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/5a85ad22-3cd2-a316-ba24-0d1350809586.png)





![スクリーンショット 2024-12-05 20.17.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/2556cbd0-4b46-092c-d8c6-5209a6d18778.png)




サーバーレスでも　ローカルのファイルシステムに保存できるので
もはや、利便性は仮想マシン同等で、
お値段は、サーバーレスのままです。
便利ですね。



目次

https://qiita.com/bono0/items/dc1d000c98af7e07c9a7



無事に、クラウドストレージもマウントできました。
サーバーレスのcloudrun　と　docker仮想環境でも　ハードディスクを利用できました。
完成です。おめでとうございます。





ー続くー
自前のSlackアプリに追加したスラッシュコマンドでJSONのオブジェクトを返す

## 概要

Slackアプリに追加したスラッシュコマンドでJSONを返してBotがSlackチャンネルで発言できるようにしてみる。

## 前提

下記の内容が完了していること。

https://qiita.com/miriwo/items/b43654cba1235f331a75

https://qiita.com/miriwo/items/a57679401c9d7c485a81

## 内容

1. 下記のようにPOSTのリクエストを受け取るGASのコードを修正

    ```js
    function doPost(e) {
      console.log('関数は実行されました');
    
      // オブジェクトの定義
      const data = {
        message: "Hello, World!",
      };
      
      const jsonData = JSON.stringify(data); // jsのオブジェクトからJSONを生成
      const jsonOutput = ContentService.createTextOutput(jsonData); // GASから返すコンテンツを作成
      jsonOutput.setMimeType(ContentService.MimeType.JSON); // 返すコンテンツのMimeタイプを明示的にJSONに設定
      
      return jsonOutput;
    }
    ```

1. 右上の「デプロイ」→「新しいデプロイ」をクリック

    ![CleanShot 2024-12-05 at 22.37.01@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/d0465c0c-d158-5d05-d00e-bc3ca0e3a7e6.png)

1. 「デプロイ」をクリック
1. 「ウェブアプリ」のURLをコピーしてメモ

    ![CleanShot 2024-12-05 at 22.38.24@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b0f8db21-dd03-a686-7ff9-bb01952496e6.png)

1. 下記にアクセス
    1. https://api.slack.com/apps
1. 対象のアプリ名をクリック
1. サイドバーの「Slash Commands」をクリック
1. Name /gas_triggerの鉛筆マークをクリック

    ![CleanShot 2024-12-05 at 22.40.15@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/f8bb2ad1-5647-674a-1016-6e893ba90fa9.png)

1. 「Request URL」の「ウェブアプリ」のURLを貼り付けて保存
1. Slack上で`/gas_trigger`コマンドを実行して`{"message":"Hello, World!"}`が出力されたら完了

## 参考文献

https://developers.google.com/apps-script/reference/content/content-service?hl=ja
OpenCV の Elixir バインディング Evision の紹介

プログラミング言語ElixirにもOpenCVを使えるようにするバインディングEvisionがあります．ElixirにおけるJupyter NoteにあたるLivebookでEvisionを使う方法について紹介します．

## Livebookインストール方法

https://livebook.dev/#install

![livebook.dev](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55223/d2005a9f-ec4d-d69e-6467-71f4fcb1b1c3.png)

下の Run on your machine で Mac もしくは Windows を選ぶか，Run in the cloud の Run on Hugging Face を選ぶ，あるいは，Linux等の場合は，check our READMEを選んで，Dockerで実行します．

## Livebook

下記で + New notebook とします．

![Livebook](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55223/efa14954-b85e-b594-bc29-67ed39c822ef.png)

## Evision実行

Reconnect and setup をクリックして，下記を入れて実行します．

```elixir
Mix.install([:evision, :kino])
```

これにより，Evisionと，Livebookで画像等を表示するプラグインであるKinoをインストールします．

正常に終了した後で，SectionのEvaluateのところに下記を入れて実行します．

```elixir
Evision.imread("(お好きな画像へのPATH)")
```

![Run Evision](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55223/75804b40-8e35-1b43-bf3e-81194a0165d4.png)

基本的に`cv.(メソッド名)`と書くところを`Evision.(関数名)`とすれば，OpenCVプログラマであれば，大体直観的に動かせると思います．

## Evisionの仕組み

Evisionの仕組みって結構巧みにできています．OpenCVのソースコードを読み込んで，Pythonバインディングのコードをパースすることで，インタフェースとC++ライブラリの呼び出すコードを取得し，ElixirとC++FFIのコードを自動生成するというような離れ技をやっているように思います．すごい技術力ですね！
PowerShell 起動 Version とどの profile が利用されているか、を確認できるようにしておく

# 背景

Powershell の起動 Version 7.* という制約があった際、
実際にどっちが動いているか分からないってことがあった

というのも、5.* 系の Powershell 使ってても、<code>pwsh -V</code> って打てば 7.* 系に見えてしまうっていう話と、proile に書き込んでも反応しない！ってならないための予防策

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/4c936913-0108-993e-32ed-74d115fbd882.png)

# 解決策

ってことで、profile に、以下のようなものを仕込んでおくことで、起動時のバージョンと、どの profile を使ってるかを認識して使えるよって話

```powershell: version & profile 表示
# get the PowerShell edition and version
$edition = $PSVersionTable.PSEdition
$version = $PSVersionTable.PSVersion
$profilePath = $MyInvocation.MyCommand.Path

# 表示するメッセージを作成
if ($edition -eq 'Core') {
    $message = "PowerShell Core (pwsh) version $version"
} else {
    $message = "Windows PowerShell version $version"
}

# メッセージを表示
Write-Host "$message"
Write-Host " with: $profilePath"
```

## profile

profile は、条件によって複数読み込まれる。
以下のように、最終的に読み込まれた profile がわかることで、なにが有効になっているかを把握出来る。
分かってないと、設定したのに反応しない！って思うこともあるので。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/eb9eba43-20dd-365f-1202-cc893212a291.png)

https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_profiles?view=powershell-7.4


# あとがき

正直、分かってる人は分かってるので、要らないんじゃね？というオチだったりする :sweat_smile: 

まぁ、<code>-V</code> ではなく、<code>$PSVersionTable</code> 確認のほうが、version 依存しなくていいねってことが分かったので良しとする
【競技プログラミング】AtCoder Beginner Contest 35_B問題

# 問題
https://atcoder.jp/contests/abc035/tasks/abc035_b

## 要約
1. 無限に広い二次元グリッドの原点(0,0)に高橋君とドローンがいる。
2. ドローンは文字列Sに従って移動します。Sは'L'(左)、'R'(右)、'U'(上)、'D'(下)の4種類の命令からなる。
3. Sの一部が'?'に破損しています。'?'は元々L、R、U、Dのいずれか。
4. ドローンの最終位置(x,y)と高橋君(0,0)との距離は、マンハッタン距離|x|+|y|で表される。
5. 整数Tが与えられ、T=1の場合は可能な最大距離を、T=2の場合は可能な最小距離を求める。

変数情報：
- S: ドローンへの命令を表す文字列（一部が'?'に破損）
- T: 求める値の種類を表す整数（1または2）


# 既存投稿一覧ページへのリンク
[一覧ページ](https://qiita.com/o_chan_t/items/fc759695acfaef8df2cc)


# 独り言
不意打ちで難しい問題やって時間潰すのも楽しいけど着実に勉強していこうと思って、diff値に従って学習中。
2016年の問題ってレベルBでもdiff804あるんだ。
まぁ、やっぱり競技プログラム参加者のレベルが爆上がりしているんでしょうね。
予想だけど、若い参加者がメチャクチャレベルを押し上げてる気がする。
私も、今が学生の頃だったら、かなり高い確率でガチ勢になってただろうし。

# アプローチ
ドローンの移動を追跡し、'?'の数をカウントしながら最終位置を計算。
その後、'?'の影響を考慮して最大距離または最小距離を求める。


# 解法手順

1. 入力文字列Sと整数Tを受け取る。

2. ドローンの現在位置を表す変数nowを[0, 0]で初期化する。

3. '?'の数をカウントする変数cntを0で初期化する。

4. Sの各文字について以下の処理を行う：
   - 'L'なら、nowのx座標を1減少させる。
   - 'R'なら、nowのx座標を1増加させる。
   - 'U'なら、nowのy座標を1増加させる。
   - 'D'なら、nowのy座標を1減少させる。
   - '?'なら、cntを1増加させる。

5. nowの座標から原点(0,0)までのマンハッタン距離distを計算する。

6. Tの値に応じて以下の処理を行う：
   - T=1（最大距離）の場合、distにcntを加算する。
   - T=2（最小距離）の場合、distからcntを減算する。
     - もしdistが負になった場合、distを2で割った余りを取る。

7. 最終的なdistを出力する。


# ACコード
```python:ac.py


def solve(S, T):
    # 移動方向と対応する座標変化を定義
    order = ["L", "R", "U", "D", "?"]
    direction = [[-1, 0], [1, 0], [0, 1], [0, -1]]

    # 2. ドローンの現在位置を表す変数nowを[0, 0]で初期化する
    now = [0, 0]

    # 3. '?'の数をカウントする変数cntを0で初期化する
    cnt = 0

    # 4. Sの各文字について処理を行う
    for i in range(len(S)):
        if S[i] == order[0]:  # 'L'の場合
            now[0] += direction[0][0]
            now[1] += direction[0][1]
        if S[i] == order[1]:  # 'R'の場合
            now[0] += direction[1][0]
            now[1] += direction[1][1]
        if S[i] == order[2]:  # 'U'の場合
            now[0] += direction[2][0]
            now[1] += direction[2][1]
        if S[i] == order[3]:  # 'D'の場合
            now[0] += direction[3][0]
            now[1] += direction[3][1]
        if S[i] == order[4]:  # '?'の場合
            cnt += 1

    # 5. nowの座標から原点(0,0)までのマンハッタン距離distを計算する
    dist = abs(now[0]) + abs(now[1])

    # 6. Tの値に応じて処理を行う
    if T == "1":  # 最大距離の場合
        dist += cnt
    else:  # 最小距離の場合
        dist -= cnt
        if dist < 0:
            dist %= 2

    # 7. 最終的なdistを出力する
    print(dist)

if __name__=="__main__":
    # 1. 入力文字列Sと整数Tを受け取る
    S = input()
    T = input()
    solve(S, T)
```


# 机上トレース
## 入力例3
1. 入力文字列Sと整数Tを受け取る。

   S = UUUU?DDR?LLLL
   T = 1


2. ドローンの現在位置を表す変数nowを[0, 0]で初期化する。
3. '?'の数をカウントする変数cntを0で初期化する。

4. Sの各文字について以下の処理を行う：
   - 'L'なら、nowのx座標を1減少させる。
     (0,0) -> (-4,0)
   - 'R'なら、nowのx座標を1増加させる。
     (0,0) -> (-3,0)
   - 'U'なら、nowのy座標を1増加させる。
     (0,0) -> (-3,4)
   - 'D'なら、nowのy座標を1減少させる。
     (0,0) -> (-3,2)
   - '?'なら、cntを1増加させる。
     cnt = 2

5. nowの座標から原点(0,0)までのマンハッタン距離distを計算する。
   dist = 5

6. Tの値に応じて以下の処理を行う：
   - T=1（最大距離）の場合、distにcntを加算する。
   - T=2（最小距離）の場合、distからcntを減算する。
     T = 1なので、マンハッタン距離をcnt分加算する。

7. 最終的なdistを出力する。
dist = ans = 7
1年間なにもしなかったと思ってしまう現象に名前

# 初めに
最初は普通に1年間の振り返り的な記事を書こうと思ったのですが、「1年間何もしていないような気がしてなにも書けない」現象に陥ってしまいました。そこで、「じゃあなんでそう思うの？」を考えてみようと思います。
~~タイトル死語だな~~

# 今年1年失敗しかしていない気がする
- 本当にミスしかしてない気がする
    - 「これも終わってない、あれも出来てない」
    - 「作った手順通り出来てない」
    - 「この間のトラブルってどうなりました」
- ミスと遅延の挽回のために残業が嵩んだ
    - 本来であれば発生しなかった残業
    - 残業しなければならない状況に自分でしてしまった
 
# 弊害
- 自分のキャリアの積み上げが出来ない
- 自分がどう成長したのかがわからない
- 何が出来るのかがわからない

# なんでこう思うのか
- 目の前のタスクにかかりきりになっていた
    - これまでやったタスクの振り返りが出来なかった
    - 振り返りが出来ない間に何をしたか忘れた
- 自分の仕事を信用していない
    - ケアレスミスが一向に減らない
        - 手順書通りできないとか
    - 知らないことが多すぎる
        - そもそも言われていないこともあるが
            - 言われてないから知りませんはNG
            - 自分から情報を取りに行く必要がある
        - 言われてても把握していないことがある
            - 把握してないから「そんなんありましたっけ」「いやまだ考えてないです」が頻発する
    - 強気に出られない
        - 自分が間違っている（可能性が高い）から、自分と違う主張をされると「あ、そうなんですね」になる
- 成長が感じられない
    - ずっと同じことで注意されている気がする
    - 「前同じ作業したときに同じ注意されたな」

# 反省
- 自分のいい面に目を向けてあげたい
    - 自分は何が出来るのか
    - 何が出来るようになったのか
    - なにを褒められたか
- 自分に自信を持ってあげたい
    - なんで自分に質問されるのか
        - 自分が知っていると思われているから
    - ここまで書いて、配属された当時の上司の **「仕事は減点法」** という言葉にとらわれているのかなという気がしてきた　ミスが許されない世界
JSON.stringify()って結局何？

## 概要

jsでJSONのレスポンスを作るときに大体使う`JSON.stringify()`が何者なのかざっくり調べてみた。

## 内容

一言でいうと「jsのオブジェクトをJSONに変換してくれるメソッド」のこと。
第一引数でJSONに変換したいオブジェクト
第二引数は省略可能で、第一引数で渡したオブジェクトからプロパティを抜粋したり除外したりしてJSON化したいときに使用
第三引数は省略可能で、JSON化後のインデント数を指定

## 参考文献

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
Canbus. のデータ自動連携について

# Canbus. サービスについて
[Canbus. ](https://canbus.com/)サービスとは，データを管理，共有するためのアプリをノーコードで作成可能なサービスである．[料金体系](https://canbus.com/price/)は非常にシンプルで，ユーザ単位のライセンス体型ではなく，利用サイズ（e.g. レコード数）を想定して，それに適したプランを選択し，月額で費用が発生する体型となっている．Canbus. は[トライアル環境](https://canbus.com/trial/)を提供しているが，トライアル環境ではAPI仕様に関する確認は行えず，API仕様の確認は商用環境でのみ（検証用に別途契約を行うことは想定していない）となり，記事が少なかったため，私が試した内容について記事にしてみました．

# Canbus. のAPI仕様について
[Canbus. のAPI](https://support.canbus.com/hc/ja/categories/4402912586265-Canbus-API)を用いると，レコード一覧の取得，レコードの作成，レコードの取得，レコードの編集，レコードの削除が行える．APIを利用するためには，まず，[テーブルのAPIを有効化](https://support.canbus.com/hc/ja/articles/900000155103-Canbus-API-%E3%81%AE%E6%A6%82%E8%A6%81)する必要がある．テーブル単位で有効化を行う必要があり，それごとにAPIの認証情報が発行される．このときに払い出される「テナントID」，「アプリID」，「API キー」，「APIシークレット」の4つの情報は，この後のAPI連携で必要になる．

# Canbus. APIで試したこと


- curlを用いてCanbus. のAPIからレコードを取得
以下コマンドをプロンプトに打ち込むと，レコードの一覧を取得できる．このとき，""ではなく，\\"\\"（"を認識させるために"の前に\をつけること）となる点に注意すること．
```bash
curl -s -o response.txt %url% -H "Content-Type: application/json" -X GET -d "{\"tenant_id\": \"<テナントID>\", \"app_id\": \"<アプリID>\",\"api_key\": \"<APIキー>\",\"api_secret\": \"<APIシークレット>\",\"record_list\": {}}"
```
具体例を交えると，「テナントID」が"AAAA"，「アプリID」が"BBBB"，「APIキー」が"CCCC"，「APIシークレット」が"DDDD"だったとすると，以下のようになる．

```bash
curl -s -o response.txt %url% -H "Content-Type: application/json" -X GET -d "{\"tenant_id\": \"AAAA\", \"app_id\": \"BBBB\",\"api_key\": \"CCCC\",\"api_secret\": \"DDDD\",\"record_list\": {}}"
```

すると，以下のような出力結果が得られる．relustsの中身はレコードの作り方で変化する．
```
{"authen":"OK","results":[{"result":"0","count":XXXX,"length":20,"records":[{"_id":"XXXXXXXXXX","Text_management_number":"XXXXXXXXXX","Text_sna":"XXXXXXXXXX","AppLink_measure_section":"XXXXXXXXXX"},Text_management_number":"XXXXXXXXXX","Text_sna":"XXXXXXXXXX","AppLink_measure_section":"XXXXXXXXXX"},Text_management_number":"XXXXXXXXXX","Text_sna":"XXXXXXXXXX","AppLink_measure_section":"XXXXXXXXXX"}]}]}
```
このとき，Canbus. のAPI仕様を違反している，または入力パラメータに間違いがある，またはそもそもnetwork reachabilityでない場合（Canbus. 側で接続元IPに制限を欠けている場合を含む），[HTTPステータスコードのエラーコード](https://support.canbus.com/hc/ja/articles/900000155103-Canbus-API-%E3%81%AE%E6%A6%82%E8%A6%81)が返却される．
Simple WordPress Membership で「お願いログイン」をスタイリッシュに表示する方法

Simple WordPress Membership は、会員制サイトを簡単に構築できるプラグインとして非常に便利です。ですが、デフォルトの「ログインしてください」のメッセージ表示は少しシンプルすぎるかもしれません。

この記事では、この「お願いログイン」メッセージをスタイリッシュで分かりやすいデザインにカスタマイズする方法を紹介します。

### カスタマイズの方法

カスタマイズはとても簡単で、WordPress テーマの functions.php に以下のコードを追加するだけです。

### コード例
```php wp-content/themes/example/functions.php
function customize_swpm_more_tag_error_msg($error_msg) {
    $error_msg = '
    <div class="swpm-more-tag-not-logged-in swpm-margin-top-10">
        <div style="padding:10px; text-align: center;">
            <p><strong>【こちらは有料記事です】</strong></p>
            <strong>続きを読むには<a href="/">「ログイン」</a>して下さい。</strong>
            <p>ご購読いただくと続きをご覧いただけます。</p>
            <a class="btn" style="border:1px solid #f70075; background-color: #f70075; color: #fff; padding: 10px 20px; text-decoration: none; display: inline-block;">今すぐ会員登録して続きを読む</a>
        </div>
    </div>';
    return $error_msg;
}

// フィルタを追加
add_filter('swpm_not_logged_in_more_tag_msg', 'customize_swpm_more_tag_error_msg');
```

### コードの解説

#### 1. フィルターフックの利用
add_filter を使って、Simple WordPress Membership が提供する swpm_not_logged_in_more_tag_msg フィルターをカスタマイズします。このフィルターは、ログインしていないユーザー向けのメッセージを上書きするためのものです。

#### 2. メッセージのカスタマイズ
HTML を用いて、見やすくスタイリッシュなデザインを作成しています。以下の要素を含めています：

強調された見出し：【こちらは有料記事です】
ログインリンク：<a href="/">「ログイン」</a>
説明文：購読を促すメッセージ
会員登録ボタン：目立つ色と適切な余白を設定したボタン

#### 3. ボタンデザイン
ボタンは CSS で簡単なデザインを施し、視認性を向上させています。スタイルはインライン CSS で記述していますが、外部スタイルシートにまとめることも可能です。

### 表示例

上記のコードを追加した後、ログインしていない状態で有料記事のエリアにアクセスすると、次のような表示になります：

![スクリーンショット 2024-12-05 22.13.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65992/b48ad7a9-61f3-d789-364e-b18bc96208a1.png)

変更後

![スクリーンショット 2024-12-05 22.13.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65992/e18b8f30-519c-fd83-aa28-0a302af6e75c.png)


### 注意点

ボタンのリンク先（href 属性）を実際の会員登録ページに変更してください。
サイトデザインに合わせてスタイルを調整することをおすすめします。
functions.php を編集する際は、バックアップを取るようにしましょう。
まとめ

この方法を使うと、Simple WordPress Membership の「お願いログイン」メッセージを簡単にカスタマイズできます。ユーザーにとって分かりやすく、行動を促しやすいデザインに仕上げることができるので、ぜひ試してみてください。

いいねもらえると励みになります🙇‍♂️🙇‍♂️🙇‍♂️
Kubernetes クラスタのバックアップを取得したいとき

# Kubernetes クラスタのバックアップを取りたい

Kuberentes クラスタの安全性の保持のために、バックアップを取得したい時があります。
組み込みのスナップショット機能を使用して ETCD データベースのスナップショットを取得するときに利用するコマンドを、この記事では説明します。

* etcdctl snapshot save
* etcdctl snapshot restore

## etcdctl snapshot save

ETCD のスナップショットを取得するコマンド。
これによって、渡したパスにスナップショットが取得されます。
コマンド実行例を次に示します。

```sh
$ ETCDCTL_API=3 etcdctl --endpoints=http://ENDPOINTS \
--cacert=CACERT_PATH \
--cert=CERT_PATH \
--key=SERVER_KEY_PATH \
snapshot save /opt/snapshot-pre-boot.db

Snapshot saved at /opt/snapshot-pre-boot.db
```

それぞれのオプションの意味を次に示します。

* `--endpoints`: ETCD サーバが実際にクライアントから接続を受け付けるアドレスを指定
* `--cacert`: ETCD CA 証明書ファイルのパスを指定
* `--cert`: ETCD サーバ証明書ファイルのパスを指定
* `--key`: ETCD サーバがクライアントを識別するために使用する SSL 鍵ファイル

これらのアドレスやパスの確認方法は、後述の「ETCD の設定の確認方法」を参照ください。

## etcdctl snapshot restore

スナップショットを復元するコマンド。
これによって、`etcdctl snapshot save` で取得したスナップショットを復元できます。
コマンド実行例を次に示します。

```sh
$ ETCDCTL_API=3 etcdctl  --data-dir /var/lib/etcd-from-backup \
snapshot restore /opt/snapshot-pre-boot.db
```

バックアップを作成したサーバと同じサーバで復元する場合には、
上記のように、`--data-dir` のオプションのみが必要になる。

復元後には、`/etc/kubernetes/manifests/etcd.yaml` をアップデートするのを忘れないでください。
上記の場合は、ETCD のスナップショットを新しいパス `/var/lib/etcd-from-backup` へ復元したため、
それを YAML ファイルへ反映させます。
具体的には、etcd-data の hostPath の部分を修正します。

```yaml
  volumes:
  - hostPath:
      path: /var/lib/etcd-from-backup
      type: DirectoryOrCreate
    name: etcd-data
```

これによって、コンテナ上の /var/lib/etcd は、コントロールプレーン上の `/var/lib/etcd-from-backup` を指すようになります。
このファイルが更新されると、ETCD Pod は `/etc/kubernetes/manifests` ディレクトリの下に配置される静的 Pod であるため、自動的に再作成されます。

### 注意

ETCD Pod が変更されると、自動的に再起動され、kube-controller-manager および kube-scheduler も再起動されます。このポッドが再起動するまで 1-2 分かかります。次のコマンドを実行すると、ETCD ポッドがいつ再起動されるかを確認できます。

```sh
$ watch "crictl ps | grep etcd"
```

ETCD ポッドが Ready 1/1 になっていない場合は、次のコマンドで再起動し、1 分間待ってください。

```sh
$ kubectl delete pod -n kube-system etcd-controlplane
```

## ETCD の設定の確認方法

### ETCD のバージョン

```sh
$ kubectl describe pod etcd-controlplane -n kube-system| grep -i image
    Image:         registry.k8s.io/etcd:3.5.15-0
```

### ETCD のクライアントからの接続を受付けるアドレス

```sh
$ kubectl describe pod etcd-controlplane -n kube-system | grep advertise-client-urls
   --advertise-client-urls=https://192.168.28.11:2379
```

### ETCD サーバ証明書ファイルのパス

```sh
$ kubectl describe pods etcd-controlplane -n kube-system | grep cert-file
    --cert-file=/etc/kubernetes/pki/etcd/server.crt
```

### ETCD CA 証明書ファイルのパス

```sh
$ kubectl describe pods etcd-controlplane -n kube-system | grep trusted-ca-file
      --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
```

### SSL 鍵のファイルパス

```sh
$ kubectl describe pod etcd-controlplane -n kube-system | grep key-file
      --key-file=/etc/kubernetes/pki/etcd/server.key
```

## 参考

* [Kubernetesドキュメント - クラスターの管理 - Kubernetes向けetcdクラスターの運用](https://kubernetes.io/ja/docs/tasks/administer-cluster/configure-upgrade-etcd/)
ページの再読み込みによってDevToolsのログが消えてお困りのあなたへ

表題の通り、Web開発をしている時にページのリロードが勝手に行われてしまって、ログが消え去り困っている方向けの記事です。

# 解決法
__コンソールタブの設定から「ログを保持」にチェックを入れる！__

- いつものコンソールタブ
![スクリーンショット 2024-12-05 20.59.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778030/fa1da114-c19c-b6ea-f130-2f3fb70329f3.png)


- ２つあるうちの下の歯車マークをクリック
![スクリーンショット 2024-12-05 21.25.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778030/6ec4dd9b-5c3e-90cb-18af-23ebcf371db1.png)


- 出てきたチェックボックスたちの中にある、「ログを保持」(Preserve log)にチェックをいれる
![スクリーンショット 2024-12-05 21.27.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778030/5fa5d968-208f-4d3c-3cc2-dfe9952d9076.png)

これで完了です！

以降、ページ移動時にはログがリセットされる代わりに、以下のような「〜に移動しました」と言うログや、
![スクリーンショット 2024-12-05 22.04.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778030/ae0b2c50-aeac-d805-8cda-810bc3d7bc7d.png)

ブラウザバックしたときには「〜への移動がバックフォワード キャッシュから復元されました」など、
![スクリーンショット 2024-12-05 22.05.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778030/4cb00a02-c3c2-0072-a8de-54e3dd9b6077.png)

かなりわかりやすくページの遷移がログに出てくれるようになります。
ブラウザバックした時にキャッシュを使用していることが明示的に示されているのはかなり良いですね...
なぜか今まで知らなかったAOPの概念

## 本日も読み飛ばしていきましょう！

どうも、限界派遣SESです。
最近はQiitanのために記事を書くことを日課にしてから「こんなクソ記事世の中にさらしてええんか・・・？」と葛藤しています。
そんなこんなで、ひとりアドカレ5日目で、そろそろ書くこと思いつかないなと思いつつ書いていきましょう。

本日はほとんどポエムです。

なぜか今まで知らなかったAOPの概念について書いていきます。

## AOPとは？

AOPとは、アスペクト指向プログラミング(Aspect-Oriented Programming)のことです。

クロスカッティングな関心事を分離して云々と説明されるこれですが、なぜか今までこの概念を知らなかったです。

その理由はフレームワークがそもそもAOPを前提として実装されている事が多いということもあって、使っているのにそれがどういう設計思想で実現されているか？などを知らない事で気づいていなかったりします。

つまり結構身近な存在なのです。

### AOPの基本概念

以下の4点が基本的な概念だそうです。

#### Aspect(アスペクト)

横断的関心事を定義する単位だそうです。

横断的関心事というと何を言っているのかわかりにくいですが、この横断的というのは「なんかいろんなとこで使いそうなヤツ」みたいな意味だと思っています。

- ログ記録
- ユーザーの権限チェック
- トランザクション管理

これらは様々な場所で呼ばれる事が予想されますよね。
これらをアスペクトとして定義します。

#### Join Point(ジョインポイント)

アスペクトを適用できるプログラムの特定箇所のことです。
具体的には以下のような箇所ですね。

- 関数呼び出し
- コンストラクタ呼び出し
- 関数終了
- 例外スロー
- フィールドアクセス

などがあります。
フィールドアクセスで呼び出される処理と言えばバリデーションチェックですね。

#### Advice(アドバイス)

アスペクトが具体的に何を行うか定義したものの事だそうです。

先ほどのアスペクトが関心事に対してこれは実際にどんな処理するんー？って感じですかね。
例えば「メソッドの前後には絶対にログをつける！」みたいな。

#### Pointcut(ポイントカット)

アスペクトを適用する具体的なジョインポイントを定義するルールだそう。

C#をやったことがある人なら以下の構文で理解できますね。具体的にどこにつけられるか？というのを`Attribute`で定義できます。
```cs
//  この属性が利用できる場所を定義
[AttributeUsage(AttributeTargets.Property)] // プロパティのみで利用できる
public class MyAttribute: Attribute{ ... }
```

### これってデコレータでやってた処理じゃん

そうなんですよ。なので、本当に「なぜか今まで知らなかった」って気分です。

例えば、ログ記録であれば関数の開始と最後に必ずログを記録するという処理をしたりするわけです。

```py
def hello_world():
    logging.info(f"Function hello_world started")
    print("Hello, world!")
    logging.info(f"Function hello_world finished")
```

これは、先日の[デコレータの話](https://qiita.com/nikawamikan/items/f3fb14818da518d72fda)がまさにそれでした。
デコレーターを使うと以下のように記述できます。

```py
@log
def hello_world():
    print("Hello, world!")
```

ね、簡単でしょ？

つまり、私は今まで概念のみ何となく理解して、名称は知らずとも勝手にそれを実装したりなんだりをしてきたわけですね。

思えばDiscordBotを作り始めた頃からそれに触れてきたわけですが、概念として知ったのはつい先月(2024/11)のことでした。

~~あれ、初めてDiscordのBotを作ったのって3年前ぐらいじゃ・・・？~~

ともあれ、これにより言語ごとに「Go デコレータみたいなヤツ」という検索ワードではなく「Go　AOP」のようにググれるようになったのはいいことです。

## まとめ

ほぼ独学でプログラマを始めた私にとって、これらの概念は体感的に覚える事が多くなっていました。
それが悪いという訳ではないのですが、結果として共通言語的にそれを話す機会が失われるというのは少し惜しい気がします。
実際、私の知識は独学という事もあってアーキテクチャパターンなどにはかなり弱いです。毎回「これってどこに責任持たせるべきだろう？」となります。

そんなこんなで、やっぱり体系的に学びを得られる書籍はいいなー。と思う今日この頃でした。

おしまい
クラスの継承

## クラスの継承とは何か？

継承とは元になるクラス(基底クラス)の機能を派生されたクラス(派生クラス)に持たせることができる。
    継承された基底クラスの関数・変数などはアクセス修飾子public,protected内にあると派生クラスでも使うことができる。

継承にはオーバーライドという機能がある。
    オーバーライドとは基底クラスの関数の中身を使わず派生クラスの関数の中身を使うことができるという機能である。

##  アクセス修飾子
public 外部からの読み書きが可能になる
protected　基底クラス・派生クラス内のみ読み書きが可能
private そのクラス内のみ読み書きが可能

## オーバーライドの使い方

(基底クラス)
virtual 戻り値　関数名 (引数);

(派生クラス)
戻り値　関数名　(引数)override;

## オーバーライドの注意点
    
関数名　戻り値の型　引数が違うとエラーが起こる

## 仮想関数

仮想関数とは基底クラスで定義した関数を派生クラスでは定義しないことで基底クラスの関数を使うことができることをいう

## 仮想関数の使い方

(基底クラス)
virtual 戻り値 関数名　(引数);

(派生クラス)
定義しない　→　基底クラス内の関数が呼ばれる
戻り値　関数名　(引数)override;　→　派生クラス内の関数が呼ばれる

## 純粋仮想関数
純粋仮想関数とは必ずオーバーライドをしないといけない関数のことである

## 純粋仮想関数の使い方

(基底クラス)
virtual 戻り値　関数名 (引数)= 0;

(派生クラス)
定義しない　→　エラーが起こる
戻り値　関数名　(引数)override;　→　派生クラス内の関数が呼ばれる

## 最後に

ここまで見ていただきありがとうございます。
今回初投稿ということで書きなれていませんし文章もおかしいところがありますし言葉足らずなところがあります。
私はまだ学生なのでこれが正しいという保証はありません。