OmniAICreator/Qiita-1.07M huggingface dataset:
PowerAutomateのExcelOnlineでテーブル更新

# 概要
[前々々回](https://qiita.com/loto0704/items/bb91c53e0f2411b69693)：ファイルの格納
[前々回](https://qiita.com/loto0704/items/c75d32326194088e0c20)：テーブルの取得
[前回](https://qiita.com/loto0704/items/9f1837b38a9c11ae9b59)：テーブルへ追記
と行いまして、今回はテーブルへの追記についての備忘録になります。

# やること


# PowerAutomate全体イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130969/6ae25fa1-eb24-096e-90cd-1455eda831ad.png)



# 手順
- ステップ0-1：（SharePointにExcelファイル格納）
- ステップ0-2：（テーブルの取得）
- ステップ1：行の取得
    - コネクタ：ExcelOnlineの「表内に存在する行を一覧表示」を選択
    - 場所：Excelを格納したSharePointのサイトを指定
    - ドキュメントライブラリ：ドキュメント
    - ファイル：Excelを格納した「Path」
    - テーブル：ステップ1で取得したテーブルの「ID」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130969/f8fbdf41-55dc-7636-22f9-3f23da0009e2.png)

- ステップ2：Jsonの解析
    - コネクタ：データ操作のJSONの解析を選択
    - コンテンツ：ステップ2で取得したvalueを選択
    - スキーマ：下記参照
```
{
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "@@odata.etag": {
                "type": "string"
            },
            "ItemInternalId": {
                "type": "string"
            },
            "ID": {
                "type": "string"
            },
            "送信先メールアドレス": {
                "type": "string"
            }
        },
        "required": [
            "@@odata.etag",
            "ItemInternalId",
            "ID",
            "送信先メールアドレス"
        ]
    }
}
```

- ステップ3：行の更新
    - コネクタ：ExcelOnlineの「表内に存在する行を一覧表示」を選択
    - 場所：Excelを格納したSharePointのサイトを指定
    - ドキュメントライブラリ：ドキュメント
    - ファイル：Excelを格納した「Path」
    - テーブル：ステップ1で取得したテーブルの「ID」
    - 項目のプロパティを指定する **※1**：下記画像参照
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130969/1d6a7ad5-6368-0fde-ee39-d6c5b58e910d.png)


※1：テーブルが動的の場合出現し、配列で指定可能です。
弊研究室における卒論の終わらせ方

# はじめに
私が第4志望の研究室に入れられてもう卒論の提出時期に差し掛かっています、私は元気ではありません。周りもみんな狂っています。
ところで、弊研究室では教授の対応がとてもとても遅いです。テンプレートも用意しますといってからしばらく時間がかかりました。なので私は後輩のためにここに書き記しておきます。分からないことがあれば教授や先輩に聞くのが一番ですが、待っている時間がもったいないほど卒論提出間際でテンプレートを用意してくれます。何事も早めに動くのが吉です。

完全に身内向けなのでご了承ください。
# 目次
<!-- タイトルとアンカー名を編集 -->
1. [一年間の流れ](#Chapter1)
1. [弊研究室の仕様](#Chapter2)
1. [やっておくべきこと](#Chapter3)
1. [ちょっとしたトラブルシューティング](#Chapter4)
1. [最後に](#Chapter5)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# 一年間の流れ
まず、基本的に夏合宿➔中間発表➔卒論発表という流れだと思います。
ここでパワーポイントで発表用スライドを用意しなければなりませんが、そこら辺は先輩や教授が教えてくれると思います。
問題なのが、卒論です。卒論では、[Latex](https://texwiki.texjp.org/?LaTeX%E5%85%A5%E9%96%80)という文書作成ツールを用います。ちなみに中間発表はWordなので余計ややこしいです。

<a id="#Chapter2"></a>
# 弊研究室の仕様
Latexに関してですが、そもそも何も教えてもらっていない状態で書き始める必要があります。しかも、そのLatexでのテンプレートを渡されるのは私達の代では年末付近でかなり忙しくなりました。親にも顔を合わせていません。そしてバージョンがはちゃめちゃ古いと思うので、あまり調べても参考にならないサイトが多数です。
あと、画像のファイルの拡張子としてepsを使うので変換できるサイトやAdobeを用意しておくと安心です。
また、手渡しで提出するため時間とお金がかかる人はかかります。

<a id="#Chapter3"></a>
# やっておくべきこと
テンプレートが配られる前に研究をある程度進めることはもちろんですが、関連研究と最初の部分（はじめに、など）をどこかWordかなんかで書いておくといいです。先行研究は10個とか準備しておくといいです。まぁそれくらい読んでおいて損はないですしね。

<追記>
卒論提出前にお気持ち表明案件がありました。教授は何も行ってくれないんでコミュニケーション取るか、すべての可能性を考慮して行動してください。
まず、提出（訂正など）は紙ですが、本提出はtexファイルなどです。作り終わったら**絶対に**フォルダごとクラウドに上げるかなんかしてください。提出2時間前に言われて締め切りに間に合いませんでした。
それと、texで書ける環境を作れないと詰むので早めにやってください。教授に言われようが5W1Hがないので理解できません、最悪の場合を想定しましょう常に。

<a id="#Chapter4"></a>
# ちょっとしたトラブルシューティング

## 文字化け問題
utfの方とjisの方があると思うんですけど、jisを使えば行けると思います。Texworksを使っていたら設定からjisに変えれば～みたいな話も先輩にされましたが、多分jisでいけると思います。

## 図の番号が[??]になる問題
```言語名:soturon.tex
platex soturon.tex  
platex soturon  
dvipdfmx soturon
```
卒論用のLatexでは、複数のtexファイルが存在しますが集約されてるsample.tex（おそらく）をコンパイルすればいいです。ここで、コンパイルの仕方を調べていくと色々出てきますが、弊研究室のテンプレートファイルではこのようにすれば大丈夫です。
また、拡張子がなくてもコンパイルいけます。

## usepackage使えない問題
```言語名:kougai.tex
\documentstyle[subcaption,eclepsf,graphicx]{kougai}
%docyumentstyleのオプションとして使いたいオプションを引数に増やします。
\begin{document}
```
プリアンブルに以下の記述が必要です、とかサイトに書いてあるのを見てもエラー出るわ！！って思いましたがバージョンが古いのが悪いのです。こうしましょう。[オプション]{ファイル名}となっているらしいです。

<a id="#Chapter2"></a>
## VScodeでやるとエラーめちゃ出る問題
放置してても動きます、なぜか。これはLatexの仕様なんでしょうけど分からないのでわかる人に聞いてください。

<a id="#Chapter5"></a>
# 最後に
とりあえず教授はさっさとテンプレート更新してください。記事が参考になりません。
まだまだあれば随時更新したいと思います。卒論がんばってください（瀕死）


<a id="#reference"></a>
# 参考文献
- [usepackage問題](https://groups.google.com/g/comp.text.tex/c/v6hg6xIzZko)
- [eps変換](https://www.aconvert.com/jp/image/png-to-eps/)（まぁ本来はAdobeやらパワポでやるべきなんでしょうけど）
Azure無料アカウントを従量課金＋Basicサポートプランで更新する方法

### この記事でわかること

・Azureのサブスクリプション確認方法
・Azureアカウントが無料アカウントのままか、従量課金制になっているか
・Azure無料アカウントを従量課金＋Basicサポートプランに更新する方法

### ①サブスクリプションからアカウントの状態を確認する
https://azure.microsoft.com/ja-jp

まずグローバル管理者としてAzureにログインします。
（多くの無料アカウント利用者にとって、グローバル管理者=Azure無料アカウント登録時のアカウントです。サブスクリプションを管理できる権限があれば何でもかまいません。）

ログイン後、上部にある検索バーから「サブスクリプション」と入力し、サブスクリプションページに飛びます。
![スクリーンショット 2023-01-15 20.13.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/2b17d381-b9f1-1269-c345-dbcfa0760663.png)

無料アカウントユーザーかつ他にサブスクリプションを作成していないならこのように表示されているはずです。
（他にサブスクリプションを作成している場合作成済みのサブスクリプションが表示されます。
その場合「概要」を選び次の作業に移ってください。）
![スクリーンショット 2023-01-15 20.23.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/ececb72a-ae86-8308-7dda-d6dc50e2d483.png)

「＋追加」ボタンを押します。
**無料アカウントの場合「新しいサブスクリプションを作成する前に、アカウントをアップグレードしてください」と上部に表示されます。**
「今すぐアップグレード」を押します。
![スクリーンショット 2023-01-15 20.23.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/81652fbd-9210-4ce1-739c-7d5fae563add.png)

まず電話番号での追加認証とクレジットカードによる支払い情報登録（アカウント作成時に登録図済みなら登録不要）を求められます。
![スクリーンショット 2023-01-15 20.23.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/32b79711-f817-b22e-0c9a-18786316f203.png)

Azureの説明に従い進めて行きます。
サポートプランのみBasicを間違いなく選びましょう。Basicプランが無料です。
![スクリーンショット 2023-01-15 20.24.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/a2e84c39-33fa-e52b-a641-a7e16149039b.png)

元々サブスクリプションが1つもなかった場合→このままサブスクリプションを作成して作業完了。
サブスクリプションがあった場合→アップグレードして完了（たぶんですが）。

従量課金制に切り替えた後は、何かしらの課金されすぎ対策をすることをお勧めします。
（今後機会があれば紹介したいと思います。）

以上。

公式の説明ページだけではわかりにくい部分があったので自分の見直しのために作成いたしました。
誤りやわからない部分がありましたらコメントでお知らせください。
dockerでNFSサーバー構築

## gitからコピー
```
git clone https://github.com/GoogleCloudPlatform/nfs-server-docker.git
```

```
cd nfs-server-docker/1/debian11/1.3/
```
## dockerファイル関係編集
```
vi Dockerfile

# Copyright 2016 The Kubernetes Authors.
# Copyright 2018 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# FROM gcr.io/google-appengine/debian9
FROM debian:bullseye-slim

ENV NFS_VERSION 1:1.3.4-2.1

ENV C2D_RELEASE 1.3.4

RUN set -x && \
    apt-get update && apt-get install -qq -y nfs-kernel-server && \
    rm -rf /var/lib/apt/lists/* && \
    mkdir /exports

COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +rx /usr/local/bin/docker-entrypoint.sh

VOLUME /exports

EXPOSE 2049/tcp
EXPOSE 20048/tcp

ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
CMD ["/exports"]
```
```
vi docker-compose.yaml

version: '3'

services:
  nfs-server:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      TZ: '=JST-9'
      USERID: 1001
      GROUPID: 1001
    volumes:
      - ./exports:/exports
    privileged: true
    restart: always
    ports: 
      - "2049:2049"
      - "20048:20048"
```
## nfsserver構築
docker-composeは複数コンテナで構成されるプロジェクトの起動・停止などの手順を、yamlファイルに定義した設定内容に基づいて自動的にしてくれるツール。-dはバックグラウンドで実行。
```
docker-compose up -d
```
複数サーバー間で、ネットワークファイル共有をするにはNFSサーバーにマウントするための機能を提供するnfs-commonをインストール。
```
sudo apt install nfs-common
```
## サーバーディレクトリにマウント
```
sudo mkdir -p /mnt/nfs_share
```
```
sudo mount -t nfs 172.18.0.2:/exports /mnt/nfs_share
```
```
## マウント状態確認
~$ sudo df -T

Filesystem          Type  1K-blocks     Used Available Use% Mounted on
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
172.18.0.2:/exports nfs   479079424 14567936 440101888   4% /mnt/nfs_share
```
草莽Erlang ── 26. lists:uniq

口で言うより行うことがErlang習得への近道と信じています。

https://qiita.com/mnishiguchi/items/9237780e849d80a85e11

## lists:uniq/1

リストから重複した要素を取り除きます。

https://www.erlang.org/doc/man/lists.html#uniq-1

```erlang
> lists:uniq([3, 3, 1, 2, 1, 2, 3]).
[3,1,2]

> lists:uniq([a, a, 1, b, 2, a, 3]).
[a, 1, b, 2, 3]
```

## lists:uniq/2

一意かどうかを判定する関数を渡せます。

```erlang
%% タプルの値で一意かどうかを判定

> L1 = [{b, 1}, {a, 1}, {c, 1}, {a, 1}]

> lists:uniq(fun({K, _V}) -> K end, L1).
[{b,1},{a,1},{c,1}]
```

```erlang
%% マップのキーで一意かどうかを判定

> L2 = [#{x => 2}, #{x => 1}, #{x => 3}, #{x => 2}]

> lists:uniq(fun (#{x := X}) -> X end, L2).
[#{x => 2},#{x => 1},#{x => 3}]
```

https://www.erlang.org/doc/man/lists.html#uniq-2

[listsモジュール](https://www.erlang.org/doc/man/lists.html)には他にもリスト処理のための関数がたくさんあります。

## Elixirにも挑戦したい

闘魂ElixirシリーズとElixir Schoolがオススメです。

https://qiita.com/torifukukaiou/items/3b65e5c04fa8c55f526e

https://elixirschool.com/ja

https://qiita.com/piacerex/items/09876caa1e17169ec5e1
変数の値を含んだ文字列を作成したいときはf文字列を使うとよい

# やりたいこと
変数の値を含んだ文字列を作成したい

# 結論
f文字列を使用するとよい(Python3.6以上に限る)

# 方法1: +演算子を使用する
## ソースコード
```python
name = '太郎'
text = '私の名前は ' + name + ' です'

print(text)
```
## 出力
私の名前は 太郎 です


# 方法2: format()を使用する
## ソースコード
```python
name = '太郎'
text = '私の名前は {} です'.format(name)

print(text)
```
## 出力
私の名前は 太郎 です

# 方法3: f文字列を使用する
## ソースコード
```python
name = '太郎'
text = f'私の名前は {name} です'

print(text)
```
## 出力
私の名前は 太郎 です

# 参考
https://note.nkmk.me/python-f-strings/
初心者質問ですみませんをやめてみよう！


プログラミングを始めて、はや３か月。
毎週課題提出をしてはいるものの、改めてコードについて聞かれると分からないな、、、。っていうことありませんか？
だけど周りはどんどん学習が進んでいって、今更こんなこと聞きづらいよな。などど二の足を踏んでしまう気持ち、分かります。痛いほど分かります。わかりみです。

今日ちょうどAnime.JSに挑戦している時に、疑問点があり、思い切ってまえたつ大先生に質問したところ、JS学んだはずなのに理解できてなかったぞ！という気付きがいくつかあったので共有させていただきますね。

▼コードの参考にしたページはこちらです▼
https://www.youtube.com/watch?v=-2dyyzU2O-o

- ## 「:」の後にfunctionが来てる意味は？
```JavaScript:
targets:".block",
          translateX:function(){
            return anime.random(-800,700);
          },
```
初めの頃の学習では「〇〇〇:△△△」のようにvalueが短い文字列になっていることが多かったのですが、この場合は「短いテキストをkeyに渡している」という状況ですね。
それと同様に「長い記述の関数をkeyに渡す」ということも可能なのです。valueは短いテキストであるという固定観念が混乱の原因でした。

- ## VSCode上で黄色くなる長い単語、何？
```JavaScript:
container = document.querySelector(".container");
```
上記では緑色になっていますが、VSCodeで記述すると「querySelector」の部分が黄色くなります。これを「魔法」と呼ばれている機会に遭遇することがよくありますが、詰まるところ何？って感じでした。
これは特定のライブラリを読み込むことで使えるメソッドのこと。ここでのライブラリは「anime.min.js」となります。
つまり、今日の晩御飯にかに玉を食べたいな！と思った時に、普通であれば八百屋や魚屋でたけのこ・にんじん・かに肉・かまぼこ・きくらげ・しいたけを買わなければなりませんが、「永谷園」というライブラリが用意した「広東風かに玉の素」というメソッドを用いることで誰でも簡単においしいかに玉が作れるということですね。そうですね（？）

ライブラリが違うと、もちろん使えるメソッドも異なりますのでこれが「丸美屋」の「かに玉の素」だと全く違うかに玉が出来上がるということですね。（伝わってる？）

- ## 「 } 」の後の「 , 」って何？

```JavaScript:
scale:function(){
            return anime.random(1,3);
          },
```
functionの最後に付いているカンマ。これって何の役割があるの？と思っていたんですが、結論、**無くてもOK**らしいです。「ここまでが一つのオブジェクトですよ～」を表す為のカンマなのですが、処理の一番最後のカンマってみんな付けるの忘れちゃうよね。という世話心から、JavaScriptではカンマが無くてもエラーが出ないようにデフォルト設定されているそうです。やさしい世界。

- ## 思い切って質問してみると一気に頭がクリアになるよ

「こんなこと聞いて大丈夫かな？」「そこもう勉強したところじゃん！と思われるかな…」みたいな気持ちは誰しもが持っていると思うのですが、誰もそんなこと気にしてないから大丈夫だよ！と言ってあげたいですし、現に今この文章を通してお伝えしています。

そして、分からないことがクリアにあったらそれを誰かに教えてあげることで、自分のアウトプットにもなるという素晴らしいエコシステムですね。今後もこのエコシステムどんどん回していきましょう！

以上、本日の学習の気付きでした！
Systemctl Timerが動かないなと思ったら

# Timerが動かない、、？

タイトル通りなんですけどね。
こんな感じになっちゃいます。

```
$ sudo systemctl list-timers
NEXT                        LEFT          LAST                        PASSED             UNIT                           ACTIVATES                       
...
n/a                         n/a           n/a                         n/a                test01.timer                   test01.service
```

# 何が悪かったの？

もともとの設定はこんなです。
1分おきに淡々と処理を繰り返すようにしたかったのですが、、

```
$ sudo systemctl cat test01.timer
# /etc/systemd/system/test01.timer
[Unit]
Description=My Script Timer

[Timer]
OnUnitActiveSec=1m

[Install]
WantedBy=timers.target
```

結論としては、[Timer]のところに１行足りませんでした。
OnStartupSec=10m とかを足せばOK。

ただし、１回OSを再起動もしないと駄目っぽいですが。

これどういうことだったかというと、元の「OnUnitActiveSec」は前回実行からX後に次の回を実施するという設定。
で、それだけだと、「最初の１回」を実行する指定がされてないのですね。。
最初の１回が無いので、次以降の回も無い、ということのようです。
OnStartupSecなり、OnBootSecなりを指定して、最初の１回の実施タイミングを合わせて指定してやればOK。

蓋を開ければそりゃそうだなんですけど、ちと調査に手こずりました。
文字列の類似度を計算するアルゴリズムを実装した

# レーベンシュタイン距離ではだめなのか
文字列の類似度を計算するアルゴリズムの一つとして、レーベンシュタイン距離がありますが、計算量が *O(mn)* であるため、文字数が増えると計算量が加速度的に増えてしまいます。  
ですので、計算量が少ないものを求めたところ、以下のサイトにあるものが参考になりましたので、Javascript(Typescript)で実装してみることにしました。

https://www.k-intl.co.jp/blog/B_200729A

# N-gramを求める
1-gramから3-gram(unigramとかtrigramとかいうらしい)を求めて、
```js
{[n-gram]:[そのn-gramが出た回数]}
```
を返す関数が都合がよさそうです。
以下のように実装しました。
```ts
const getToNgram = (text: string, n: number = 3) => {
  let ret: { [key: string]: number } = {};
  for (var m = 0; m < n; m++) {
    for (var i = 0; i < text.length - m; i++) {
      const c = text.substring(i, i + m + 1);
      ret[c] = ret[c] ? ret[c] + 1 : 1;
    }
  }
  return ret;
};
```
まんま実装しただけなので、特記することはないです。

# 余弦を求める
余弦を求めるには、`内積/長さの積`を求めれば良いようなので、求めてみました。

```ts
// valueが数値のobjectの数値の和を求める関数。
const getValuesSum = (object: { [key: string]: number }) => {
  return Object.values(object).reduce((prev, current) => prev + current, 0);
};

const calculate =  (a: string, b: string) => {
  const aGram = getToNgram(a);
  const bGram = getToNgram(b);
  const keyOfAGram = Object.keys(aGram);
  const keyOfBGram = Object.keys(bGram);
  // aGramとbGramに共通するN-gramのkeyの配列
  const abKey = keyOfAGram.filter((n) => keyOfBGram.includes(n));

  // aGramとbGramの内積(0と1の掛け算のため、小さいほうの値を足し算すれば終わる。)
  let dot = abKey.reduce(
    (prev, key) => prev + Math.min(aGram[key], bGram[key]),
    0
  );

  // 長さの積(平方根の積は積の平方根)
  const abLengthMul = Math.sqrt(getValuesSum(aGram) * getValuesSum(bGram));
  return dot / abLengthMul;
};
```

# 完成
<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="dyjzpOB" data-user="ajiken4610" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ajiken4610/pen/dyjzpOB">
  文字列の類似度</a> by ajiken4610 (<a href="https://codepen.io/ajiken4610">@ajiken4610</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

以上。
gitkraken

https://knowledge.sakura.ad.jp/26627/

http://qa.elecom.co.jp/faq_detail.html?id=4073


https://dime.jp/genre/799476/#:~:text=1%3AGoogle%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%AB%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3,%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82

https://dev.classmethod.jp/articles/git-pull-local-change-keep/


https://qiita.com/dondoko-susumu/items/ec09378f430ab4dcfe23


https://www.server-memo.net/ubuntu/ubuntu_screenshot.html

https://gist.github.com/hidepin/b54e223d417002be489089b59ab97e8c


https://www.xmisao.com/2014/02/07/get-screenshot-on-linux-by-shutter.html

https://nwengblog.com/teraterm-timestamp/
```bash
git checkout --no-track -b Branch_v.0.8.14 v.0.8.14
git checkout -b v.0.8.14-SNAPSHOT v.0.8.14
git checkout --no-track -b v.0.8.14-SNAPSHOT v.0.8.14
```

```bash
git push --progress "origin" main:main
git push --tags --progress "origin" refs/tags/v.0.8.15
```
### タグ「v0.8.15」を作成してリモートリポジトリに反映する
```bash
git tag v0.8.15
git push origin v0.8.15
```
### ローカルの全てのタグをリモートにプッシュする
```bash
git push origin --tags
```


https://www.slideshare.net/hashimom/ccmakeeclipse

https://qiita.com/t-tkd3a/items/39d9f9f64b6707332cbd

https://qiita.com/yagiaoskywalker/items/38bd5c0d08e35946645b

https://blog.goo.ne.jp/sohgoh/e/9adf8a63d0ebf4ca0101ca47420f60ee


https://blog.goo.ne.jp/xmldtp/e/2b8bd9f0a146f6ac430bcb9b71f812b0


https://scrapbox.io/snaka/git_checkout_%E3%81%A7%E7%89%B9%E5%AE%9A%E3%81%AE%E6%97%A5%E4%BB%98%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B

https://atmarkit.itmedia.co.jp/ait/articles/1806/08/news028.html


https://www.delftstack.com/ja/howto/git/git-diff-meld/

https://runebook.dev/ja/docs/git/git-difftool

https://qiita.com/take5249/items/64d76f1a1acb7a190b6c

https://qiita.com/kohga/items/20819414da2972bc5e0d

https://github.com/craftzdog/dotfiles-public

https://zenn.dev/takuya/articles/7550d21ddd17f121602e

# gitkraken
```bash
wget https://release.gitkraken.com/linux/gitkraken-amd64.deb
sudo dpkg -i gitkraken-amd64.deb
```
PowerAutomateのExcelOnlineでテーブルへ追記

# 概要
[前々回](https://qiita.com/loto0704/items/bb91c53e0f2411b69693)：ファイルの格納
[前回](https://qiita.com/loto0704/items/c75d32326194088e0c20)：テーブルの取得
と行いまして、今回はテーブルへの追記についての備忘録になります。

## 前提
ファイルの格納

https://qiita.com/loto0704/items/bb91c53e0f2411b69693

テーブル取得

https://qiita.com/loto0704/items/c75d32326194088e0c20

ファイル格納とテーブル取得のフローは上記を参考ください。

# やること
1. （SharePointにExcelファイル格納）
1. （テーブルの取得）
1. 行の取得
1. 行の追加

# PowerAutomate全体イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130969/b8104a4f-5545-cbf1-c655-ef1411019c6a.png)


# 手順
- ステップ0-1：（SharePointにExcelファイル格納）
- ステップ0-2：（テーブルの取得）
- ステップ1：行の取得
    - コネクタ：ExcelOnlineの「表内に存在する行を一覧表示」を選択
    - 場所：Excelを格納したSharePointのサイトを指定
    - ドキュメントライブラリ：ドキュメント
    - ファイル：Excelを格納した「Path」
    - テーブル：ステップ1で取得したテーブルの「ID」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130969/31ec050b-8509-eb8a-dbc0-e9f40758ff42.png)

- ステップ2：Jsonの解析
    - コネクタ：データ操作のJSONの解析を選択
    - コンテンツ：ステップ2で取得したvalueを選択
    - スキーマ：下記参照

```
{
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "@@odata.etag": {
                "type": "string"
            },
            "ItemInternalId": {
                "type": "string"
            },
            "ID": {
                "type": "string"
            },
            "送信先メールアドレス": {
                "type": "string"
            }
        },
        "required": [
            "@@odata.etag",
            "ItemInternalId",
            "ID",
            "送信先メールアドレス"
        ]
    }
}
```

- ステップ3：行を追加
    - コネクタ：ExcelOnlineの「表内に存在する行を一覧表示」を選択
    - 場所：Excelを格納したSharePointのサイトを指定
    - ドキュメントライブラリ：ドキュメント
    - ファイル：Excelを格納した「Path」
    - テーブル：ステップ1で取得したテーブルの「ID」
    - 行：下記画像参照

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130969/da2b2b87-473a-5025-46f9-fbf9c29abe34.png)
スマートウォッチ(Garmin)でスマートロック(SESAME)を操作したい！（だからアプリ作った）

# はじめに
帰宅時にスマホを取り出して鍵を開けるのが割りと面倒くさいので、GarminのスマートウォッチでSESAME4を操作できるアプリを作ってみました。
ただ、SESAME公式ではGarminに対応していないため、SESAMEが提供しているWebAPIをコールし駆動させる形で実装します。（なお、WebAPIを使用するためWiFiモジュールが必要）

# Garmin用のアプリって作れるん？
Garmin公式がアプリ開発用のSDKを配布しているため、これを使って実装出来ます。 [^1]

ちなみにプログラミング言語はGarminによる公式独自言語のMonkey Cになりますが、この独自言語、さすがに独自なだけあって情報はかなり少ないです。
環境構築など一部の情報に関してはまとめられている方がいらっしゃいますが、それでも言語仕様の部分になってくると、やはり英語で書かれた公式のドキュメントを頼りに開発することになると思います。 [^2]

なお実装完了後は、Connect IQストアで公開することも可能です。

[^1]: https://developer.garmin.com/connect-iq/overview/
[^2]: ちなみに今回のアプリはオープンソースにしてあるため、それをまるまる参考にしてもいいっすよ！(MITライセンスの範囲内で)

# アプリについて
以下のアプリがスマートロック操作用のアプリになります。
[日本語ページ](https://apps.garmin.com/ja-JP/apps/0ca43b21-43c1-487d-b573-937a561971cf)、[英語ページ](https://apps.garmin.com/en-US/apps/0ca43b21-43c1-487d-b573-937a561971cf)

どういったアプリかはザッと先程のページにあるとおりですが、簡単に説明すると**WebAPIに対応したスマートロックを操作するためアプリ**になります。
モードとして、WebAPIの設定(URLなど)をすべて自力で行う**カスタムAPI機能**とSESAME OS2対応スマートロックにチューニングした**SESAMI API機能**があります。

# 使い方
SESAMEスマートロックを動かすのに必要な情報は主に以下の2つです。
この情報を今回公開したアプリの設定値として入力してください。
- SesameのQRコードを読み取った際の文字列(権限がマネジャー以上のもの)
- SesameのAPIキー

### SesameのQRコードを読み取った際の文字列
セサミの公式アプリで生成したQRコードをカメラ等で読み取った際に得られる文字列です。

アプリから鍵の設定を開くと、鍵をシェアする機能があります。
このセサミの鍵をシェアする機能で、マネジャー以上の権限を持つQRコードを生成します。
<img width="300" alt="sesame.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523180/3c661a27-46f4-fd19-c133-bc064d046926.jpeg">
生成されたQRコードを任意のQRコードリーダーで読み取った文字列が設定値になります。（ssm://から始まる文字列）

### SesameのAPIキー
SESAME APIを使用するためのAPIキーです。
APIキーは以下のページから取得できます。
https://partners.candyhouse.co/login/
<img width="1000" alt="api key.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523180/2bb2b94e-0dba-be38-4b3f-23838775bfb5.jpeg">

# 最後に
作ったアプリをここ数週間は使っていますが、スマホ出さなくていいのはやっぱ楽ですね。
特に外が寒かったりすると手袋とかするので、タッチでなく手元のボタンで操作できるのは便利です。

ただ、まぁ正直、自分が欲しくて作ったところがでかいので、どこかにバグが隠れているかもしれません…
とはいえ、どうせ作ったなら公開までしてみたかったのでやりきることにしました。

もしもバグがあった場合は[GithubのIssues](https://github.com/yamaserif/garminSmartLockApi/issues)にメモってやってください。
時間と気持ちの余裕があったら修正するかもしれません。
【備忘録】 #tweepy でツイート取得しようとしたらハマった

tweepyでツイート内容を取得しようとしたらハマったので備忘録。

## 環境

Pyhton v3.7.6
TwitterAPI v2（Essential）
---権限：Read and write
---プロトコル：OAuth2.0
　↓権限をReadOnlyからRead and writeに変えたときにここが必須項目になっていてOAuth2.0になってしまった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2565307/bf268478-f89f-6bac-aca5-38f52299f8a2.png)

## ハマったこと

以下のコードでツイート取得しようとしたら401エラー（権限がない）と怒られた。

~~~Python:ツイート取得.py
import tweepy

CONSUMER_API_KEY = ''
CONSUMER_API_SECRET = ''
ACCESS_API_TOKEN =''
ACCESS_API_SECRET = ''
tweet_id = ''

auth = tweepy.OAuthHandler(CONSUMER_API_KEY, CONSUMER_API_SECRET)
auth.set_access_token(ACCESS_API_TOKEN, ACCESS_API_SECRET)
api = tweepy.api(auth)

Responses = api.statuses_lookup(auth)
Print(Responses)
~~~

## 原因と解決策
TweepyでTwitterAPIv2を使うときはapiではなくClientを使う必要がある。
また、プロトコルがOAuth2.0の時はCnsumer keyなどは使用せず、BearerTokenを使用する。下記公式ドキュメント参照
https://docs.tweepy.org/en/stable/authentication.html#twitter-api-v2

エラーにハマっているときは自分のTwitterAppがOAuth2.0に切り替わってしまったことに気づいてなかったのが原因だった。

~~~Python:
import tweepy

BEARER_API_TOKEN = ''
tweet_id = ''

client = tweepy.Client(BEARER_API_TOKEN)

Responses = client.get_tweet(tweet_id)
print(Responses)
~~~

公式ドキュメントと設定内容はしっかり読もう！という教訓でした。
【ネットワーク】MACアドレスとIPアドレスの違い



# MACアドレスとIPアドレスの違い

IPアドレスは、最終的な目的地を表す。
MACアドレスは、次の経由地を表す。


# IPアドレスとは

IPアドレス（グローバルIPアドレス）は、インターネット上の住所を表す。
インターネット上で一意に決まっている。

# MACアドレスとは

ネットワークに存在する機器につけられる一意の番号。
各ネットワーク機器に一意でつけられている。


# ARPテーブル

宛先IPとMACアドレスを結びつける表。

宛先IPから次に送るMACアドレスを特定してパケットをバケツリレーのように運んでいく。



# ARP

IPアドレスを使ってMACアドレスを調べる仕組み。


# プライベートIPアドレス

ネットワーク内部で使われるIPアドレス。
ネットワーク内で一意であれば良い。

MACアドレスと同じくネットワーク内のホストを特定することができる。
（MACアドレスが名前だとすると、プライベートIPはネットワーク内でつけられた出席番号みたいなもの。）



# まとめ

IPアドレスは、最終的な目的地を表す。
MACアドレスは、次の中継先を表す。
機械学習効率化のコンセプト動画を作った話

# 1.この記事の内容

[Webアプリケーション開発のお勉強 #6](https://qiita.com/ryoma-jp/items/1b4f1cc90531b408b98d)を記載してから約1年，[AI Dashboard](https://github.com/ryoma-jp/AI_Dashboard)がなんとなく動く状態になってきたので，新たな試みとして[YouTube](https://www.youtube.com/@ryoma_2905/featured)へ動画を投稿してみました．

　投稿した動画 → [機械学習効率化のコンセプト動画](https://youtu.be/w2Iu0p9nosk)

画面録画から動画編集から動画投稿まで，すべてが初めての作業ということもあり，一度記事として整理しておこうと思いました．

本記事では，動画投稿までの作業として，[画面録画](#2-1画面録画)，[動画編集](#2-2動画編集)，[YouTubeへのアップロード](#2-3YouTubeへのアップロード)の3点を紹介します．

# 2.動画投稿までの作業内容

## 2-1.画面録画

スクリーンショットはよく使いますが，録画ってどうやるんだ？　というところからのスタートでした．
調べてみると，YouTubeのライブ配信でも使用されている[OBS Studio](https://obsproject.com/ja)が使いやすそうだったので，これを採用しました．
YouTubeのライブ配信をよく観るのですが，配信者が「OBSが～」とよく言っているので，ツールとしての信頼度は個人的に高く，それで録画もできるなら使おう，というバイアスもありました．

今回は，単に1画面を録画しただけですが，レイヤ構造で録画する画面を作れるので，機会があれば使ってみようと思います．

## 2-2.動画編集

### 2-2-1.編集ソフト探し

検索するとランキングがたくさん出てきましたが，上位に[Power Director](https://jp.cyberlink.com/products/powerdirector-video-editing-software/overview_ja_JP.html)が多く出ていたので，今回はこれを使いました．
編集した動画を保存する為に，[CyberLink](https://jp.cyberlink.com/)のユーザ登録が必要なのと，保存した動画の右下にPowerDirectorの透かしが入ります．

サブスクへ加入すると透かしを消すことができる（＋色々素材を使用できる）ようですが，当面はお試しで活動するのと，透かしがそこまで邪魔ではなかったので，フリー版を使うことにしました．

今後の作業で機能不足を感じたり，透かしが邪魔と感じだしたら，サブスクへ加入しようと思います．

### 2-2-2.BGM

今回の動画には説明音声は入れず，字幕だけで対応することとしました．
無音はさみしいので，[DOVA-SYNDROME](https://dova-s.jp/)からお借りしました．
YouTubeへの利用が可能である点と，多くのライバーさんが利用していることからも，個人的に信頼のおけるサービスでした．

### 2-2-3.動画編集作業

OBS Studioで撮影した動画にBGMや字幕を付ける作業をPower Directorで実施しましたが，直感的な操作で作業できました．
Power Director上で動画の指定フレームのスナップショットを撮ったり，BGMの編集（フェードイン，フェードアウトやゲイン設定など）もできて，一貫して作業することができました．

## 2-3.YouTubeへのアップロード

これはチャンネルを作成して動画をアップロードするだけでした．
動画のアップロードには，動画のタイトル・説明以外に，動画の内容に関するチェック（こども向けかどうか，18歳以上限定かどうか，どの再生リストに加えるかなど）が必要で，想定よりも入力項目が多い印象でした．

# 3.まとめ

動画撮影にあたり，AI Dashboardのバグが見つかり，修正に時間がかかりましたが，撮影・編集・アップロードだけなら半日くらいの期間・作業量でした．

デザインセンスは皆無ですが，階数を重ねることで少しでも良くなるといいな，と思います．

# 4.関連リンク

* [OBS Studio](https://obsproject.com/ja)
* [Power Director](https://jp.cyberlink.com/products/powerdirector-video-editing-software/overview_ja_JP.html)
* [DOVA-SYNDROME](https://dova-s.jp/)
* [AI Dashboard](https://github.com/ryoma-jp/AI_Dashboard)
Pythonを学び始めた時に書いていたコードがあったので何してたのか思い出すために載せるだけの記事

前職のときにPythonに出会って、当時は勉強を兼ねて来客数をデータ化してみようということをしてました。

その時のコードがPCから見つかったので、何してたか思い出しながら載せようと思いました。
※当時の職場に非利益になるような情報は載せません。
　あくまで「こう書けばこう動く」ということを載せるだけなので悪しからず

最初は人数を表にしたいので、データフレームにしました。
![データフレーム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273331/5e33ea0c-822f-2274-133f-8d52000ccc95.png)
このように比較する年を列、比較項目を行として表にしたかったので、
当時の私はこのように書きました。(数字は適当です)

```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

#totalの数字(20xx年と20yy年の人数の比較)
data20xx = {'Separation':["total","weekday","holiday","man","child-man","woman","child-woman"]
            ,'people20xx':[21000,1000,2000,3000,4000,5000,6000]}
data20yy = {'Separation':["total","weekday","holiday","man","child-man","woman","child-woman"]
            ,'people20yy':[32000,2000,4000,10000,2000,4000,10000]}

df_total20xx = pd.DataFrame(data20xx)
df_total20yy = pd.DataFrame(data20yy)
df_total = pd.merge(df_total20xx,df_total20yy,how="inner",on="Separation")

fig, ax = plt.subplots(figsize=(4,4))
ax.axis('off')
ax.axis('tight')
ax.table(cellText=df_total.values,
         colLabels=df_total.columns,
         rowLabels=df_total.index,
         loc='center',
         bbox=[0,0,1,1])
#画像として保存
plt.savefig('20xx-20yy-total.png')

```

1ヶ月ごとの人数を線グラフにしました。
![ダウンロード (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273331/7170f866-384b-1afd-e1f3-3abceffac966.png)

```python

#１ヵ月ごとの線グラフ(20xx-20yy)

plt.plot(columns1,list20xx,color="green",ls="--",marker="*",label="20xx")
plt.plot(columns1,list20yy,color='red',ls="--",marker="o",label='20yy')

plt.xticks(columns1,columns1)
plt.xlabel('month')
plt.ylabel('people')
plt.grid()
plt.legend(bbox_to_anchor=(1, 1), loc='upper right', borderaxespad=0, fontsize=10)
plt.show()
plt.savefig('20xx-20yymonth_total.png')
```

男女(大人、子供)の人数の割合を円グラフで比較してみました。
![ダウンロード (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273331/60807d78-d416-9e00-74d5-7868dc571fb0.png)

```python
# 円グラフ (外側20xx)
plt.pie([11000,5440,3400,1000],
       labels=["Man","ChildMan","Woman","ChildWoman"],
       counterclock=False,
       startangle=90,
       autopct="%1.1f%%",
       wedgeprops={'linewidth':1,'edgecolor':"white"})
plt.axis('equal') 
 
# 円グラフ (内側2019, 半径 70% で描画)
plt.pie([9000,3500,3500,800],
       counterclock=False,
       startangle=90,
       radius=0.7,
       autopct="%1.1f%%",
       wedgeprops={'linewidth':1,'edgecolor':"white"})
   
plt.axis("equal")
 
# 中心 (0,0) に 40% の大きさで円を描画
centre_circle = plt.Circle((0,0),0.4,color='black', fc='white',linewidth=1.25)
fig = plt.gcf()
fig.gca().add_artist(centre_circle)

```

このようなことをしていました。

当時の私は自作関数を使わず、組込み関数だけを使って書いてました。
理由は関数を作るのがめんどくさかったからです。
(当時の自分を殴りたい)

また、人の数え方は目視で人数を数え、そのデータを自分で入力するというだけの物でした…。
ラズパイなどでセンサーの開発をしてみよう！って気持ちはありましたが、その気持ちは前の職場に置いていきました笑

当時は自分が書いたコードが動くだけで満足していましたが、今このコードを見たり当時の作業を思い出せば、なんて無謀なことをしていたのだろうかと思います…。

これらのコードの整理はいつか行いたいとは思います。
Googleプロジェクト管理：プロジェクト憲章の要素

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/a1cc3407-8d1d-b37c-1d3a-50bf9ea5159f.png" width="800">

# プロジェクト憲章について

プロジェクト憲章は、プロジェクトを明確に定義し、プロジェクトが目標に到達するために必要な詳細を概説するものです。よくできたプロジェクト憲章は、プロジェクトマネージャーにとって、成功への秘密兵器となります。

憲章は、プロジェクトのライフサイクルを通じて使用するものなので、 ***<font color="MediumVioletRed">プロジェクトの羅針盤</font>*** と考えることができます。多くのステークホルダーは、プロジェクトが戦略的なゴールに沿っているか、望ましい最終ゴールを達成するための体制が整っているかを確認するために、プロジェクト憲章を見ることになります。プロジェクト憲章は非常に重要であるため、雑多な要素を排除し、適切な量の詳細を盛り込むことが重要です。

他のプロジェクト文書と同様、早い段階から頻繁にチームやステークホルダーとコラボレーションするのがよいでしょう。両者の協力のもとにプロジェクト憲章を作成することで、プロジェクト憲章が主要なステークホルダーの最も重要な懸念に対応し、チームの足並みを揃えることができます。

# プロジェクト憲章の要素

- イントロダクション/プロジェクト概要
- 目標/目的
- ビジネスケース/利益とコスト
- プロジェクトチーム
- スコープ
- 成功基準
- 主要な要求事項または主要な成果物
- 予算
- スケジュール/タイムラインまたはマイルストーン
- 制約条件と前提条件
- リスク
- OKR
- 承認

プロジェクト管理のキャリアを通じて、さまざまな形式のプロジェクト憲章を使用することになるでしょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/d9a3202f-ce72-b8c7-b540-cf5f437cf589.jpeg" width="７00">

- 短くシンプルなプロジェクト憲章は、あまり複雑でない小規模なプロジェクトに使用することができます。
- より複雑なプロジェクトの場合、追加の分析や文書にリンクすることができます。このような項目は、付録にすることができます。

# サンプル


https://docs.google.com/document/d/1r9814d0IyFZAfXTdpYyBATgbbSCjl9qRiGZRTRMtVRA/edit?resourcekey=0-x3MCQP0ykKSZ7VwksDf41w
AWSを基本からまとめてみた【AWS Amplifyを用いたデプロイ】

## Amplifyコンソールを確認する

①作成したアプリを選択し、『Hosting enviroments』を押す。

②『ウェブアプリケーションをホスト』で GitHub を選択し、
『リポジトリブランチ』を追加する。

※ Environmentは、『develop』を選択する。
※ フルスタックの継続的デプロイ（CI/CD）を有効化をチェックする
※ 『AmplifyConsoleServiceRole -AmplifyRole』を選択する

③『詳細設定』のAmplify CLIは、バージョンの数値を合わせて入力する。
例　8.4.0

④『次へ』を押す。

⑤最終確認をして問題がなければ、『保存してデプロイ』を押す。



## 参考サイト
[【AWS Amplify入門】第6回：Amplifyを用いたデプロイ](https://www.youtube.com/watch?v=sJ3n35y-kMY)
ddでisoを作成する（Windows）

CD／DVDを丸ごとisoファイルに保存したいと考えており、ImgBurnなどのフリーウェアを追加したくなかったため、今あるもので実現できないか考えていました。

Windowsの標準機能ではないものの、ほぼ全員がインストールしているであろうGit（Git Bash）のみで実現できます。

# Windowsでddを使用したい

LinuxやmacOSではdd（coreutils）というコマンドを使用すると、簡単にデバイスファイルからisoを作成できます。

```sh
dd if=/dev/scd0 of=out.iso status=progress
```

> `status=progress`オプションを付与すると、ddコマンドは進捗を表示します。デフォルトでは何も表示されないため、これを付けておいたほうが動いている感があり心が落ち着きます。

WSL上でddを利用することを考えましたが、デバイスの扱いがわからず、実現できませんでした。光学ドライブは`\\.\PHYSICALDRIVE*`形式では表されないため、WSLにマウントする方法がわかりません。

https://learn.microsoft.com/ja-jp/windows/wsl/wsl2-mount-disk

# `/mnt`以下にマウントしてmkisofsを使用する（失敗）

先に思い付いた方法は、光学ドライブもC:\、D:\ほかと同様にWSLの`/mnt`以下にマウントして、mkisofsコマンドでisoファイルを作成することでした。

しかし、この方法は正しくありませんでした（コマンドも割愛します）。ディスクの容量よりも小さいisoファイルが完成したので、およそフォルダ内を走査して、ファイル内容のみを固めたファイルを作成したのでしょう。

今回は物理メディアの完全なバックアップが目的だったので、これでは不十分でした。

# Git Bashのddを使う

Windows上でLinux系のツールを使い、デバイスもLinux上のように扱いたいなら、WSLよりCygwin系列の互換レイヤーを利用したほうがよいようです。

Gitをインストールする際に付いてくるGit Bashには、ddが搭載されており、光学ドライブも`/dev/scd*`および`/dev/sr*`にマッピングされています。

https://www.debian.org/releases/jessie/mips/apcs04.html.ja

つまり、再掲ですが、Git Bash上ではこちらのコマンドで光学ドライブからisoを作成することができます。

```sh
dd if=/dev/scd0 of=out.iso status=progress
```

実際に試せばわかることですが、たとえば`/dev/scd0`と`/dev/sr0`はまったく同じデバイスを指しています。どちらを指定してもよいですが、光学ドライブだとわかりやすいので`scd`が気に入りました。

# 余談

- isoからディスクに焼くのは、Windowsの標準機能で可能
- ついでに、USBメモリのバックアップにはDisk2vhdを使用して、仮想ディスクファイルに固めることにした

https://learn.microsoft.com/ja-jp/sysinternals/downloads/disk2vhd
【Laravel】マイグレーションを使ったテーブル作成

# はじめに
Laravelの機能であるマイグレーション機能を使って、テーブル作成を行う方法を説明していきます。

# 作成の流れ
1. コマンドでマイグレーションファイルを作成する
2. マイグレーションファイルにフィールドを記述する
3. マイグレーションコマンドを実行してテーブルを作る

## 1. マイグレーションファイル作成
コマンド実行後、  下記ディレクトリにマイグレーションファイルが作成される。
ファイル名のxxxxの箇所は、作成した日付が表示される。
(例：database/migrations/xxxx_xx_xx_xxxxxxx_create_testtable_table.php)

また、コマンドのファイル名の箇所は次のように名付ける。
`ファイル名：create_テーブル名_table`

``` bash
php aritsan make:migration ファイル名

// 使用例 (テーブル名：testtable)
php artisan make:migration create_testtable_table
```
<br>

作成されたファイルには、下記コードが記述されている。
■ upメソッド
テーブルを生成するための処理を記述する。
デフォルトでは、プライマリキーであるidカラムとタイムスタンプの項目を追加するコードが作成さている。
■ downメソッド
テーブルを削除するための処理を記述する。デフォルトでは作成したテーブルが存在すれば、それを削除する処理が書かれる。

``` php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('testtable', function (Blueprint $table) {
            $table->bigIncrements('id');
			$table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('testtable');
    }
};

```

## 2. マイグレーションファイルにフィールドを記述する
upメソッドの中に作成したいフィールドを定義していきます。
■ Schema::createについて
テーブル作成は、Schemaクラスのcreateメソッドを使って行う。
createは、第1引数にテーブル名、第2引数にはテーブルを作成するためのクロージャを書く。
作成するフィールド定義は、クロージャ内に書く。
フィールドの設定は、Blueprintクラスのメソッドが行っている。
``` php
    public function up()
    {
        Schema::create('testtable', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->integer('math');
            $table->integer('englixh');
            $table->integer('science');
            $table->timestamps();
        });
    }

```

## 3. マイグレーションコマンド実行
下記コマンドを実行すると、テーブルが作成されます。

``` bash
php artisan migration
```

## 参考
https://www.shuwasystem.co.jp/book/9784798060996.html
開発現場に入る前に知りたかったeclipseの便利機能（ショートカット中心）

以下はすべて開発現場にはいってから知ったショートカットです。
知らないと全然ソースを追えないものもあるので覚えておきましょう。
(以下の「+」は「+」の右と左のキーを同時押しするという意味で「+」自体を実際に押すわけではない)

# ctrl + t
ソースを追う中でinterfaceが出てきた際に、その実装を探すために使う。
interfaceのクラス名にフォーカスを当てて使用すると、そのinterfaceを実装している
クラスがポップアップで表示される。

# ctrl + alt + H
あるメソッドにフォーカスを当てて使用すると、どこから呼び出されているかを確認したり、影響範囲を調べるのにも使える。
eclipseでは呼び出し階層タブに表示される。

# F3
変数やメソッド名にフォーカスを当てて使用すると、それらの宣言場所まで飛ぶことができる。
初期値や処理を確認したいときに使用する。

# alt + right、alt + left
ソースを追う中で一つ前にみていたおおよその位置やファイルに戻る。

# ctrl + shift + P
for文やif文などの始まりと終わりの括弧を行き来できる。ネストが深い処理の際に使用する。
括弧にカーソルを当ててダブルクリックしても同じように範囲を調べることができる。

# ctrl + space
変数名を途中まで書いてからこれを使うとプロポーザルが表示される。
長いメソッド名や変数名を書く手間も省ける。

# 以下、ショートカット以外

※インストールされている場合にのみ使用できる
クラスファイル右クリック→open class with→CFR
「ソースが見つかりませんでした」などソースを追う中でライブラリのクラスファイルが出てきた場合に
使用すると、中身を閲覧できる。クラスファイル自体を探すためは「エディタにリンク」状態にしておくとやりやすい。




# 参考URL
https://qiita.com/arai-wa/items/c2eb7387b5bf37b4ace4#%E7%AC%AC1%E4%BD%8D-ctrl--alt--h-%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97%E9%9A%8E%E5%B1%A4%E3%82%92%E9%96%8B%E3%81%8F
[Flutter] TextFormFieldのinitialValueが更新されなかったのでKeyにhashCodeを設定して解決した

# 前提
Flutterで以下のような`TextFormField`のリストを表示していた
![スクリーンショット 2023-01-15 17.17.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352532/e5f1ea35-4b0d-90a5-4cfc-51592bc1cbf2.png)


コードは(不要な部分を省略すると)以下の通り。
mealsをforで回してTextFormFieldと削除ボタンを生成しており、`meal.name`を編集するためTextFormFieldの`initialValue`に設定している。
なおmealsはRiverpodで監視している。

```dart:list
Column(
  children: [
    for (final meal in meals)
      Row(
        children: [
          IconButton(
            onPressed: () => {_removeMeal(meal)}, // mealsの中から該当のmealを消す処理
          ),
          TextFormField(
            initialValue: meal.name,          
          ),
        ],
      ),
    ],
  )
```

# 困ったこと①
上記画像の状態から`昼ごはん`を消しても、`initialValue`が更新されず以下のようになってしまった。
![スクリーンショット 2023-01-15 17.35.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352532/465d1a54-1396-5100-364c-e99bb1c94afb.png)
本当は`[朝ごはん, 夕ごはん]`になってほしい。

この手の問題はFlutterに限らず他のWebフレームワークなどでもあるあるだが、mealsはRiverpodで監視しているためよしなにやってくれるかなと思っていたがそうでもなかった。
※ mealsが更新されたこと自体は検知してWidgetが3つから2つに減っているが、`TextFormField`の`initialValue`はリフレッシュされていない状態


# 解決①
知恵の泉(stack overflow)いわく、
> これは、initState で theTextEditingController を使用して initialValue が設定されているため、
> その値を更新できないためです。**これは単なる「初期値」です**。

そして、

> リアクティブなデータ ソース、つまりネットワークの更新やその他のデータに基づいて変化する可能性のあるデータがある場合、
> 私にとって有効なハックの 1 つは、キーを使用することでした。
> **リアクティブデータのキー(toString())を作ることで、キーが変わるたびにフォームフィールドが変化します**。

とのこと。Vue.jsのv-forでkeyを設定するのと同じ話だろう多分。

# 困ったこと②
Keyを設定したらいいのはわかったけど、mealはkeyになれそうなユニークな項目を持っていないためもう一度困った。
(TextFormFieldのWidget自体が持ってるKeyを使ったりとかできないかなと思ったけどちょっとわからず、、、)

そこで、Rubyにおける`object_id`みたいな、個々のオブジェクトごとに一意の値を得る手段がないかなぁと思って調べたらあった。

# 解決②
mealごとの[hashCode](https://api.flutter.dev/flutter/dart-core/Object/hashCode.html)をKeyとして使うことにした。

公式ドキュメントいわく
>すべてのオブジェクトにはハッシュコードがあります

らしい

```dart:list
Column(
  children: [
    for (final meal in meals)
      Row(
        children: [
          IconButton(
            onPressed: () => {_removeMeal(meal)}, // mealsの中から該当のmealを消す処理
          ),
          TextFormField(
            key: Key(meal.hashCode.toString()), // ← 追加！
            initialValue: meal.name,          
          ),
        ],
      ),
    ],
  )
```
これで無事に昼ごはんだけを消すことができた。
![スクリーンショット 2023-01-15 18.02.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352532/395cf895-78a5-0985-83e0-d236d8e12252.png)



# 参考リンク
- [TextFormField Flutter not changing appropriately](https://stackoverflow.com/questions/51715534/textformfield-flutter-not-changing-appropriately)
- [setState does not update TextFormField when use initialValue](https://stackoverflow.com/questions/58053956/setstate-does-not-update-textformfield-when-use-initialvalue)
- [hashCode property](https://api.flutter.dev/flutter/dart-core/Object/hashCode.html)
systemdを有効にしたWSLを常時起動する(+ssh向けポートフォワーディング)

## はじめに

いつの間にかWSL上でsystemdを動かせるようになっていましたが、systemdを有効にした状態でシェルを閉じるとWSLのインスタンスが自動的にStoppedになってしまいました。

色々試行錯誤した結果、以下の方法で落ち着いたので備忘録的にまとめています。

## TL;DR

- daemonizeコマンドを使用して、initの子プロセスを走らせ続ける。
- 具体例として、以下のPowershellスクリプトを使用してWSLを起動する。
    - https://gist.github.com/k-tahiro/7485d311d2d694c6ba0ad1d7bede336d

## 背景

### WSL上でのsystemd 

- 以下のブログで公式にサポートされたことがアナウンスされている。
    - https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/
    - 以下のファイルを作成することで有効になる。

```/etc/wsl.conf
[boot]
systemd=true
```

### systemdを有効にした際の問題

- 上記の記事の記述から以下がわかる。
    - systemdのサービスはWSL instanceの生存に寄与しない。
    - 既存の手順でinstanceを起動させ続けることができるとのこと。

> It is also important to note that with these change, systemd services will NOT keep your WSL instance alive. Your WSL instance will stay alive in the same way it did before, which you can read more about here.

### 既存の手順では常時起動させることができない

- 上記の記事から以下の記事へリンクが張られている。
    - https://devblogs.microsoft.com/commandline/background-task-support-in-wsl/
- この記事ではtmuxを使用して、一般的なバックグラウンドタスクの実行方法について解説してある。
- これを参考に実行しても、上手くいかない。

```
> wsl -d Ubuntu -e tmux new -d -s htop htop
> wsl -d Ubuntu -e pstree

systemd─┬─
........<中略>......
         ├─tmux: server───htop
```

```
> wsl -d Ubuntu 
$ tmux new -d -s htop htop
$ exit
> wsl -d Ubuntu -e pstree

systemd─┬─
........<中略>......
         ├─tmux: server───htop
```

## 解決方法

- daemonizeコマンドを使用し、initの子プロセスとしてsleepコマンドが無限ループするbashプロセスを起動する。

```powershell
Param(
    [String]$distro = "Ubuntu"
)

Write-Host "Start WSL $distro ..."
wsl -d $distro -u root -e bash -c 'apt list daemonize || (apt update && apt install daemonize -y) && daemonize $(which bash) -c \"while true; do sleep 1d; done\"'
Write-Host "WSL $distro has been started."
```

プロセスツリーを確認すると、確かにinitの子プロセスになっている。

```
> wsl -d Ubuntu -e pstree

systemd─┬─
........<中略>......
         ├─init───bash───sleep
```

## おまけ: ssh向けポートフォワーディング

- 以下でWindowsホストからのproxyを設定

```powershell
$wsl_ip = wsl -d $distro -e bash -c "hostname -I | cut -d' ' -f1"
netsh interface portproxy delete v4tov4 listenport=22
netsh interface portproxy add    v4tov4 listenport=22 connectaddress=$wsl_ip
```
.NET MAUIでプラットフォーム・デバイスの種類ごとの条件分岐

# .NET MAUIでプラットフォームごとの条件分岐
## 目的
主に備忘録として記載。
# 環境
- windows11 HOME 64bit
- Visual Studio2022 community
- .Net framework4.8(533320)
## 参照元
https://learn.microsoft.com/ja-jp/dotnet/api/microsoft.maui.devices?view=net-maui-6.0
## プラットフォームによる条件分岐
- Android
- watchOS
- tvOS
- iOS
- macOS
- Tizen
- MacCatalyst
- WinUI（windows系）
- UWP（2023年1月15日現在互換性維持のためにある）
- Unknown(不明なプラットフォーム)
~~~C#
if ( DeviceInfo . Platform == DevicePlatform . Android ) {
// Android用の処理を記載
}
if ( DeviceInfo . Platform == DevicePlatform . watchOS ) {
// watchOS用の処理を記載
}
if ( DeviceInfo . Platform == DevicePlatform . tvOS ) {
// tvOS用の処理を記載
}
if ( DeviceInfo . Platform == DevicePlatform . iOS ) {
// iOS用の処理を記載
}
if ( DeviceInfo . Platform == DevicePlatform . macOS ) {
// macOS用の処理を記載
}
if ( DeviceInfo . Platform == DevicePlatform . Tizen ) {
// Tizen用の処理を記載
}
if ( DeviceInfo . Platform == DevicePlatform . MacCatalyst ) {
// MacCatalyst用の処理を記載
}
if ( DeviceInfo . Platform == DevicePlatform . WinUI ) {
// WinUI用の処理を記載
}
if ( DeviceInfo . Platform == DevicePlatform . UWP ) {
// UWP用の処理を記載
}
if ( DeviceInfo . Platform == DevicePlatform . Unknown ) {
// Unknown用の処理を記載
}
~~~
## デバイスの種類による条件分岐
- Phone
    - スマートフォン
- Watch
    - スマートウォッチ
- Tablet
    - タブレット
- Desktop
    - デスクトップ
- Unknown
    - 不明なプラットフォーム
~~~C#
if ( DeviceInfo . Idiom == DeviceIdiom.Phone ) {
// スマートフォン用の処理を記載
}
if ( DeviceInfo . Idiom == DeviceIdiom.Watch ) {
// スマートウォッチ用の処理を記載
}
if ( DeviceInfo . Idiom == DeviceIdiom.Tablet ) {
// タブレット用の処理を記載
}
if ( DeviceInfo . Idiom == DeviceIdiom.Desktop ) {
// デスクトップ用の処理を記載
}
if ( DeviceInfo . Idiom == DeviceIdiom.Unknown ) {
// 不明なプラットフォーム用の処理を記載
}
~~~
## 最後に
すべてのプラットフォームで検証する時間とお金がなかったので
間違いあれば指摘をお願い致します。
DockerでVue(Vite使用)の環境構築をしたが、docker-compose upをしてもVueの画面が表示されない時の対処法

## 1. 問題

DockerでViteを使ってVueの環境構築をしたが、localhost:5173を叩いてみてもVueの初期画面が表示されなかった。

![スクリーンショット 2023-01-15 17.10.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638783/b3225e8d-6732-a781-88af-b514a9464920.png)


設定したDockerfileとdocker-compose.ymlは以下の通り。
ポート番号等は特に間違っていなさそう。

```:Dockerfile
FROM node:18.13.0-alpine

ARG WORKDIR

ENV HOME=/${WORKDIR}

WORKDIR ${HOME}

RUN apk update && npm install -g npm

CMD ["npm", "run", "dev"]
```

```docker-compose.yml
version: '3.8'

services:
 db:
  ・・・

 backend:
  ・・・

 frontend:
    build:
      context: ./frontend
      
      args:
        WORKDIR: $WORKDIR
    
    volumes:
      - './frontend:/$WORKDIR'
    # ホストの5173番ポートをコンテナの5173番ポートに繋ぐ
    ports:
      - '5173:5173'
    
    depends_on:
      - backend

```

## 2. 解決法
#### エラー
ログを見ると、networkの箇所に何やら表示されている
``Network: use --host to expose``

```
frontend_1  | 8:09:42 AM [vite] vite.config.js changed, restarting server...
frontend_1  | 8:09:43 AM [vite] server restarted.
frontend_1  | 
frontend_1  |   ➜  Local:   http://localhost:5173/
frontend_1  |   ➜  Network: use --host to expose
```

#### 解決法
下記のGitHubに解決法が2つ載っていた

https://github.com/vitejs/vite/discussions/3396
> The default host now listens to 127.0.0.1 so you only get localhost exposure. It was changed because it is a security concern to expose your file system to external addresses by default.
To get the same behaviour as in v2.2, you can use:
 vite --host
Or set server.host to true in your config.
https://vitejs.dev/config/#server-host

①``npm run dev``する時に、``--host``オプションを付ける
```
npm run dev -- --host
```
②configファイルにhostからアクセスできるよう設定する
```
server: {
  host: true
}
```

今回は②で対応する

```:vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  //ここを追加！
  server: {
    host: true
  },

  plugins: [vue()]
})
```

上記を追加するとNetworkが変更されたことが分かる

```
frontend_1  | 
frontend_1  |   VITE v4.0.4  ready in 1665 ms
frontend_1  | 
frontend_1  |   ➜  Local:   http://localhost:5173/
frontend_1  |   ➜  Network: http://172.21.0.4:5173/
```

アクセスできるようになった！！！
![スクリーンショット 2023-01-15 18.00.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638783/e6fa245b-aa28-4cba-c463-e9aeb1a815f9.png)

## 3. 背景 
この設定が必要になった背景は以下。

デフォルトのホスト(コンテナ側)はポート番号127.0.0.1をリッスンするようになったので、自ホスト以外からのリクエストが拒否されてしまう。これはデフォルトでファイルシステムを外部のアドレスに公開することはセキュリティ上問題があるためこのようになっている。

何の設定もしていない場合、外部アドレス(ホスト)からアクセスすることができないので、ホスト側からアクセス可能とするには、上記の設定が必要。

## 参考

https://github.com/vitejs/vite/discussions/3396

https://qiita.com/generonishimura/items/88742085294bd0b234a6
np.datetime64の使い方

# 内容
 numpyのdatetime64が使いにくいので、ググってもあまりわからなかったので正解ではないかもしれないけど動いたので紹介

# 環境
　python 3.7.15 numpy 1.16.5 または
　python 3.10.8 numpy 1.23.4

# datetime64からdatetimeへの変換
```test.py
  t1 = np.datetime64('2023-01-15T13:11:11')
  #datetimeに変換
  t2 = t1.item()
  #t2だったらいろいろできる
  t2.strftime('%Y/%M/%D %T')
  t2.year
```
SLF4JとLogbackの競合で警告が出る場合の対処方法

# はじめに
今年に入ってサーバー側の調整をお手伝いする機会が多いのですが、koinのslf4jとlogbackを導入したことで以下のような警告が出ていました。
```
log4j:WARN No appenders could be found for logger (com.example.Log4j1). log4j:WARN Please initialize the log4j system properly. log4j:WARN See
```
この対処法に関して備忘録的にまとめておこうと思います。

# 対処方法
調整方法としましては、非常にシンプルです。
build.gradleに以下を記述する形になります。

```
configurations.all {
    exclude(module = "slf4j-log4j12")
}
```

以上になります。
上記を設定しビルドすれば以降は表示されないはずです。

# さいごに
今年はやれる限り色々トライしていきますー！
その過程の知見をどんどん記事にしていきます！
要件定義で使用するフロー図の違い

## はじめに

要件定義はシステム開発の成功を左右すると言われるほど重要と考えられています。
実際に要件定義に携わっていても、そのことを日々痛感しています。

要件定義を進める際、お互いの認識を確認するためにフロー図を頻繁に使用します。
フロー図と言っても粒度の違い、書き出す項目等によって相手への伝わり方が大きく変わるため、その時々で適したフロー図を作成する必要があります。

本記事では、要件定義のためのフロー図について学習した記録をご紹介します。

## 要件定義の流れ（要件定義プロセス）

要件定義プロセスは、ビジネス要件とシステム化要件に大別されます。

| 要件定義       | 概要                                                                                               |
| -------------- | -------------------------------------------------------------------------------------------------- |
| ビジネス要件   | 業務の現状を把握して、課題やニーズを理解することで、あるべき姿（解決すべき要件）を検討するプロセス |
| システム化要件 | ビジネス要件を満たすため、システムの要件（機能、データ等）を検討するプロセス                       |

## フロー図の種類

要件定義で使用するフロー図は主に 3 つです。
それぞれのフロー図は要件定義プロセスによって使い分けをします。

| 要件定義       | フロー図             | ポイント                                                                             |
| -------------- | -------------------- | ------------------------------------------------------------------------------------ |
| ビジネス要件   | 業務全体図           | 経営資源（ヒト・モノ・カネ・情報）が発生する業務を線で結んだ図                       |
| ビジネス要件   | 業務フロー           | IPO（Input Process Output）を明確にして入力(Input)と出力(Output)の業務を線で結んだ図 |
| システム化要件 | システム化業務フロー | 人が行う作業とシステム機能を区別して線で結んだ図（業務フロー ＋ システム機能）       |

![purposeFlowRd_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/f988ba67-faf4-d5fd-21f3-290ef380242e.png)

## 学習参考書

| タイトル                        | 著者                            | 出版社 |
| ------------------------------- | ------------------------------- | ------ |
| 図解まるわかり 要件定義のきほん | 西村 泰洋、相川 正昭、蓮沼 潤一 | 翔泳社 |

ご参考になれば幸いです。最後までお読み頂きありがとうございます。

## 関連した投稿

[Miroでシステム化要件【画面イメージ／画面レイアウト】](https://qiita.com/tamaday/items/b46413b5620849c89b08)
[Miroでシステム化要件【動く画面遷移図】](https://qiita.com/tamaday/items/94af9158e79eec21a71e)
【Django】blockタグの使い方、base.htmlとは？（titleがサーバー名になってしまう場合の理由も）

# 概要
* djangoの魅力の一つとも言われている、テンプレート拡張について簡単に説明。
    * `{% block %}, {% endblock %}`タグとは？
    * `{% extends 'base.html' %}`タグとは？
    * 実際に事例を作って検証してみる
    * 補足①：子テンプレートを`{% block title %}{% endblock %}`とした場合は？
    * 補足②：`block`のあとって決まっているのか？何でもいいのか？

# `{% block %}, {% endblock %}`タグとは？
* {% block %}, {% endblock %}は領域を確保するタグ
* 使い方としては、以下の通り
    * 親テンプレートにHTMLで指定したものをデフォルト値として利用できる
    * 子テンプレートのHTMLで指定したものを、デフォルト値に置き換えて（オーバーライドして）利用できる
* 上記の「デフォルト値」に付随して、`{% extends 'base.html' %}`タグを次に紹介する

# `{% extends 'base.html' %}`タグとは？
* 意味としては「base.htmlの内容をベースに拡張(extend)します」というイメージです。
* これを、親テンプレートとしてbase.htmlを継承するといい、「継承関係」を作ることができます。

# 実際に事例を作って検証してみる
* 以下では、親テンプレートをbase、子テンプレートをexampleとしました。

```polls/base.html
<!doctype html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>{% block title %}親テンプレートのタイトル{% endblock %}</title>
</head>
<body>
 <div class="row">
    {% block content %}
    {% endblock %}
 </div>
</body>
</html>
```


```polls/example.html
{% extends 'polls/base.html' %}
{% block title %}子テンプレートのタイトル{% endblock %}
{% block content %}
<p>block contentをオーバーライドできます</p>
{% endblock %}
```

* 上記の通り、子テンプレートである`example.html`の{% block content %}ブロックの中身に記入したものが、デフォルト値に置き換えられます。

# 補足①：子テンプレートを`{% block title %}{% endblock %}`とした場合は？

* `polls/example.html`を`{% block title %}{% endblock %}`としても、親テンプレートの`{% block title %}`が反映されるわけではありません。この場合は、`localhost`などのサーバー名がタイトルにやってきますのでご注意。ブロックの中身を消したつもりでも、ブロックのHTMLが残っているとこのような現象が発生してしまいます。

```polls/example.html
{% extends 'polls/base.html' %}
{% block title %}{% endblock %}  # この状態では、タイトルはlocaｌhostなどになります
{% block content %}
<p>block contentをオーバーライドできます</p>
{% endblock %}
```

* 親テンプレートのタイトルにしたい場合は、以下のようにタグを消す必要があります。

```polls/example.html
{% extends 'polls/base.html' %}
 # block titleを消すことで、親テンプレートに記載されたタイトルが子テンプレートに適用されます
{% block content %}
<p>block contentをオーバーライドできます</p>
{% endblock %}
```

# 補足②：`block`のあとって決まっているのか？何でもいいのか？
* 上記の例ではわかりやすいように`{% block title %}`としていますが、blockに続く名前はなんでも大丈夫です。
* 例えば、`{% block titleaaaa %}`としても、子テンプレートでも`{% block titleaaaa %}`と名前を一致させれば問題ありません。ただ、人に読んでもらうことを前提とするならば、ここはわかりやすい名前にするのが良いでしょう。なので、一般的には、タイトルの場合は、`{% block title %}`とすることが多いのかと思います。