OmniAICreator/Qiita-1.07M huggingface dataset:
Windows Copilotが進化していた

船井総研デジタルのよもぎたです。

Preview開始当初は[ダークモードとライトモードの切り替えしか出来なかった](https://cloud-expert.fsdg.co.jp/column/471/)Windows Copilotですが、[Microsoft Copilotがアナウンスされた](https://blogs.microsoft.com/blog/2023/09/21/announcing-microsoft-copilot-your-everyday-ai-companion/)ので改めて試したところ、しっかり進化していたので、出来るようになっていたことをお伝えします。アナウンスのページには Copilot in Windows (in preview) という表記があるので、正式リリース時には名称が変更されるかもしれません。ただ、この記事中ではWindows Copilotの表記で統一させていただきます。

### 試した日と環境とお断り

2023年9月23日に Windows 11 Pro Insider PreviewのBuild 23545.ni_prerelease.230908-1421 で試しました。Preview期間中、正式リリース時には機能が追加・変更されている可能性があります。

# 新しくできるようになったこと

- アプリケーションを起動できるようになった
- Windowsの設定変更ができるようになった

## アプリケーションの起動

まずはメモ帳の実行ファイル名 ``notepad.exe`` を指定してメモ帳を起動させてみます。

![スクリーンショット 2023-09-23 215815.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822136/dd1473d9-a761-f9de-8050-94677b1b8f46.png)

次にアプリケーションの名前でペイントを起動させてみました。

![スクリーンショット 2023-09-23 221243.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822136/75c5beab-b1d9-640b-60af-675cb1b7f625.png)

「Bingを起動して」と指示すると、Edgeを起動してくれるものの、Webサイトへのアクセスまではしてくれませんでした。

![スクリーンショット 2023-09-23 222123.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822136/4c22f1ba-f59a-3153-03cc-edd8a8440555.png)

「スクリーンショットを取りたい」「ビデオ通話をしたい」というプロンプトでそれぞれSnipping Tool、Teamsを起動してくれました。

![スクリーンショット 2023-09-24 223312.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822136/0b310c95-ecb9-f759-1005-0d9c7bf1757c.png)

![スクリーンショット 2023-09-24 223341.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822136/5df62995-3e9f-16f1-df42-8f8d587777b6.png)

「文書を作成したい」「プレゼン資料を作るから準備して」と指示すると、それぞれWordとPowerPointを起動してくれました。

![スクリーンショット 2023-09-24 225039.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822136/95048035-b925-8d0d-0e28-fc0ec4846280.png)

デスクトップにあるテキストファイルを開くように指示してみましたが、できません、と断られました。

![スクリーンショット 2023-09-24 223914.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822136/bcb9ef3b-ac56-d022-9869-9e407556758d.png)

驚いたことに、YouTubeにはダイレクトにアクセスできました。既定のブラウザをEdgeにしていてもChromeで開きました。

![スクリーンショット 2023-09-24 224215.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822136/88d41207-024d-8a69-db74-eb57148470a7.png)

## Windowsの設定

BluetoothのOn/Offができるようになっていました。「オフにして」というプロンプトに対して「オンにします」と返答してきますが、実際にはきちんとOffにしてくれます。

![スクリーンショット 2023-09-23 221956.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822136/9898c62d-b0ad-efbb-c64e-a1b98a9c910d.png)

「集中モードにして」と指示すると「応答不可モード」にしてくれました。

![スクリーンショット 2023-09-24 223627.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822136/976f5bd7-4fe9-62b2-ef27-60b45ffa6169.png)

インストールされているアプリの一覧も出してくれました。

![スクリーンショット 2023-09-24 225315.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822136/75da37d6-c114-158d-2838-0f4ba89c2684.png)

# まとめ

なんだかスクリーンショットをぺたぺた貼っただけに近い記事ですが、いろいろ試してみてワクワクしました。Copilotシリーズの正式リリースもいよいよ近づいてきましたし、楽しみです。

最後までお読みいただきありがとうございました。
Javaで「日時を設定する」の動作を確認してみた

# 概要

Javaで「日時を設定する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/start/calendar/index3.html

# 実装

以下のファイルを作成しました。
```TestCalendar2.java
import java.util.Calendar;

class TestCalendar2{
  public static void main(String args[]){

    Calendar calendar = Calendar.getInstance();

    System.out.println("現在の日時を設定します");
    dispCalendar(calendar);

    System.out.println("-- -- -- -- -- --");

    calendar.set(Calendar.YEAR, 2005);
    System.out.println("年を2005年に設定します");
    dispCalendar(calendar);

    System.out.println("-- -- -- -- -- --");

    calendar.set(2005, 10, 25);
    System.out.println("年月日を2005年11月25日に設定します");
    dispCalendar(calendar);

    System.out.println("-- -- -- -- -- --");

    calendar.set(2005, 10, 25, 14, 18);
    System.out.println("日時を2005年11月25日14時18分に設定します");
    dispCalendar(calendar);
  }

  private static void dispCalendar(Calendar calendar){
    String[] week_name = {"日曜日", "月曜日", "火曜日", 
                          "水曜日", "木曜日", "金曜日", "土曜日"};

    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH) + 1;
    int day = calendar.get(Calendar.DATE);
    int hour = calendar.get(Calendar.HOUR_OF_DAY);
    int minute = calendar.get(Calendar.MINUTE);
    int second = calendar.get(Calendar.SECOND);
    int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;

    System.out.println("設定されている日時は");
    System.out.println(year + "年" + month + "月" + day + "日");
    System.out.println("(" + week_name[week] + ")");
    System.out.println(hour + "時" + minute + "分" + second + "秒");
  }
}
```

以下のコマンドを実行しました。
```
$ javac TestCalendar2.java 
$ java TestCalendar2 
現在の日時を設定します
設定されている日時は
2023年9月25日
(月曜日)
7時0分41秒
-- -- -- -- -- --
年を2005年に設定します
設定されている日時は
2005年9月25日
(日曜日)
7時0分41秒
-- -- -- -- -- --
年月日を2005年11月25日に設定します
設定されている日時は
2005年11月25日
(金曜日)
7時0分41秒
-- -- -- -- -- --
日時を2005年11月25日14時18分に設定します
設定されている日時は
2005年11月25日
(金曜日)
14時18分41秒
```

# まとめ

何かの役に立てばと。
コマンドプロンプトで別のドライブに移動する方法

# はじめに
これは備忘録的な感じです。

# 問題
いつも通り`cd`コマンドで外付けのSSDであるEドライブに移動しようとしたら、
```
C:\Users\username>cd E:\data
C:\Users\username>
```
あれれーー？おっかしいぞーー!?
移動できてないじゃないか！！
エラー文はないし、ファイルエクスプローラーでも認識されてる．．．
どういうことだってばよ？
気になったので、調べてみました。

# 理由
コマンドプロンプトで`cd E:\data`を打つと、**Eドライブでの Current Working Directory (作業ディレクトリ) が切り替わるのたけであって、今いるドライブは切り替わりません。**

MS-DOSの最初のバージョンからずっとこの挙動らしいです。普段、UbuntuやMacOSでしかCUIで作業しないので、知らなかったです。

https://superuser.com/questions/441491/cant-change-current-working-directory-to-external-drive-in-windows

# 方法
別のドライブに移動するには、`cd`コマンドした後にドライブに割り当てられてる`E:`を打ちます。
```
C:\Users\username>cd E:\data
C:\Users\username>E:
E:\data>
```
もしくは、パラメータ`/d`を使います。
```
C:\Users\username>cd /d E:\data
E:\data>
```

# おまけ
コマンドプロンプトで`pwd`コマンドに当たるのは`@cd`らしいです。
```
E:\data>@cd
E:\data

E:\data>@cd C:
C:\Users\username
```

https://karat5i.blogspot.com/2015/02/pwd.html
PHP 8.2のインストール

PHP 8.X系をインストールしたので、手順を備忘録として残しておきます。

## 経緯
AWSを使用したPHPのアプリを何か作りたいと考えていて、Laravelを使うべくインストールしようとしたら、自前のMacにPHPが入っていないことに気付かされる。

## 環境
macOS Monterey version 12.3.1
Homebrew 4.1.2

## 前提
Homebrewのインストールは下記参照。
https://aiacademy.jp/media/?p=2817

Homebrewは入っていたので、Composer入れるべく、OpenSSLのインストール。
``
% brew install openssl
``
次に、以下のコマンドでComposerをインストール…
``
% curl -sS http://getcomposer.org/installer | php
``
しようとしたところ、下記のエラーが出てきた。
```
zsh: command not found: php
curl: (23) Failure writing output to destination
```

「PHPがないの…？」
``
% php -v
``
ないらしい。
```
% php -v
zsh: command not found: php
```
Homebrewのアップグレードをやってみたら何か解決するかもしれないと考え、とりあえずアップグレード。
```
% brew upgrade
==> Downloading https://formulae.brew.sh/api/formula.jws.json
#=#=#                                                                          
==> Upgrading 4 outdated packages:
brotli 1.0.9 -> 1.1.0
grep 3.7 -> 3.11
nodebrew 1.1.0 -> 1.2.0
tfenv 2.2.3 -> 3.0.0
```
解決したかなと、とりあえずネットで探したコマンドでPHPインストール試みる。
```
% brew install php@7.4
Error: php@7.4 has been disabled because it is a versioned formula!
```
7.4は古いバージョンでサポート対象外、というエラーらしい。

## 結局
下記のコマンドで最新のPHPをインストール出来、解決した模様。
```
% brew install php
==> Downloading https://ghcr.io/v2/homebrew/core/php/manifests/8.2.10
```

Composerもバッチリ。
```
% curl -sS http://getcomposer.org/installer | php
All settings correct for using Composer
Downloading...

Composer (version 2.6.3) successfully installed to: /Users/masaki/Desktop/Bifree/ciel-app/02_app/composer.phar
Use it: php composer.phar

% php composer.phar
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
```
このままだと結局使えないので、
```
% composer --version                
zsh: command not found: composer
```
パスを通すこともお忘れなく。

```
% sudo mv composer.phar /usr/local/bin/composer
Password:
% composer --version
Composer version 2.6.3 2023-09-15 09:38:21
```
デザイン関係メモ


# keywords

```
宇宙船
未来
テクノロジー
```

# フリー素材

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/5ac4523f-ae67-5524-4762-4c75f16c80b8.png)

- こういった画像の上に製品を乗せるといい感じになる

# 透明化技術
## want to do
上のような背景に製品を乗せる場合，背景の白色を透明にしたい

https://tech-lagoon.com/imagechef/white-to-transparent.html

## iphone app ?

iphoneのアプリのほうがよい？

## 参考

https://streamrental.com/20190316remove/

canva proに機能があるみたい？

## removebg

めっちゃいい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/e613ec6c-49b8-28e3-b019-fdf48057011e.png)

canvaに送れる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/e7731727-7d0c-2090-641d-9aec1d2c1b0c.png)

# canva 

# 成果物
## 1
![Screenshot from 2023-09-25 05-29-59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/d435ea40-d517-1dd4-982a-c13d8c2872f1.png)

改善点
- 製品自体も一部透けてしまいっている

## 2

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/d27acd49-faf8-dbfb-52a7-60173228f10b.png)

## 3

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/26434409-e905-daac-749c-5a472184ccb5.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/bfabbf53-c100-438f-e337-16caafff6268.png)


この辺の画像いいね．キーワード`テクノロジー`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/61a6a910-5090-9415-a2e8-27765d76f098.png)

キーワード`ロボティクス`も良き

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/6b43bb8d-8e9a-0df8-8b8b-90c4c896bbdc.png)


`人工知能`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/dbc52e07-9526-2065-93e7-707f9775d97f.png)

`pc`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/10284bdb-9f21-6fc6-b814-77d77c211d9d.png)

# freepik


https://jp.freepik.com/

`AI画像`

![9067755.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/10fbd670-e30c-da82-7779-658aaab6b8a1.jpeg)

# iStock

https://www.istockphoto.com/jp/search/search-by-asset?affiliateredirect=true&assetid=1481634326&assettype=image&utm_campaign=SRP_image_sponsored&utm_content=https%3A%2F%2Fpixabay.com%2Fimages%2Fsearch%2Frobot%2520arm%2F&utm_medium=affiliate&utm_source=pixabay&utm_term=robot+arm

いい感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/693cac02-fb65-06c6-e885-91cff36ae385.png)
Autokey フレーズとタスクのツール


+ Linux Mint21.1 
+ Python3 

すべてが書かれいます。 

https://autokey.github.io/

https://github.com/autokey/autokey

## AutoKeyについて

+ Wikipedia 翻訳
```
AutoKey を使用すると、ユーザーはホットキーとトリガー フレーズを定義して、
事前定義されたテキストに展開することができ、タイプミスや一般的なスペルミスの修正やテキストの定型セクションの挿入など、頻繁または反復的なタスクを自動化できます。
```


## AutoKeyの2つの機能を持ちます。
:::note alert
変更したとき、Saveを忘れないこと。
:::


### テキスト置換

テキストエディタなどでユーザが、あらかじめ決めてある単語を入力します。
エンターキーを押下した時、登録していたテキスト文に置換してくれます。
![Auto01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23768/18eb45d4-0ec4-d190-df18-b27b0ebe39de.png)
### プログラミング

通常はAutokeyメニューから起動します。

+ Windowの指定は次を指定します。
```
window.activate('Thunar.Thunar', switchDesktop=True, matchClass=True)
```
サンプル Display Window infoを実行する。Classが実行しているWindowになります。  
```
Active window information:
Title: 'Pictures'
Class: 'Thunar.Thunar'
```

+ 回数指定
```
prompt="Please..."
retCode, userInput = dialog.input_dialog(title="Input required", message=prompt, default="example")
```

+ マウスの座標

ターミナルからxdotoolを実行します。
```
xdotool getmouselocation
```
## サンプルコード

### ファイルマネージャーの複数のタブの操作

```
# Enter script code
# Active window information:
# Title: 'Downloads'
# Class: 'Thunar.Thunar'
#

window.activate('Thunar.Thunar', switchDesktop=True, matchClass=True)

keyboard.send_keys("<ctrl>+l")
keyboard.send_keys("/home/bomiura/Downloads/")
keyboard.send_keys("<enter>")

keyboard.send_keys("<ctrl>+t")
keyboard.send_keys("<ctrl>+t")
keyboard.send_keys("<ctrl>+t")

# Dvice
# mouse buttons: left=1, middle=2, right=3
mouse.click_absolute(60, 450, 1)
time.sleep(1.0)

#
# x:54 y:376 screen:0 window:21070347 
mouse.click_absolute(73, 264, 1)
```
### Firework 複数のダウンロード 
```
# Enter script code

# Enter script code
#Active window information:
#Title: 'Search | Hitomi.la — Mozilla Firefox'
#Class: 'Navigator.firefox'

window.activate('Navigator.firefox', switchDesktop=True, matchClass=True)

prompt="Please..."
# Ask for input, offer a default example, and check the exit code of the command:
retCode, userInput = dialog.input_dialog(title="Input required", message=prompt, default="example")

a = int(userInput)

for i in range(a):
    keyboard.send_keys("<ctrl>+<page_down>")
    keyboard.send_keys("<ctrl>+f")
    time.sleep(1.0)
    keyboard.send_keys("Download")
    keyboard.send_keys("<enter>")
    time.sleep(1.0)
    keyboard.send_keys("<escape>")
    keyboard.send_keys("<enter>")
```
terraformとGithub actionsでAWS構築　〜序 terraformバージョン設定〜

普段、Jenkinsを使いDevOpsとして仕事をしているのだが、Github actionsも使えるようになりたいと思い、練習を試みている。
気付いたことなどをメモにしていきたいと思っているが、忘れてしまう恐れもある。
漏れがあったら、ごめんなさい…

コードはこちらで管理しています。
https://github.com/bifree-llc/ciel-app

今回はterraformのインストール、バージョン設定について記事にしていきます。備忘録、みたいな意味合い強いのでGithub actionsに触れてねえじゃねーかというクレームは追々…。

## 環境
macOS Monterey version 12.3.1
Homebrew 4.1.2

## tfenv設定　（terraform初見さんはこちらから）
tfenvはTerraformのバージョンマネージャーで、簡単にバージョンの切り替えが可能となる。

<details><summary>Homebrewでtfenvをインストールします。</summary>
※Homebrewのインストール方法は、こちらを参考に。
https://aiacademy.jp/media/?p=2817</details>

``
% brew install tfenv
``
バージョン確認してみましょう。
``
% tfenv --version
``

## Terraformバージョンインストール
インストール可能なバージョン一覧を確認。
``
% tfenv list-remote
``
最新のバージョンをインストールします。（2023.9.25現在）
``
% tfenv install 1.5.7
``
以前、terraformを練習していた時に設定していたバージョン 0.14.6 のままだったので、インストールした最新のバージョンに切り替える。
```
% cd 対象のリポジトリ
% tfenv use 1.5.7
Switching default version to v1.5.7
Switching completed
```
.terraform-versionを作成しておく。
```
% vim .terraform-version
1.5.7 
```
下記のコマンドを実行し、terraformのバージョンをしっかり設定。
``
% terraform init -upgrade
``
バージョン確認も忘れずに。
``
% terraform --version
``
2023/9/25主にITとかセキュリティの記事

Facebookアカウントをサイバー犯罪から守る9つの方法(9/23)
https://news.mynavi.jp/techplus/article/20230923-2774830/

偽の解約通告メール、真偽の区別が付かないので厄介過ぎる――ETC利用照会サービスの偽物に注意(9/23)
https://ascii.jp/elem/000/004/158/4158472/?rss

壁越しの文字を「Wi-Fi」で画像化できる技術を発表　カリフォルニア大学(9/23)
https://atmarkit.itmedia.co.jp/ait/articles/2309/23/news043.html

【詐欺】「平素よりAmazonプライムをご利用いただき…」→会費値上げのタイミングで「詐欺メール」が!? これはだまされる！ 注意すべき最新詐欺メール5選(9/23)
https://nordot.app/1078192399030894750

大分県が「生成ＡＩ」を情報収集や文書要約向けに利用開始…「あくまでも業務の補助」(9/23)
https://www.yomiuri.co.jp/local/kyushu/news/20230922-OYTNT50131/

生成ＡＩ県が利用開始　ガイドライン策定、補助的に活用(9/23)
https://www.yomiuri.co.jp/local/oita/news/20230922-OYTNT50100/

生成系AIが小売業にもたらす好影響(9/22)
https://aws.amazon.com/jp/blogs/news/the-positive-impact-generative-ai-could-have-for-retail/

ロシア当局、ハッカー使い戦争犯罪の証拠模索＝ウクライナ高官(9/23)
https://jp.reuters.com/world/ukraine/L6G4A7VVKFO4HGC3V3ZI2KR2ZE-2023-09-22/

中学生 同級生端末に不正アクセス　津山市教委発表、外部流出なし(9/22)
https://www.sanyonews.jp/article/1455335

クラス３０人のＩＤ・パスワード一覧表を中学生が盗み撮り…８人のアカウントで不正アクセス(9/23)
https://www.yomiuri.co.jp/national/20230923-OYT1T50017/

英副首相 AIの安全な活用へ各国連携の重要性を強調 国連総会(9/23)
https://www3.nhk.or.jp/news/html/20230923/k10014204491000.html

ウクライナのサイバー防御から学ぶ　有事への備え　松原実穂子氏の講演・詳報(9/23)
https://www.sankei.com/article/20230923-IY3WTC4C6RKQHPLHNZBVVXR2VA/

マイナンバーカード「持ち歩かない」人の割合は?(9/23)
https://news.mynavi.jp/article/20230923-2776797/

生理アプリへの個人情報登録は安全？　半数以上のユーザーが疑問視する調査結果(9/23)
https://nordot.app/1078249468294300450

鳥羽商船高専、物流のサイバー攻撃防げ
25年度、ITに特化 コース新設(9/23)
https://www.nikkei.com/article/DGKKZO74677910S3A920C2L91000/
Next.jsの本番環境をdockerで構築する方法

# 経緯
Next.jsで作成した、アプリケーションの本番環境をdockerで構築しようとしたときに、詰まって試行錯誤した結果、npmがうまく実行できたので備忘録として記します。

# dockerfile
```dockerfile:dockerfile
# syntax=docker/dockerfile:1

ARG NODE_VERSION=18.16.0

################################################################################
# 全てのステージのベースイメージとしてnodeイメージを使用する。
FROM node:${NODE_VERSION}-alpine as base

# すべてのビルドステージの作業ディレクトリを設定。
WORKDIR /usr/src/app

################################################################################
# 本番環境の依存関係をインストールするステージを作成する。
FROM base as deps

# Dockerのキャッシュ機能を最大限に活用するため、依存関係を別のステップでダウンロードする。
# /root/.yarn へのキャッシュマウントを利用して、後続のビルドのスピードアップを図る。
# package.jsonとyarn.lockのバインドマウントを利用して、これらをこのレイヤにコピーする必要がないようにする。
RUN --mount=type=bind,source=package.json,target=package.json \
    --mount=type=bind,source=package-lock.json,target=package-lock.json \
    --mount=type=cache,target=/root/.npm \
    npm ci --production

################################################################################
# アプリケーションをビルドするためのステージを作成する。
FROM deps as build

# ソースファイルの残りをイメージにコピー。
COPY . .

# ビルドスクリプトを実行。
RUN npm run build

################################################################################
# 最小限のランタイム依存関係でアプリケーションを実行する新しいステージを作成する。
# 必要なファイルはビルドステージからコピーされる。
FROM base as final

# 既定で本番のnode環境を使用する。
ENV NODE_ENV production

# ルート以外のユーザーとしてアプリケーションを実行する。
USER node

# パッケージマネージャのコマンドが使用できるようにpackage.jsonをコピー。
COPY package.json .

# depsステージからの本番依存関係と、buildステージからビルドされたアプリケーションをイメージにコピーする。
COPY --from=deps /usr/src/app/node_modules ./node_modules
COPY --from=build /usr/src/app/.next ./.next
#imagesもコピー
COPY ./public ./public

# アプリケーションを実行。
CMD npm start
```
# docker-compose.yml
```yaml:docker-compose.yml
version: '3'

services:
  next-app:
    container_name: next-app
    image: next-app
    build:
      context: .
      dockerfile: dockerfile
      args:
        ENV_VARIABLE: ${ENV_VARIABLE}
        NEXT_PUBLIC_ENV_VARIABLE: ${NEXT_PUBLIC_ENV_VARIABLE}
    restart: always
    ports:
      - 6000:6000
```
# コンテナの起動
```
docker-compose build
docker-compose up -d
```
# 参考資料
https://qiita.com/piny940/items/e30f219f98bb3b87af18
49利用者確認と認証の方法

### 利用者IDとパスワードを使ったパスワード認証
コンピューター利用開始時、本人である証拠を示してもらう。（ログイン時に本人認証）
最も一般的　パスワード認証
利用者ID　システムの利用者を一意に識別するための情報
パスワード　利用者本人を確認するための情報。推測しにくい。
### 一度だけしか使えないパスワードを使用する
その本人のみが知るIDとパスワードを用いるパスワード認証は、容易に本人認証を行うことができるが、リモートアクセスの場合、通信途中が盗み見されてしまう可能性がある。
　その対策として、使い捨てパスワード、ワンタイムパスワード認証といい。
#### トークン（パスワード生成器）方式
　　一度しか使えない、時間ごと（一分とか）に異なるパスワードを生成するパスワード生成器（トークン）を使って時刻同期方式（タイムシンクロナス方式）。
　利用者にIDが登録されたトークン、パスワード生成器を配布する。　
　利用者IDとパスワード生成器に表示された使い捨てパスワードを認証サーバーへ送信する。
　認証サーバでは、アクセスしてきた時刻を元に、利用者のパスワード生成器と同じルールでパスワードを生成し、送られてきたパスワードと照合することで、本人認証ができる。（steamとか）
#### チャレンジレスポンス方式
　チャレンジレスポンス方式では、利用者が入力した自身のパスワードと、認証サーバーから送られたチャレンジと利用者側で演算し、その結果（レスポンス）を認証用データに用いる。
#### 個人所持品をもとに本人認証する物理認証
ICカード（SUICA）物理認証
#### 生体認証
虹彩　　　
指紋
指の静脈
声紋
網膜認証
FRR（本人拒否率）FAR（他人受入率）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293109/844782d3-1232-a856-b228-49962fc9c97c.png)

練習問題
ワンタイムパスワード認証は、一度しか使えないパスワードを使用することで、パスワード認証の弱点を克服した認証方式である。
ワンタイムパスワード認証を実現する方法の一つで、時間ごとに異なるパスワードを生成するパスワード生成器を使って行う方式をトークン方式、あるいはタイムシンクロナス方式。
チャレンジレスポンス方式では、利用者が入力した自身のパスワードと、認証サーバーから送られたチャレンジと利用者側で演算し、その結果（レスポンス）を認証用データに用いる。
ICカードなど、個人所持品をもとに本人認証を行う方法を物理認証という。
指紋、手のひらや先の静脈などの特徴で認証する方法は生体認証、あるいは　バイオメトリクス認証。
スプレッドシート内でBig Queryで抽出したデータをGASを使って、他のページに貼り付ける


<br>
<br>
こちらのGASは、スプレッドシート上でBig Queryのデータを抽出後に、別シートにデータをコピー、貼り付けする時に用いていました。

スプレッドシートでは、Big Queryに接続して抽出したデータを表示することができますが
例えば直近のデータだけを抽出して、そのデータを別のシートに貼り付けデータをためることができれば、クエリ費を節約することに繋がります。

GASの利用方法については、こちらの記事では割愛いたします。
参考に、公式ページだけ貼っておきます。
https://developers.google.com/apps-script?hl=ja

<br>
<br>
<br>
以下構文です。

<br>

```
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(”コピー先のシート名”）：

var lastRow1 = sheet.getRange (1, 1) .getNextDataCell(SpreadsheetApp.Direction.DOWN) .getRow();
Logger. log (lastRow1);


function copyDataToDauSheet () {
    //コピー元のシート名を入力する
    let sheet_copyFrom = SpreadsheetApp. getActiveSpreadsheet().getSheetByName(”コピー元のシート名”);
    //コピー先のシート名を入力する
    let sheet_copyTo = SpreadsheetApp.getActiveSpreadsheet() ・getSheetByName(”コピー先のシート名”）;
    let lastRow = sheet_copyTo.getLastRow();
    //コピー元のコピーするセルを指定する
    let copyValue = sheet_copyFrom. getRange (1, 1, lastRow, 4) . getValues ()
    //コピー先の貼り付けするセルを指定する
    sheet_copyTo.getRange (lastRow1+1, 1, lastRow, 4). setValues (copyValue);
    }

```


<br>

注意点として、
コピーするセルと貼り付けするセルの範囲指定、getRangeはデータの行列数によって変わります。
行列数に合わせて、指定する数値を変えてください。


また、
空欄箇所にデータを貼りつけ続けるため、lastRow1 で特定列の最終行を取得しています。
つまり、1列目に格納されているデータの空欄箇所は何行目かを算出し、その行の数値をgetRangeで指定しています。

<br>
<br>
<br>
自動でデータ抽出する流れとして、

①スプレッドシート上で、Big Queryのデータを抽出
↓
②クエリの更新スケジュールを設定
↓
③抽出されたデータを拡張機能 Apps Scriptで別のシートに貼り付ける
↓
④GASの自動更新を設定する

上記4点になるのですが、
今回のGASを利用するタイミングは、③です。




## まとめ

今回は、データのコピー、貼り付けのGASを記載させて頂きました。
スプレッドシート上でどうやってデータ抽出、コピー、貼り付けを自動化しているかの詳細に関しては、また別の機会でご説明させて頂ければと思います。

最後までお読み頂きありがとうございました。
【Photoshop】画像の背景を透明に切り抜く方法

今回はPhotoshopで切り抜きたい画像の背景を透明にする手順を説明していきます。

![スクリーンショット-2023-09-25-1.42.45.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/17b52e4b-4053-73f5-4d3b-1daed5c8c49b.jpeg)


# 目次
* [画像を用意する](#画像を用意する)
* [「背景」→「レイヤー」に変更](#背景レイヤーに変更)
* [クイック選択](#クイック選択)
* [オブジェクトを選択](#オブジェクトを選択)
* [選択範囲を反転](#選択範囲を反転)
* [選択範囲を反転されたのを確認](#選択範囲を反転されたのを確認)
* [選択範囲を削除](#選択範囲を削除)
* [オブジェクトの背景が削除される](#オブジェクトの背景が削除される)
* [最後に](#最後に)

### 画像を用意する
![スクリーンショット-2023-09-25-1.32.58.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/924df516-1d79-9a3a-21b2-43abe8766df5.jpeg)
背景を切り抜きたい画像を用意します。

### 「背景」→「レイヤー」に変更
![スクリーンショット-2023-09-25-1.33.08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/e76ffee6-73fb-f27e-8fa6-b078767e1369.jpeg)
「背景」になっている時は右クリックし、「背景からレイヤーへ」を選択して「レイヤー」に変更してください。

### クイック選択
![スクリーンショット-2023-09-25-1.33.19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/1ac37cc2-c34e-6c65-8087-7702402ec097.jpeg)
左のメニューから「クイック選択ツール」を選択してください。

### オブジェクトを選択
![スクリーンショット-2023-09-25-1.36.43.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/0018f649-61c6-1918-2c28-3b0b278eb291.jpeg)
切り抜きたいオブジェクトを選択してください。

![スクリーンショット 2023-09-25 1.51.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/89c33b74-ee29-6f3b-095b-f53b6d2ba6fa.png)
※細かい選択の微調整は「生成塗りつぶし」の隣の「選択範囲修正」で微調整可能です。

### 選択範囲を反転
![スクリーンショット-2023-09-25-1.33.38.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/eeabb2d9-8571-5072-ae0d-737c61cd641e.jpeg)
メニューから「選択範囲」→「選択範囲を反転」を選択してください。

### 選択範囲を反転されたのを確認
![スクリーンショット-2023-09-25-1.37.01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/62fb14b5-5a4e-abc7-30e4-fcb643dcd84a.jpeg)
選択したものが反転されました。

### 選択範囲を削除
![スクリーンショット-2023-09-25-1.37.14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/2211b59e-db88-dd93-b284-5ff9df0f641f.jpeg)
メニューから「編集」→「削除」を選択してください。

### オブジェクトの背景が削除される
![スクリーンショット-2023-09-25-1.37.25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/31ad4403-6b36-5f6d-e72c-a3d19beb35e8.jpeg)
これでオブジェクトの背景が削除され透明になりました。

## 最後に
以上となります！
手順さえ覚えてしまえば簡単に背景を透明にすることができます。
是非試してみてください！
EC-CUBE4のメモ




## logでオブジェクトをデバッグしたい

### 通常のログ

```
log_info('xxxxxxx');
```

### オブジェクトのデバッグ

```
$myCar = new stdClass;
$myCar->engine = 'Engine1';
log_info("xxxxx", (array)$myCar);
```

### その他の情報は他のページを参照

ログの出力先やlogの種類など。

https://qiita.com/okazy/items/aab56f30812e2d92fd9f
量子機械学習 PennyLane の量子回路の表示方法

# はじめに

量子機械学習 [PennyLane](https://pennylane.ai) を使う上で、量子回路を図示するのは最初に一歩となりますので、その方法について紹介します。

このページの例は google colab 上で再現できます。

https://colab.research.google.com/drive/1WBmO-zxVDblp99jWlFUGow_Nsk_m1tVP?usp=sharing

## ご本家の例

qml.drawer.use_style という関数が定義されていて、この使い方のサンプルの下記のページに書かれています。

https://docs.pennylane.ai/en/stable/code/api/pennylane.drawer.use_style.html

``` python
import pennylane as qml
qml.drawer.use_style('black_white')

@qml.qnode(qml.device('lightning.qubit', wires=(0,1,2,3)))
def circuit(x, z):
    qml.QFT(wires=(0,1,2,3))
    qml.Toffoli(wires=(0,1,2))
    qml.CSWAP(wires=(0,2,3))
    qml.RX(x, wires=0)
    qml.CRZ(z, wires=(3,0))
    return qml.expval(qml.PauliZ(0) @ qml.PauliZ(2))

fig, ax = qml.draw_mpl(circuit)(1.2345,1.2345)
fig.show()
```

基本的にはこれを使えばOKです。次のような図が生成されます。

![qiita_qml_drawer_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179652/3ac4a803-7a5d-4626-0d7c-7d736b55e05c.png)


## スタイルと見た目の関係

いくつかのスタイルが用意されているので、その一覧をここでは紹介します。

用意されているスタイルは、

``` python:
# 使用可能なスタイルを確認する
qml.drawer.available_styles()
('black_white',
 'black_white_dark',
 'sketch',
 'pennylane',
 'sketch_dark',
 'solarized_light',
 'solarized_dark',
 'default')
```

の８つあります(2023.9.25時点)。

これらを、

``` python:
import pennylane as qml

for style in qml.drawer.available_styles():
  qml.drawer.use_style(style)

  @qml.qnode(qml.device('lightning.qubit', wires=(0,1,2,3)))
  def circuit(x, z):
      qml.QFT(wires=(0,1,2,3))
      qml.Toffoli(wires=(0,1,2))
      qml.CSWAP(wires=(0,2,3))
      qml.RX(x, wires=0)
      qml.CRZ(z, wires=(3,0))
      return qml.expval(qml.PauliZ(0) @ qml.PauliZ(2))

  fig, ax = qml.draw_mpl(circuit)(1.2345,1.2345)
  ax.set_title(style)
  fig.savefig(style+".png")
  fig.show()
```

を実行して、図を生成します。

結果を整理すると、下記のようなスタイルと図の関係になりますので、好きなデザインでプロットしましょう。

![qiita_qml_drawer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179652/41ab4606-6e13-69ec-f5ac-6f65df1802dd.png)
Excelでテストケース(マトリクス)作成するときのツール

,を列区切りとして表現。一部では、_を行区切りとして表現

ケース分解を作る

例
1,null
2,フラグオフ
3,フラグオン

選択肢の数が基数となる。

上記状態が複数項目にあるとき、
ケタ数列を作る(4項目なら、0,1,2,3)
ケース番号を、0～基数^項目数で振って行にする。
ここでは、3選択肢が4項目なので、81個振る。(0_1_2_3_..._80)

↓のような表になればおｋ

```
基数,0,1,2,3
0,,,,
1,,,,
2,,,,
```

データ値部分に以下の通り数式を組む

```vb:c
=mod(int(ケース番号/power(基数,ケタ数)),基数)

'番号0のところで、
=mod(int($A2/power($A$1,B$1)),$A$1)
```

基数は絶対参照(`$A$1`)かマジックnum、ケース番号は列固定(`$A2`)、桁数は行固定(`B$1`)
で組めば複製が簡単

番号になった部分をﾆﾎﾝｺﾞにするなら、`index`使えばよい。(`index(選択肢,式結果+1)`)


もっと細かく説明したいけどめんどくさいので一例を貼っとく（Googleスプシだけど数式とか同じ）

https://docs.google.com/spreadsheets/d/1Ill3z0ccMMfDIExDSsMAv60GvU5W_I0KspH4xPwIQ0Q/edit?usp=sharing
Pyxelでの日本語フォント表示を簡単に！ - PyxelUniversalFontの紹介

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700066/2986a7e7-d45e-31ea-cf79-6b2814eb1ec9.png)

pyxelでゲーム開発やアプリ制作を楽しんでいる皆さん、テキストの表示に日本語フォントを使いたいと思ったことはありませんか？今回、そのための便利なパッケージを作成しましたので、紹介いたします！

## PyxelUniversalFontとは？

[`PyxelUniversalFont`](https://github.com/n-koba0427/PyxelUniversalFont)は、[pyxel](https://github.com/kitao/pyxel)ライブラリのフォント機能を拡張するためのツールです。このパッケージを利用することで、簡単にpyxelでの日本語フォントの表示が可能になります。

## 主な機能

1. **追加フォントのインストール**  
   pyxelのデフォルトのフォントだけでなく、様々な日本語フォントを追加して使用することができます。
   
2. **カスタムフォントのサポート**  
   お気に入りのフォントを自分で追加することが可能です。
   
3. **高品質な文字表示**  
   ゲームやアプリケーションの文字を、綺麗に、そして多様に表示することができます。

## 標準でサポートしているフォント

![スクリーンショット 2023-09-25 17.23.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700066/b9ab4e2b-76ca-faa3-8276-48510a043adc.png)

1. [IPAexフォント](https://moji.or.jp/ipafont/ipafontdownload/)
    - IPA ゴシック
    - IPA Pゴシック
    - IPA 明朝
    - IPA P明朝

2. [美咲フォント](https://littlelimit.net/misaki.htm)
    - 美咲ゴシック
    - 美咲ゴシック第2
    - 美咲明朝

任意のフォントを追加することも可能です!!!

[怨霊フォント](http://www.ankokukoubou.com/font/onryou.htm)で遊んでみた⇩
![onryo_font](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700066/3bde160d-a3d8-5d47-48ab-5769f649c0af.png)

## インストール

PyxelUniversalFontはpipを利用して簡単にインストールできます。

```bash
pip install pyxel-universal-font
```

その後、pyxelのプロジェクト内で以下のようにインポートするだけ！
```python
import PyxelUniversalFont
```

## 体験してみよう！

まずはプログラム不要！

インストールをした後、```puf sample```というコマンドでサンプルアプリケーションを起動して、動作を確認することができます。

![スクリーンショット 2023-09-25 17.23.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700066/914c6e62-f5e1-8e19-162a-41ec2e6dfd99.png)

こんな感じ？


## 使用方法

上記のインストール後、以下のサンプルコードを参考にしてください

```python
import pyxel
import PyxelUniversalFont as puf

pyxel.init(500, 50)

# フォントを指定
writer = puf.Writer("misaki_gothic.ttf")

pyxel.cls(7)

# draw(x座標, y座標, テキスト, フォントサイズ, 文字の色(16:モザイク))
# 背景色はデフォルト値(-1:透明)
writer.draw(25, 4, "PyselUniversalFont", 50, 16)

pyxel.show()
```

![スクリーンショット 2023-09-25 17.47.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700066/6f4ab8d8-e592-d26a-7091-8a3100853cf5.png)

うまくいけばこのように表示されるはずです！


## まとめ

PyxelUniversalFontを利用すれば、pyxelでの日本語フォント表示が簡単にできるようになります。ゲーム開発をもっと楽しんでみてください！


## コード
- [github](https://github.com/n-koba0427/PyxelUniversalFont)
- [PyPI](https://pypi.org/project/pyxel-universal-font/)
Pythonでファイル名を変更する方法をコードを用いて解説

Pythonでファイル名を変更するには、osモジュールまたはshutilモジュールを使用できます。以下に、これらのモジュールを使ったファイル名の変更方法をコード例を交えて説明します。

## 1. osモジュールを使用したファイル名の変更

osモジュールのrename()関数を使用してファイル名を変更する方法です。

```python
import os

# 変更前のファイル名と変更後のファイル名を指定
old_filename = "old_file.txt"
new_filename = "new_file.txt"

# ファイル名を変更
os.rename(old_filename, new_filename)
```
このコードでは、os.rename()関数を使用して、old_file.txtというファイル名をnew_file.txtに変更しています。

## 2. shutilモジュールを使用したファイル名の変更

shutilモジュールのmove()関数を使用してファイル名を変更する方法です。

```python
import shutil

# 変更前のファイル名と変更後のファイル名を指定
old_filename = "old_file.txt"
new_filename = "new_file.txt"

# ファイル名を変更
shutil.move(old_filename, new_filename)
```
shutil.move()関数はos.rename()関数と同様にファイル名を変更しますが、ファイルが異なるディレクトリにある場合にも使用できます。

これらのコード例を使って、ファイル名を変更することができます。変更前のファイル名と変更後のファイル名を指定し、選択した方法でファイル名を変更します。ただし、ファイルが存在しない場合や、アクセス権がない場合にはエラーが発生する可能性があるため、エラーハンドリングを追加することがおすすめです。

## Pythonのお役立ち情報

https://wagtechblog.com/programing/python-school

https://wagtechblog.com/programing/ai-develop-school
GA4で使った SQL集 2

GA4で使用したSQLの備忘録です。
GA4のBigQueryエクスポート機能を使ってデータを抽出しています。



<br>

### １：指定したURLを条件にPVを発生させたユニークなユーザー数

特定のページを表示したユニークユーザーを算出したい時に、利用していたクエリ文です。
クリック数と組み合わせ、CTR算出に用いることが多かったです。
URLの抽出は正規表現で。
イベント名を変更すれば、別イベントでの絞り込みができるかと思います。
期間指定に特にこだわりはありません。


<br>


```
WITH t1 as 
SELECT 
    event_date 
    ,count (distinct user) as top_user 
FROM 
    (SELECT 
        event_date user_pseudo_id as user 
        ,event_name
        ,e.key as page_location 
        ,e.value.string_value as url 
     FROM pmsg-portal-prd.analytics_********.events_** 
    ,unnest (event_params) as e 
     WHERE 
        key = "page_location" and REGEXP_CONTAINS(value.string_value,r"^https:.*") and _TABLE_SUFFIX BETWEEN "20230801" AND "20230808" and event_name = "page_view"
     GROUP BY event_date, user_pseudo_id, event_name,page_location, url) 
GROUP BY 
    event_date, user 
ORDER BY event_date ) 


SELECT 
    t1.event_date
    , sum(top_user) as user 
FROM 
    t1 
GROUP BY 
    t1.event_date, top_user 
ORDER BY 
    t1.event_date

```




　　
### ２：アクティブユーザー数

GA4のアクティブユーザーは、エンゲージメントが発生したかが定義となります。
Big Queryではその判断は、
・session_engaged_flagが１
・first_visit　がイベントが発生しているか
・engagement_time_msecが0以上か

上記3つに該当すればアクティブユーザーと判断されるため、
CASE文の条件分岐で抽出しています。
期間指定に特にこだわりはありません。
　
　　



```
WITH prep AS (
SELECT
    event_date
    ,user_pseudo_id
    ,event_name
    , (SELECT key FROM UNNEST(event_params) WHERE key = 'page_location') AS ur1
    , (SELECT value.string_value FROM UNNEST (event_params) WHERE key = 'page_location') AS page_location
    , (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'session_engaged') AS session_engaged_flag
    ,(SELECT value.int_value FROM UNNEST (event_params) WHERE key = 'engagement_time_msec') AS engagement_time_msec
FROM
    'pmsg-portal-prd.analytics_***********.events_*'
WHERE
_TABLE_SUFFIX = FORMAT_DATE ("*Y%m%d", DATE_SUB(CURRENT_DATE ('Asia/Tokyo'), INTERVAL 2 DAY))
GROUP BY 
    event_date, user_pseudo_id, event_name, page_location, url, session_engaged_flag, engagement_time_msec
)


SELECT
    event_date,
    COUNT (DISTINCT CASE WHEN session_engaged_flag = '1' THEN user_pseudo_id
    WHEN event_name = 'first_visit THEN user_pseudo_id
    WHEN engagement_time_msec > 0 THEN user_pseudo_id END) AS active_user_count
FROM 
    prep
GROUP BY
    event_date
ORDER BY
    event_date


```

<br>
<br>

### ３：参照元、メディアごとのセッション数

セッションの参照元/メディアを抽出するクエリ文です。
定番のクエリ文ですが、イベント名を変更したり、UIDのカラムを加えたりして、色んな条件での流入先を把握する際に流用していました。

<br>




```
with m1 as 
(
select 
    event_date
    ,concat (traffic_source. source," / ",traffic_source.medium) as source_medium
    ,count (event_name) as sessions
from pmsg-portal-prd.analytics_********.events_*
where
    _TABLE_SUFFIX = FORMAT_DATE ("*Y%m%d", DATE_SUB (CURRENT _DATE (Asia/Tokyo"),INTERVAL 2 DAY)) and event_name = 'session_start'
group by
    event_date, source_medium 
order by
    event_date desc, sessions desc
)
```


## まとめ

今回は、3つのSQLの構文を書かさせて頂きました。
基本的なクエリかも知れませんが、多用、流用することが多かったため備忘録として記載した次第です。

ご参考になれば幸いです。
デザインパターン[MVVMの章]



1. 導入
MVVMの概要
MVVM（Model-View-ViewModel）は、ユーザーインターフェースの設計パターンの一つで、特にXAMLベースのアプリケーション（WPF、Xamarin、UWPなど）で人気があります。
Model, View, ViewModelの三つのコンポーネントで構成されます。

MVVMの利点
MVVMの主な利点は、ビジネスロジックの分離、コードの再利用、テストの容易性です。

2. Model（モデル）の役割
データ管理とビジネスロジック
モデルはアプリケーションのビジネスロジックやデータを管理します。

モデルの例と実装
``` python
from dataclasses import dataclass

@dataclass
class User:
    id: int
    name: str
    email: str

```
3. View（ビュー）の役割
ユーザーインターフェースの概要
ビューは、ユーザーに表示されるUI部分を担当します。

ビューの例と実装
```xml
<StackPanel>
    <TextBlock Text="{Binding Name}" />
    <TextBlock Text="{Binding Email}" />
</StackPanel>
```
4. ViewModel（ビューモデル）の役割
状態管理とビューロジック
ビューモデルはビューに表示するデータや状態を管理し、ビューロジックを担当します。

ビューモデルの例と実装
```python
class UserViewModel:
    def __init__(self, user):
        self._user = user
        self._view = None 
        
    @property
    def name(self):
        return self._user.name
    
    @name.setter
    def name(self, value):
        if self._user.name != value:
            self._user.name = value
            self._update_view('name')
    
    @property
    def email(self):
        return self._user.email
    
    @email.setter
    def email(self, value):
        if self._user.email != value:
            self._user.email = value
            self._update_view('email')

    def attach_view(self, view):
        self._view = view
        self._update_view('name')
        self._update_view('email')

    def _update_view(self, prop_name):
        if self._view:
            if prop_name == 'name':
                self._view.name_label['text'] = "Name: " + self.name
            elif prop_name == 'email':
                self._view.email_label['text'] = "Email: " + self.email

```
5. データバインディングの重要性
データバインディングの概要
MVVMにおいて、データバインディングはビューとビューモデルの間のデータ受け渡しを管理し、同期させます。

バインディングの例と実装
```xml
<StackPanel DataContext="{Binding UserViewModel}">
    <TextBox Text="{Binding Name, Mode=TwoWay}" />
    <TextBox Text="{Binding Email, Mode=TwoWay}" />
</StackPanel>
```
6. まとめ
MVVMパターンは、コードの整理とテストの容易性を提供し、ビジネスロジックとUIの分離を実現します。データバインディングの使用により、ビューとビューモデル間の同期が容易になります。
Pythonのsleep関数の使い方をコードを用いて解説

Pythonの time モジュールには、スリープ（一時停止）を実現するための sleep() 関数が提供されています。この関数は、指定した秒数だけプログラムの実行を一時停止させます。以下に、sleep() 関数の使い方をコード例を交えて説明します。

## 1. sleep() 関数の基本的な使い方

sleep() 関数を使用して、プログラムの実行を指定した秒数だけ停止させるコード例です。

```python
import time

print("処理を開始します。")
time.sleep(3)  # 3秒間スリープ
print("3秒後に処理が再開されました。")
```
このコードでは、time.sleep(3) を使用して、プログラムの実行を3秒間停止させています。指定した秒数だけスリープし、その後にメッセージが表示されます。

## 2. 小数点以下の秒数を指定

sleep() 関数に小数点以下の秒数を指定するコード例です。

```python
import time

print("処理を開始します。")
time.sleep(1.5)  # 1.5秒間スリープ
print("1.5秒後に処理が再開されました。")
```
このコードでは、time.sleep(1.5) を使用して、1.5秒間スリープします。

sleep() 関数は、時間の待機や一時停止が必要な場面で便利です。例えば、ループの間隔を調整したり、リソースの競合を回避するために使用することができます。ただし、長時間のスリープはプログラムのパフォーマンスに影響を与える可能性があるため、慎重に使用する必要があります。

## Pythonのお役立ち情報

https://wagtechblog.com/programing/python-school

https://wagtechblog.com/programing/ai-develop-school
【積読】コードの「割れた窓」

今回は書籍「プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則」の7.3章「割れた窓の法則」について整理します。

## 悪いコードは「蟻の一穴」
ビルのような建物に、長期間修理されることのない割れた窓が1枚でもあると、ビルの住人に「投げやりな感覚」が植え付けられていきます。つまり、ビルの状態を気にもかけないようになっていく。

すると、次の窓が割れ、さらにゴミがばら撒かれ、散らかるようになる。落書きも増えていく。**たった一枚の割れた窓とはいえ、それを放置すると、建物全体に対する深刻な破損が起こり始める。**

ソフトウェアでも同じ現象が発生する。
・悪い設計
・間違った意思決定
・悪いコード
どんなに小さいものでも、ソフトウェア全体をごく短期間で腐敗させることになる。


## 悪いコードは邪心を引き出す
ソフトウェアに「割れた窓」が少しでもあると、修正するプログラマに「**きっと残りのすべてのコードもガラクタなんだから、自分も適当に作業してしまえ**」という考え方が忍び込んでしまう。

この種の心理学の実験として有名なものに、「郵便受け実験」がある。

:::note 
**郵便受け実験**
家の郵便受けの近くの壁に落書きがあったり、付近にゴミが捨てられていた場合、その郵便受けから郵便物が盗まれる割合が２５％にものぼる、というもの。
:::

このような窓が割れた状態が放置されると、人間は「みんな見て見ぬふりで、いざという時に自分は誰からも守ってもらえないのだ」という「漠然とした不安感」を抱きます。些細なことでも、それが放置されている様子を見せ続けられると、だんだん神経質になったり、自己防衛本能や恐怖に対する交感神経が高まり、それが高まったときに暴力的になる。

このような人間の小さな乱れが、脆弱性をあらわにしていく。

## コードは「清潔に保つ」
コードの「割れた窓」、つまりコードの良くない部分をそのままにせず、発見と同時に修復する。「割れた窓」がなくなれば、つまりコードが清潔で美しく保たれていれば、プログラマがそれを汚さないように、最新の注意を払うことになる。
たとえ納期を目の前にしたとしても、**コードを汚してしまう最初の人間にはなりたくない**、と思うからです。

また、正しく修復する十分な時間がない場合は、「このコードが良くない」という旨を、わかりやすいところに明示する。ダメージが広がるのを防ぐため、悪い状況が管理されていることをアピールする。


---

参考文献
「*プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則*」


https://www.amazon.co.jp/dp/4798046140?ref_=cm_sw_r_cp_ud_dp_0C637KV2ZJAP5TECFEK4_2
Pythonのset型（集合型）の使い方をコードを用いて解説

Pythonのset型は、重複要素を持たない要素の集合を表現するデータ型です。set型の使い方をコード例を交えて説明します。

## 1. 集合の作成

set型の集合を作成する方法です。

```python
my_set = {1, 2, 3, 4, 5}
```
このコードでは、波括弧 {} を使用して、要素が1から5までの集合を作成しています。

## 2. 空の集合の作成

空のsetを作成する方法です。

```python
empty_set = set()
```
このコードでは、set()コンストラクタを使用して空の集合を作成しています。

## 3. 集合の要素の追加

集合に要素を追加する方法です。

```python
my_set = {1, 2, 3}
my_set.add(4)
```
このコードでは、add()メソッドを使用して、集合my_setに要素4を追加しています。

## 4. 集合の要素の削除

集合から要素を削除する方法です。

```python
my_set = {1, 2, 3, 4, 5}
my_set.remove(3)
```
このコードでは、remove()メソッドを使用して、集合my_setから要素3を削除しています。

## 5. 集合の要素の確認

特定の要素が集合に存在するかどうかを確認する方法です。

```python
my_set = {1, 2, 3, 4, 5}

# 要素の存在確認
is_present = 3 in my_set  # True
is_absent = 6 in my_set   # False
```
このコードでは、in演算子を使用して要素の存在を確認しています。

## 6. 集合の操作

集合の演算（和集合、積集合、差集合など）を行う方法です。

```python
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

# 和集合
union_set = set1 | set2  # {1, 2, 3, 4, 5, 6}

# 積集合
intersection_set = set1 & set2  # {3, 4}

# 差集合
difference_set = set1 - set2  # {1, 2}
```
このコードでは、|演算子で和集合、&演算子で積集合、-演算子で差集合を計算しています。

set型は、要素の一意性を保持し、重複を許さないため、データの一意性を保つのに役立ちます。また、集合演算を使用してデータの操作を効率的に行うことができます。

## Pythonのお役立ち情報

https://wagtechblog.com/programing/python-school

https://wagtechblog.com/programing/ai-develop-school
Pythonのreplaceで文字列を置換する方法をコードを用いて解説

Pythonの replace() メソッドは、文字列内の指定した部分文字列を別の文字列に置換するために使用されます。以下に、replace() メソッドの使い方をコード例を交えて説明します。

## 1. 単純な置換

replace() メソッドを使用して、文字列内の指定した部分文字列を別の文字列に置換する例です。

```python
original_text = "Pythonは素晴らしいプログラミング言語です。"
new_text = original_text.replace("Python", "Java")

print(new_text)
```
このコードでは、replace() メソッドを使用して、"Python" を "Java" に置換しています。結果は新しい文字列 new_text に格納され、コンソールに表示されます。

## 2. 置換回数の指定

replace() メソッドを使用して、置換の回数を指定する例です。

```python
text = "PythonはPythonなので、PythonをPythonと呼びます。"
new_text = text.replace("Python", "Java", 2)

print(new_text)
```
このコードでは、replace("Python", "Java", 2) のように置換回数を指定しています。これにより、最初の2つの "Python" のみが "Java" に置換されます。

## 3. 大文字・小文字を区別しない置換

replace() メソッドを使用して、大文字と小文字を区別しない置換を行う例です。

```python
text = "Python is Python, python, PYTHON."
new_text = text.replace("python", "Java", -1)  # -1を指定して大文字・小文字を区別しない

print(new_text)
```
このコードでは、replace() メソッドの最後の引数に -1 を指定して、大文字・小文字を区別しない置換を行います。結果はすべての "python" が "Java" に置換されます。

replace() メソッドは、文字列内の特定の部分を効率的に置換する際に非常に便利です。必要に応じて大文字・小文字の区別を指定したり、置換回数を制御したりできます。

## Pythonのお役立ち情報

https://wagtechblog.com/programing/python-school

https://wagtechblog.com/programing/ai-develop-school
vueのテーブル入れ子がIEで出ないのの解決

要約
- `template`は使えない
    - `tbody`なら代用できる
- `table`の直の子要素の幅の制御が特殊？
    - `tbody`の繰り返しをするときは、繰り返さない行も`tbody`に入れる

```html:
<script type="text/javascript" src="vue.js"></script>
<style>
  table,
  tr,
  td,
  th {
    border: solid black 1px;
    border-collapse: collapse;
  }
</style>
<div id="app">
<!-- NG

IEで template タグはレンダされない
  <table>
    <tr>
      <td>col1</td>
      <td>col2</td>
    </tr>
    <template v-for="item in group">
      <tr>
        <td colspan="2">{{item.lab}}</td>
      </tr>
      <tr v-for="r in item.contents">
        <td>{{r.v1}}</td>
        <td>{{r.v2}}</td>
      </tr>
    </template>
  </table>

IE で 1行目(ヘッダ行)の1列目の幅と2行目以降の2列分の幅が同じになってしまう。
  <table>
    <tr>
      <td>col1</td>
      <td>col2</td>
    </tr>
    <tbody v-for="item in group">
      <tr>
        <td colspan="2">{{item.lab}}</td>
      </tr>
      <tr v-for="r in item.contents">
        <td>{{r.v1}}</td>
        <td>{{r.v2}}</td>
      </tr>
    </tbody>
  </table>
-->

  <table>
    <tbody>
      <tr>
        <td>col1</td>
        <td>col2</td>
      </tr>
    </tbody>
    <tbody v-for="(item,i) in group">
      <tr>
        <td colspan="2">{{item.lab}}</td>
      </tr>
      <tr v-for="(r,j) in item.contents" :key="'j'+j">
        <td>{{r.v1}}</td>
        <td>{{r.v2}}</td>
      </tr>
    </tbody>
  </table>

</div>

<script>
  app = new Vue({
    el: "#app",
    data: {
      group: [
        {
          lab: "lab1",
          contents: [
            { v1: "1-1-v1", v2: "1-1-v2" },
            { v1: "1-2-v1", v2: "1-2-v2" },
          ],
        },
        {
          lab: "lab2",
          contents: [
            { v1: "2-1-v1", v2: "2-1-v2" },
            { v1: "2-2-v1", v2: "2-2-v2" },
            { v1: "2-3-v1", v2: "2-3-v2" },
          ],
        },
      ],
    },
  });
</script>
```

捨てよう、IE
Pythonの文字列出力print()の使い方をコードを用いて解説

Pythonの print() 関数は、コンソールにテキストを出力するために使用されます。以下に、print() の基本的な使い方と応用的な使い方をコード例を交えて説明します。

## 1. 基本的な文字列の出力

print() を使用して文字列を出力する基本的な例です。

```python
print("こんにちは、Python!")
```
このコードでは、文字列 "こんにちは、Python!" がコンソールに出力されます。

## 2. 変数の値を出力

変数の値を print() を使用して出力する例です。

```python
name = "Alice"
age = 30

print("名前:", name)
print("年齢:", age)
```
このコードでは、変数 name と age の値が出力されます。

## 3. 書式指定

print() に書式指定文字列を使用して、変数を埋め込むことができます。

```python
name = "Bob"
age = 25

print("名前: {}, 年齢: {}".format(name, age))
```
このコードでは、{} を使用して変数の値を埋め込んでいます。

## 4. 複数の要素を一度に出力

複数の要素を一度に print() で出力する例です。

```python
item1 = "リンゴ"
item2 = "バナナ"
item3 = "オレンジ"

print(item1, item2, item3)
```
このコードでは、スペースで区切られた複数の要素が一度に出力されます。

## 5. 改行なしで出力

デフォルトでは print() は出力の最後に改行が入りますが、改行なしで出力する例です。

```python
print("改行なしで", end=" ")
print("出力します。")
```
このコードでは、end パラメータを使用して改行なしで出力しています。

## 6. ファイルへの出力

print() を使用してテキストをファイルに出力する例です。

```python
with open("output.txt", "w") as f:
    print("ファイルに出力します。", file=f)
```
このコードでは、open() 関数を使用してファイルを開き、print() を使用してテキストをファイルに書き込んでいます。

これらの例は、print() 関数の基本的な使い方と応用的な使い方を示しています。 print() を使用してテキストを出力することは、デバッグ、情報の表示、ファイルへのログの書き込みなど、Pythonプログラムで非常に一般的な操作です。

## Pythonのお役立ち情報

https://wagtechblog.com/programing/python-school

https://wagtechblog.com/programing/ai-develop-school
Pythonのclassの使い方をコード例を用いて解説

Pythonのclassを使ってクラスを定義し、オブジェクトを作成する方法をコード例を交えて説明します。

## 1. クラスの定義とオブジェクトの作成

クラスを定義し、それを基にオブジェクトを作成するコード例です。

```python
# クラスの定義
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# オブジェクトの作成
person1 = Person("Alice", 30)
person2 = Person("Bob", 25)

# オブジェクトの情報を表示
print(f"{person1.name}は{person1.age}歳です。")
print(f"{person2.name}は{person2.age}歳です。")
```
このコードでは、Personクラスを定義し、__init__メソッドを使用してオブジェクトの初期化を行っています。それから、person1とperson2という2つのオブジェクトを作成し、それぞれの情報を表示しています。

## 2. クラスのメソッド

クラス内でメソッドを定義し、オブジェクトで呼び出すコード例です。

```python
# クラスの定義
class Calculator:
    def add(self, x, y):
        return x + y

    def subtract(self, x, y):
        return x - y

# オブジェクトの作成
calc = Calculator()

# メソッドの呼び出し
result1 = calc.add(5, 3)
result2 = calc.subtract(10, 2)

print(f"5 + 3 = {result1}")
print(f"10 - 2 = {result2}")
```
このコードでは、Calculatorクラスを定義し、addとsubtractメソッドを作成しています。オブジェクトcalcを作成し、メソッドを呼び出して計算結果を表示しています。

## 3. クラスの継承

クラスの継承を使用して新しいクラスを作成するコード例です。

```python
# 親クラスの定義
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        pass

# 子クラスの定義
class Dog(Animal):
    def speak(self):
        return f"{self.name}がワンワンと鳴いています。"

class Cat(Animal):
    def speak(self):
        return f"{self.name}がニャーニャーと鳴いています。"

# オブジェクトの作成
dog = Dog("ワンちゃん")
cat = Cat("にゃんこ")

# メソッドの呼び出し
print(dog.speak())
print(cat.speak())
```
このコードでは、Animalクラスを親クラスとし、DogとCatクラスを子クラスとして定義しています。子クラスでspeachメソッドをオーバーライドして、それぞれの動物の鳴き声を定義しています。

これらのコード例は、Pythonでクラスを定義し、オブジェクトを作成する基本的な使い方を示しています。クラスはデータとメソッドを組み合わせて、オブジェクト指向プログラムの中心的な要素です。

## Pythonのお役立ち情報

https://wagtechblog.com/programing/python-school

https://wagtechblog.com/programing/ai-develop-school
Pythonのsplit()、文字列分割の使い方を解説

Pythonのsplit()メソッドは、文字列を指定した区切り文字で分割し、分割された部分文字列をリストとして返します。split()メソッドの活用法をコード例を交えて説明します。

## 1. スペースで文字列を分割

文字列をスペースで分割するコード例です。

```python
sentence = "これは Python の split() メソッドの例です"

# 文字列をスペースで分割
words = sentence.split()

print(words)
```
このコードでは、split()メソッドを引数なしで呼び出して、文字列をスペースで分割しています。分割された単語はリストに格納されます。

## 2. カンマでCSVデータを分割

CSV形式のデータをカンマで分割するコード例です。

```python
csv_data = "Alice,30,New York"

# CSVデータをカンマで分割
fields = csv_data.split(",")

print(fields)
```
このコードでは、split(",")を使用して、CSVデータをカンマで分割しています。各フィールドはリストに格納されます。

## 3. 複数行のテキストを行ごとに分割

複数行のテキストを行ごとに分割するコード例です。

```python
text = """これは
複数行の
テキストです"""

# テキストを行ごとに分割
lines = text.splitlines()

print(lines)
```
このコードでは、splitlines()メソッドを使用して、複数行のテキストを行ごとに分割しています。

## 4. デフォルトの区切り文字を指定

split()メソッドでデフォルト以外の区切り文字を指定するコード例です。

```python
date = "2023-09-18"

# ハイフンで日付を分割
date_parts = date.split("-")

print(date_parts)
```
このコードでは、split("-")を使用して、日付をハイフンで分割しています。デフォルトではスペースが区切り文字として使用されますが、ここではハイフンを指定して分割しています。

split()メソッドは、文字列の解析やデータの取り出しに非常に便利です。データを適切に分割して、必要な情報を取り出すために使用できます。

## Pythonのお役立ち情報

https://wagtechblog.com/programing/python-school

https://wagtechblog.com/programing/ai-develop-school
Pythonのスライスの使い方を解説

Pythonのスライス（slice）は、リスト、文字列、タプルなどのシーケンス（sequence）型オブジェクトから部分的なデータを取得するための強力な機能です。スライスの基本的な使い方をコード例を交えて説明します。

## 1. リストのスライス

リストから部分リストを取得するコード例です。

```python
my_list = [1, 2, 3, 4, 5]

# インデックス1から3（終端の前まで）の要素を取得
subset = my_list[1:4]

print(subset)  # 出力: [2, 3, 4]
```
このコードでは、my_list[1:4] を使用して、インデックス1から3までの要素を取得しています。

## 2. 文字列のスライス

文字列から部分文字列を取得するコード例です。

```python
my_string = "Hello, World!"

# インデックス7から12（終端の前まで）の部分文字列を取得
substring = my_string[7:12]

print(substring)  # 出力: "World"
```
このコードでは、my_string[7:12] を使用して、インデックス7から11までの部分文字列を取得しています。

## 3. ステップ（スライスの間隔）を指定する

ステップを指定してスライスを行うコード例です。

```python
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]

# インデックス1から8までの要素をステップ2で取得
subset = my_list[1:9:2]

print(subset)  # 出力: [2, 4, 6, 8]
```
このコードでは、my_list[1:9:2] を使用して、インデックス1から8までの要素をステップ2で取得しています。

## 4. スライスの省略

スライスを省略して、リストや文字列の一部を取得するコード例です。

```python
my_list = [1, 2, 3, 4, 5]

# 最初からインデックス2までの要素を取得
subset1 = my_list[:3]

# インデックス2から最後までの要素を取得
subset2 = my_list[2:]

print(subset1)  # 出力: [1, 2, 3]
print(subset2)  # 出力: [3, 4, 5]
```
このコードでは、[:3] は最初からインデックス2までの要素を、[2:] はインデックス2から最後までの要素を取得します。

Pythonのスライスは非常に柔軟で強力であり、シーケンス型オブジェクトから特定の部分を抽出するために広く使用されます。スライスを使うことで、データの加工やフィルタリングが容易に行えます。

## Pythonのお役立ち情報

https://wagtechblog.com/programing/python-school

https://wagtechblog.com/programing/ai-develop-school
Pythonのdictionary（辞書）の使い方を解説

Pythonの辞書（dictionary）は、キー（key）と値（value）のペアを格納するデータ構造です。以下に、Pythonの辞書の基本的な使い方をいくつかのコード例を交えて説明します。

## 1. 辞書の作成と要素の追加

辞書を作成し、キーと値を追加するコード例です。

```python
# 空の辞書を作成
my_dict = {}

# キーと値を追加
my_dict['name'] = 'Alice'
my_dict['age'] = 30
my_dict['city'] = 'New York'

# 辞書の内容を表示
print(my_dict)
```
このコードでは、空の辞書 my_dict を作成し、['name']、['age']、['city'] のキーとそれに対応する値を追加しています。

## 2. 辞書の要素のアクセス

辞書内の要素にアクセスするコード例です。

```python
# 辞書の要素にアクセス
name = my_dict['name']
age = my_dict['age']

# アクセスした要素を表示
print(f'名前: {name}, 年齢: {age}')
```
このコードでは、['name'] キーと ['age'] キーを使用して、辞書内の値にアクセスしています。

## 3. 辞書のループ処理

辞書内のキーと値を反復処理するコード例です。

```python
# 辞書のキーと値を反復処理
for key, value in my_dict.items():
    print(f'{key}: {value}')
```
このコードでは、items() メソッドを使用して辞書内のキーと値のペアを反復処理しています。

## 4. 辞書のキーの存在確認

指定したキーが辞書内に存在するかどうかを確認するコード例です。

```python
# キーの存在確認
if 'name' in my_dict:
    print('名前が存在します。')

if 'address' not in my_dict:
    print('住所は存在しません。')
```
このコードでは、in キーワードを使用してキーの存在を確認しています。

これらはPythonの辞書の基本的な使い方の一部です。辞書はさまざまなデータを効率的に格納し、検索するために非常に便利なデータ構造です。必要に応じて辞書を操作し、データを取り出したり、変更したりできます。

## Pythonのお役立ち情報

https://wagtechblog.com/programing/python-school

https://wagtechblog.com/programing/ai-develop-school
アジャイル道

## アジャイルソフトウェア開発宣言
左記よりも右記の価値を優先する
- プロセスやツールよりも個人と対話を
- 包括的なドキュメントよりも動くソフトウェアを
- 契約交渉よりも顧客との協調を
- 計画に従うことよりも変化への対応を


## アジャイル宣言の背後にある原則
スクラム的にあてはめる

- 顧客満足を最優先し、価値のあるソフトウェアを早く継続的に提供
    - スプリントが短い方が良い
- 要求の変更はたとえ開発の後期であっても歓迎。変化を味方につけることによってお客様の競争力を引き上げる
    - ウォーターフォールとの大きな違い
- 動くソフトウェアを2-3週間から2-3か月というできるだけ短い時間間隔でリリース
    - スプリント
- ビジネス側の人と開発者はプロジェクトを通して日々一緒に働かなければならない
    - スクラムチーム
- 意欲に満ちた人々を集めてプロジェクトを構成。環境と支援を与え仕事が無事終わるまで彼らを信頼する
    - SBI
- 情報を伝える効率的で効果的な方法はフェイス・トゥ・フェイスで話をすること
    - 各イベント
- 動くソフトウェアこそが進捗の最も重要な尺度
    - インクリメント
- アジャイルプロセスは持続可能な開発を促進。一定のペースを継続的に維持できるようにしなければならない
    - スプリントと各イベント
- 技術的卓越性と優れた設計に対する不断の注意が機敏さを高める
    - 職能横断。自己組織化し課題を可視化
- シンプルさ（無駄なく作れる量を最大限にすること）が本質
    - 各イベント。最低限の設計書
- 最良のアーキテクチャ・要求・設計は自己組織的なチームから生み出される
- チームがもっと効率を高めることができるかを定期的にふりかえり、それに基づいて自分たちのやり方を最適に調整
    - レトロ
なぜGoogle以外のパスワードマネージャーが必要なのか

# TL;DR

安心するためにパスワードマネージャーを使う

# Google パスワードマネージャーのみだと困る理由

- Googleアカウントを誤って削除するリスクがある
- 複数のGoogleアカウントを使う場合、どのアカウントにパスワードを入力したか探さないといけない
- スマホでパスワードを確認する場合、画面ロックを設定して毎回解除しないといけない
- Googleドライブやスプレッドシートでもパスワード管理できるがGoogleアカウントにログインできなければ終わり

# パスワードを紙で管理しない理由

- 外出先でパスワードを確認するときに常に紙を持ち歩かないといけない
- 盗難や火災でパスワードを紛失するリスクがある

# どのパスワードマネージャーを使うべきか？

- 1Password
- LastPass
- Bitwarden
- KeePass

一番老舗な1Passwordが安心できそう。それ以外は問題があったりローカルにしか保存できなかったり不便！
[https://ja.wikipedia.org/wiki/LastPass#セキュリティ問題](https://ja.wikipedia.org/wiki/LastPass#セキュリティ問題)
[https://ja.wikipedia.org/wiki/Bitwarden#JavaScriptを埋め込んだとして批判された](https://ja.wikipedia.org/wiki/Bitwarden#JavaScriptを埋め込んだとして批判された)

**1Passwordでお金払えなくなったらパスワードはどうなるのか？**

凍結はされるけど、パスワードを確認することは可能。

**もしマスターパスワードを忘れたら？**

34桁の固有のシークレットキーを印刷して保管することでマスターパスワードを忘れても大丈夫

# まとめ

長年パスワード管理に悩まされていたが自分の中で答えが出てよかった。Googleパスワードマネージャーも使うけど、冗長化構成として1Passwordも使ってゆるく管理していく。