OmniAICreator/Qiita-1.07M huggingface dataset:
SchemaSpyの設定を環境変数でいい感じに指定する

「SchemaSpyを使ってER図を作ってるけど、プロジェクトや環境が変わるたびにschemaspy.propertyを作るとそのまま再利用できないじゃん！」ってなってる方向けの記事です。
また、SchemaSpyのバージョン変更によりディレクトリ構成も変わってきているみたいなので、今のところの最新バージョン(v6.2.4)でやるための方法を示します。

## TL;DR
公式のDockerイメージを用いて、schemaspy.propertyを使わず環境変数でプロパティを指定できるイメージを生成します。

## 要件
- schemaspy.propertyのファイルを環境毎やプロジェクト毎に用意するのが面倒
- 後々ECRに乗せて運用する場合にも便利
- entrypoint.shをいつでも編集できるようにしておくと、生成後に何をさせたいかも容易
  - 例えば静的ファイルを生成するツールを入れて実行させ、S3にアップする等

## 全体のファイル構成
```sh
schemaspy/
    ├── output/ # ここにindex.htmlが出力される
    ├── Dockerfile
    └── entrypoint.sh
```

## Dockerfile

```dockerfile
FROM schemaspy/schemaspy:6.2.4

COPY ./entrypoint.sh /

ENTRYPOINT ["/entrypoint.sh"]
```

昔はjavaのツールを入れないと動かなかったけど、最新のはちゃんと入ってるので入れなくても動きますね・・・。

## entrypoint.sh

このファイルにはchmodで実行権限つけてあげてください。

```shell
#!/bin/sh

[ -d $SCHEMASPY_DRIVERS ] && export DRIVER_PATH=$SCHEMASPY_DRIVERS || export DRIVER_PATH=/drivers_inc/
echo -n "Using drivers:"
ls -Ax $DRIVER_PATH | sed -e 's/  */, /g'
exec java -jar /usr/local/lib/schemaspy/schemaspy*.jar \
    -dp $DRIVER_PATH \
    -o $SCHEMASPY_OUTPUT \
    -t $DB_TYPE \
    -host $DB_HOST \
    -port $DB_PORT \
    -db $DB_NAME \
    -u $DB_USER \
    -s $DB_SCHEMA \
    -p $DB_PASS \
    -connprops useSSL\\=false \
    -debug
```

ログ出力不要なら`-debug`は削除してOKです。
出力後にツールを使って静的ファイルにしてaws cliでS3に投げる、などやりたいことできます。

## イメージ作成、実行する

イメージを作成する
```
$ docker build -t er-document .
```

試しに環境変数を指定しつつ実行する。
(※ローカルでmysqlのコンテナが立ち上がっている前提です)
```
docker run --platform linux/amd64 \
           --net host \
           -v "$PWD/output:/output" \
           --rm \
           -e SCHEMASPY_OUTPUT="/output" \
           -e DB_TYPE="mysql" \
           -e DB_HOST="localhost" \
           -e DB_PORT=3366 \
           -e DB_NAME=test_db" \
           -e DB_SCHEMA="test_db" \
           -e DB_USER="test_user" \
           -e DB_PASS="password" \
           er-document
```

outputディレクトリにファイルが生成されれば動作は正常です。
これでschemaspy.propertyなしで、デプロイ環境などで設定された環境変数を用いて動作できます。

## 余談
DockerfileにENTRYPOINTを食わせれば、imageに入っているデフォルトのENTRYPOINTを上書きできます。
ShemaSpy:6.2.4ではコンテナ内の以下ディレクトリにschemaspyというファイルが入っており、これがデフォルトのENTRYPOINTです。

- **ディレクトリ**
```
/usr/local/bin/
```

- **schemaspy**
```
[ -d $SCHEMASPY_DRIVERS ] && export DRIVER_PATH=$SCHEMASPY_DRIVERS || export DRIVER_PATH=/drivers_inc/
echo -n "Using drivers:"
ls -Ax $DRIVER_PATH | sed -e 's/  */, /g'
exec java -jar /usr/local/lib/schemaspy/schemaspy*.jar -dp $DRIVER_PATH -o $SCHEMASPY_OUTPUT "$@"/usr/local/bin
```

今回の記事では、このファイルの `exec java -jar 〜` あたりの実行コマンドを編集し、環境変数を読み込ませちゃおうという感じでした。

## 参考記事

[AWS ECSにSchemaSpyを乗せてサーバレスでER図を作成する](https://qiita.com/yoshiken/items/0c5dce47f80dc8f04eaa)
化学畑出身の新米データサイエンティストが基本情報技術者試験を受けてみた

データサイエンティストとして働きはじめ約1年経過したころ、エンジニアの登竜門とも呼ばれる基本情報技術者試験を受験してきました。

**ITの知識がほとんどない状態からのスタートでしたが、何と合格基準6割のところ約8割の得点で合格することができた**ので、勉強法や資格受験の感想やメリットなどをまとめます。

# はじめに
## 自己紹介
- 大学は化学専攻
- 新卒でデータサイエンティストとして就職
- プログラミングは独学、PC知識は皆無

## 基本情報技術者試験とは
エンジニアの登竜門と呼ばれる試験です。かの有名な資格「ITパスポート」の次のステップなどと言われることもあります。

### 対象者
[公式サイト](https://www.ipa.go.jp/shiken/kubun/fe.html)では以下のように書かれています。
> ITを活用したサービス、製品、システム及びソフトウェアを作る人材に必要な基本的知識・技能をもち、実践的な活用能力を身に付けた者

### 試験形式
2023年4月より、PCで試験を受験するCBT方式となりました（今回自分が受けたのもこの形式となります）。

また、試験は「科目A（90分）」と「科目B（100分）」の2部構成となっており、どちらも1000点満点で600点以上が合格となります。

## 受験のモチベーション
基本的なIT知識を得たかったためです！

自分は「プログラミングを知っているIT音痴」であることを自覚していて、IT系の技術者としては恥ずかしいレベルであったので、とにかく基本的な知識を網羅的に見に着けたいと考えていました。

（「MACアドレス？私のPCはWindowsだよ！」とか言ってしまうレベルでした…）

# 受験結果
単刀直入ですが、勉強法紹介の前に結果を報告してしまいます。
- 科目A **785** /1000
- 科目B **810** /1000

合格基準点は600点なので、どちらも余裕を持って合格できた形となります。
# 勉強方法
ここからは私が行った勉強について紹介します。
## 1. 参考書を1周
まず、基本知識を仕入れることを目的として参考書を1周しました。自分は動画教材などは苦手なので、[キタミ式イラストIT塾 基本情報技術者](https://www.amazon.co.jp/%E3%82%AD%E3%82%BF%E3%83%9F%E5%BC%8F%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88IT%E5%A1%BE-%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85-%E4%BB%A4%E5%92%8C06%E5%B9%B4-%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E6%8A%80%E8%A1%93%E8%80%85%E8%A9%A6%E9%A8%93-%E3%81%8D%E3%81%9F%E3%81%BF%E3%82%8A%E3%82%85%E3%81%86%E3%81%98/dp/4297138077/ref=asc_df_4297138077/?tag=jpgo-22&linkCode=df0&hvadid=676036410708&hvpos=&hvnetw=g&hvrand=725555061545514925&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009233&hvtargid=pla-2247804171118&psc=1&mcid=a32f62274e343784980ba6e36a9cf404&th=1&psc=1&gad_source=1)を使って勉強しました。

この本は分厚いので勉強の気が重くなりそうにも思えますが、イラストを交えて要点が簡潔にまとめられているので、1周するのも苦ではありませんでした。

## 2. 過去問演習
IPAの公式サイトに載っている過去問をひととおり演習しました。流れは以下の通りです。

------------------------------------------------------------------------
1. 過去問1回分を解く
1. 答え合わせ（正答率を計算）
1. 分からなかったところや間違えたところを理解する
1. 次の過去問へ
------------------------------------------------------------------------

6割が合格点となるので、それを余裕で上回る7.5～8割正答を目標にしていました。

過去問演習を行う中で、**違う年度でも同じ問題が出題されることがあると分かり、頻出分野が分かったのは大きな収穫でした。**

## 3. 復習＆仕上げ
過去問を解く中で合格点は取れそうということは分かっていましたが、不安感があったので、苦手と感じた分野を上述の参考書「キタミ式」で復習しつつ、基本情報技術者試験の過去問がまとまった[過去問道場というサイト](https://www.fe-siken.com/fekakomon.php)で解いて最後の仕上げを行いました。

過去問道場は1問1答形式で演習ができるので、移動中や空き時間にスマホで勉強できて便利でした。また、かなり古い過去問も掲載されているので、IPA公式にはもう掲載のない問題もあり、最後の仕上げにはピッタリでした。

また、ここでの仕上げのお陰で基準点を上回る合格ができたように思います。

# 資格受験を通して
**PCやネットワークの仕組み・プロジェクトの進め方など基本的な知識を体系的に学ぶことができたので、効率良く最低限の知識を身に着けられた** と思います。エンジニアほどの知識は必要ないとはいえ、ITを駆使した仕事をするデータサイエンティストである以上、知っておきたい基礎知識が身に着く資格だと感じました。

次は応用情報技術者試験を目指せたらと考えています！
GitHub Monopoly Go Free Dice 2025newCodeBuildを試す

Monopoly Go Free Dice Links 2025: All the Ways to Get Free 50 Dice Rolls Without Paying
<h1> <a href="https://epicmpoly.blogspot.com/">Click Here To Get Monopoly Go Free Dice </a>

に記載のある、AWS CodeBuildをGitHub ActionsのSelf-hosted Runnerとして使用可能な機能を試します。
確認時点では英語のドキュメントのみあり、日本語版ではページごとありませんでした。 
Monopoly GO free Dice links (May 2024) Dot Esports
Six ways to get free Dice rolls in Monopoly GO · 1) Claim daily login rewards · 2) Increase your net worth · 3) Play Community Chests · 4) Bring friends to the ...MONOPOLY GO! FREE DICE LINKS

Facebook · MONOPOLY GO! FREE DICE LINKS Dice Free For Everyone ✓This will not require anything from you collect it... Immediatelly Claim 10.000 Dice Free For Everyone✓ 1BB9DCXQ3V.

+~(LIMITED-EDITION) Free Monopoly Go Dice Links ... hours ago — Aside from the social media links, there are other ways to acquire free dice in Monopoly GO. One option is to participate in giveaways and ...

Reddit · r/MonopolyGoDiceLinks Short on Monopoly Go! Dice? This is the community for you! Dice links posted daily for all users! Interested in trading…

2024-05-14時点での内容です。最新情報は上記ドキュメントを参照ください。また実際に動かしてみるのが一番わかると思います。
普段はGitHub ActionsをGitHub-hosted Runnerで動かしているので、CodeBuildにはあまり慣れていません。CodeBuild使っていれば常識的な部分もあるかもしれません。

基本的な使い方
AWS CodeBuild上でGitHubに接続設定したプロジェクトを用意し、その名前をGitHub Actionsのyamlのruns-onに記載することで動作します。
Terraformで表すと以下のような設定です。
Google Apps Script (GAS) の使いかた【基礎メソッド編】

# Google Apps Script (以下gas) とは
詳しくは[こちら](https://qiita.com/tacopic-007/items/05fff88270f9eb59e826)の記事に記載していますが、簡単に説明するとGoogleサービスの自動化スクリプトをAPIなどを使用せずに開発できる、めちゃんこ便利な言語です。

# 概念の説明
```js:コード.gs
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = spreadsheet.getActiveSheet();
```
この2つが頻繁に使用する、スプレッドシートオブジェクトです。
ぱっと見たところ、同じようなものに見えますが何が違うのでしょうか？

`spreadsheet`は、名前の通りそのスプレッドシートを取得しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3714044/cc96cbf4-5dcf-0ee8-65b5-f0b803522b6e.png)

`sheet`は、スプレッドシート下部にある、シートのことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3714044/fb7d1603-4f16-3baf-19dd-76443abfb17e.png)

また、実行しているスプレッドシートではない、別のスプレッドシートを取得するには
```js:コード.gs
const AnotherSheet = SpreadsheetApp.openByUrl("url");
```
を使用します。`url`にはスプレッドシートのurlを指定します。


# よく使用するメソッド
まず、シートの中のセルを操作するために、セルを取得します。
```js:コード.gs
const cell = sheet.getRange("セル座標");
```
`セル座標`には`A1`のように指定することも、`A1:C3`のように範囲指定もできます。
<hr>

```js:コード.gs
  range.clear();
  //すべてをclear

  range.clearContents();
  //値・書式のみをクリア

  range.clearFormats();
  //書式をすべてクリア

  range.setFontFamily();
  //FontFamilyを設定

  range.setBackground();
  //Background-colorを設定

  range.setFontColor();
  //FontColorを設定

  range.setValue();
  //セルの文字を設定

  range.setBorder();
  //ボーダーを設定

  ramge.setNumberFormat();
  //セルの文字列に時間を設定する
```
セルの基本操作メソッドを並べました！
計算などのプログラムは基本的にjavascriptと同じなので、調べるときはjavascriptを使用している体で調べたほうがいいと思われます。

ただし、javascriptでいう`console.log()`は、gasでは`Logger.log()`となります。
使い方は基本`console.log()`と同じになります。

# 最後に
gasを使ってやりたいことがあるのであれば、基本操作覚えたらなにか1つシステムを作ってみると覚えやすいと思います！

また、gasでは簡単なwebアプリを簡単に作ることができるので、成果物の作成と合わせて[Webアプリ編](https://qiita.com/minoru_kinugasa/items/a6930f66bb1d048305ce)もぜひご覧ください！
PythonでPDFをPDF/AまたはPDF/Xに変換する

PDF/AとPDF/Xは、特定の目的を持つ2つのPDFフォーマットです。PDFファイルをこの2つのフォーマットに変換することで、将来のアクセスや印刷のために、ドキュメントが最高の品質と精度を維持することを保証することができます。

この記事では、Pythonを使ってPDFファイルをPDF/AまたはPDF/Xに変換する方法を紹介します。

## PDFファイルを変換するPython PDFライブラリ
変換タスクにはサードパーティライブラリ[**Spire.PDF for Python**](https://www.e-iceblue.com/Introduce/pdf-for-python.html)が必要です。以下のpipコマンドでインストールできます：
> pip install Spire.PDF

## PythonでPDFをPDF/A形式に変換する
PDF/AはPDFアーカイブのためのISO定義規格で、現在3つの仕様があります： 現在、PDF/A-1、PDF/A-2、PDF/A-3の3つの仕様があります。各仕様には2つの適合レベル（AまたはB）があり、異なるニーズに適しています。SpirePDFforPythonはPDF/A-1a, 2a, 3a, 1b, 2b, 3bへのPDF変換をサポートしています。

**変換コードは以下の通りです：** 
```python
from spire.pdf.common import *
from spire.pdf import *
 
# PdfStandardsConverterオブジェクトを作成し、パラメータとしてPDF文書を渡す
converter = PdfStandardsConverter("input.pdf")
 
# PDFをPDF/A-1aに変換する
converter.ToPdfA1A("PdfA1A.pdf")
 
# PDFをPDF/A-1bに変換する
converter.ToPdfA1B("PdfA1B.pdf")
 
# PDFをPDF/A-2aに変換する
converter.ToPdfA2A("PdfA2A.pdf")
 
# PDFをPDF/A-2bに変換する
converter.ToPdfA2B("PdfA2B.pdf")
 
# PDFをPDF/A-3aに変換する
converter.ToPdfA3A("PdfA3A.pdf")
 
# PDFをPDF/A-3bに変換する 
converter.ToPdfA3B("PdfA3B.pdf")
```
**PDF/A の例図：**
![pdfa1a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/1c623b4c-6802-66ea-f01c-4004ff97ec46.png)

## PythonでPDFをPDF/X-1a:2001に変換する
PDF/Aフォーマットに加え、Spire.PDF for PythonはPDF/X-1a:2001規格へのPDF変換もサポートしています。2001年にリリースされたこの規格はPDF/X-1のサブ規格で、印刷や出版で広く使用されています。

**変換コードは以下の通りです：**
```python
from spire.pdf.common import *
from spire.pdf import *
 
# PdfStandardsConverterオブジェクトを作成し、パラメータとしてPDF文書を渡す
converter = PdfStandardsConverter("考核.pdf")
 
# PDFをPDF/X-1a:2001に変換する
converter.ToPdfX1A2001("PDFtoPdfX1a.pdf")
```

**PDF/X-1a:2001 の例図：**
![pdfx1a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/10e9a707-35b9-a981-f205-e070239eb28e.png)


以上の3つのサンプルコードを通して、PDFからPDF/A、PDFからPDF/Xへの変換をPythonで実現できます。ご質問があれば、[**フォーラム**](https://www.e-iceblue.com/forum/spire-pdf-f7.html)で議論してください。

赤い透かしを削除するには、トライアルライセンスを取得します：
https://www.e-iceblue.com/TemLicense.html
AWSセレクトパートナーへの道のり ～BeautyTech企業を目指して～

# はじめに

弊社はCCoEの活動としまして2024年2月22日に[APNセレクトパートナーに認定](
https://www.po-holdings.co.jp/news/pdf/20240405_topics.pdf)されました！

参画経緯は弊社エンジニア採用サイトにて詳しくお話しておりますのでぜひご覧ください:sparkles: 

https://engineer.po-holdings.co.jp/articles/529/

当記事では、レジスタードからセレクトパートナーになるまでに行ったことを紹介します！
パートナーへの参画を検討されている皆様の参考になれば幸いです:relaxed:

# APNとは？
AWSパートナーネットワークは、AWS上の開発や構築経験を持つ企業を対象に世界規模で展開しているパートナープログラムのグローバルコミュニティです。
このネットワークには、200を超える国々から130,000社を超えるパートナーが参加しています。 

https://aws.amazon.com/jp/partners/programs/

昨年AWS re:Inventに参加させて頂いた際、日本からの参加者の中でもAPNに参画されている企業が多数あり日本でも浸透しているプログラムであると感じました:sunglasses:

# セレクトパートナー要件
弊社がサービスパスでセレクトティアへアップグレードした際の要件は以下の通りでした。
最初はアップグレードできるか不安でしたが、「**どうにかなりそう！:fire:** 」という思いで最短でアップグレードできるよう計画を立てました。

   | 各種項目  | 条件 |
   |-------------|--------------|
   | APN参画料  | 2,500 USD/年 |
   | デジタルトレーニング受講者 | 4（技術2人、ビジネス2人）|
   | AWS基礎認定取得者数   | 2名            |
   | AWS技術認定取得者数   | 2名            |
   | オポチュニティ登録    | 3(合計 MRR 1,500 USD以上)|

:::note warn
最新情報は必ずAWS公式サイトよりご確認ください。
https://aws.amazon.com/jp/partners/services-tiers/
:::

# 大まかなタイムライン :page_with_curl:

アップグレードまでのおおよそのタイムラインは以下です。
セレクトティアへのアップグレードまで約2ヶ月でアップグレードすることができました。

## Ⅰ APN参画に向けた各種調査:mag: （1~2週間）
① AWSパートナーになるには？の記事から所定のメールアドレスへ資料請求を行いました。参画に向けての質問事項は同宛先に行うことが可能でしたので質問のやりとりはスムーズでした。

https://aws.amazon.com/jp/blogs/psa/how_to_become_an_aws-partner/

② 社内手続きフロー確認
当社の場合主な確認先は、経理と法務関連部門でした。
必要な申請や問い合わせ先を最初のタイミングで確認/リストアップすることでこの後の流れが非常にスムーズになるかと思います。

（個人的にはAPNのアップグレード要件をクリアしていく以上に、APN参画にあたっての社内確認が時間を要した印象でしたので最初の段階での確認は大切だと思います！）

③ APN アライアンスリードアカウント登録者の選出
アライアンスリードアカウントは、組織の代表アカウントになります。
企業で1名しか指定することができませんので責任者である上長と調整を行いました。

④ アップグレード要件の確認
最初に確認した観点は**CCoEチームメンバーだけで達成可能か？** です。
もし難しい場合は、他チームへの協力依頼が必要になりますし、その分時間がかかりますよね:disappointed_relieved:
弊社は当チームだけで条件達成が可能そうでしたので、スケジュールを立てやすかったです。

## Ⅱ APNアカウント作成 / 利用規約の法務確認 :black_nib:（1週間）
① APNサインアップ画面よりアライアンスリード者が登録を行いました。その後、メンバーがアカウントを作成し、組織として紐づいていることを確認しました。

https://partnercentral.awspartner.com/partnercentral2/s/ja/SelfRegister

② 並行して、APNサインアップ時に表示される利用規約について法務確認をおこないました。
会社によっては不要なケースもあると思いますのでⅠの準備タイミングで確認有無含めて調整しておくとよりスムーズかなと思います！

## Ⅲ 要件達成に向けた活動実施（約３週間 ※反映待ち時間含）
ⅠでCCoEチーム内でのティア要件達成を見込んでおりましたので、要件達成条件が記載されるダッシュボードへの反映時間を考慮しまして以下項目については早めに登録を行いました。

- AWS認定者情報の連携
    - 個人アカウントとAPNアカウントの紐づけ方法を事前に確認しておくとスムーズです。
    - 反映までに5～7営業日程必要だったと思いますので早めの連携をおすすめします。
- オポチュニティ登録

デジタルトレーニングは受講者を決め、2週間を目安に受講頂くよう依頼しました。
デジタルトレーニングは私も受講しましたが最後に理解度確認テストがあり、思っていたより難しい問もありましたので非常に有益な動画でしたので要件に関わらず受講して良かったと思っています:mortar_board::relaxed:

ティア要件の達成は各種項目を同時並行で進めることで、約3週間で満たすことができました！

## Ⅳ 年間利用料の支払い / アップグレード申請（1週間）

ティア要件を満たしたことを確認し、年会費の支払い申請を行いました。
年会費の支払いタイミングはアップグレード申請前であればいつでも可能でしたが、弊社は社内確認等の兼ね合いもあり要件達成後に実施いたしました。

ようやく、これでアップグレードに必要なすべての要件を満たすことができまして
「アップグレード申請」ボタンをポチッと押しました！これで全ての手続きが完了です:sob:

その後は約3営業日程で承認され無事セレクトパートナーへ昇格いたしました:tada::tada:

# さいごに

今回、APNに参画することでBeautyTech企業を目指している弊社にとって大切な1歩:feet:になったと考えています。

現在は、次のステップとしてアドバンスドパートナーを目指すべくAWS活用の社内推進を積極的に行なっております:fist: 

当記事が、これからAPNに参画されることを検討している皆さんの参考になりましたら幸いです:relaxed:

# :sunny:弊社では一緒に働く仲間を募集中です :sunny:
現在、様々な職種を募集しております。
カジュアル面談も可能ですので、ご連絡お待ちしております！

募集内容等詳細は、是非採用サイトをご確認ください。
https://engineer.po-holdings.co.jp/
CRUDとは

## CRUDとは
アプリケーション作成時の4つの機能の頭文字を並べたもので
ほとんどのアプリはこの4つの機能で成り立っている

C　Create　作成	
R　Read　　表示	
U　Update　更新	
D　Delete　削除	

## コントローラ記述用コード
```ruby:controller.rb
  # 一覧表示
  def index    
  end

  # 詳細表示
  def show   
  end

  # 作成
  def new
  end

  # 登録
  def create
  end

  # 編集
  def edit
  end

  # 更新
  def update
  end

  # 削除
  def destroy
  end
```
Incompact3Dのインストールから実行

Incompact3D (Xcompact3D) のインストールは，基本的にリポジトリないしは先駆者の記事を参考に進めればよい．

しかしながら，事前に準備しなければいけないライブラリが存在しており，またIncompact3D自体がアップデートされた都合から，インストールを終えるまでに時間を要した．

エラーコードを丁寧に読んで調べれば解決できるし，OpenFOAMなどで慣れてる人にとっては取るに足らない問題かもしれないが，同じような問題にあたった方々のために備忘録として残す．

## OpenMPIの導入
並列計算の予定がなくともOpenMPIが導入されている必要がある．
導入方法は以下のURLの通りに実行していけばよい．

https://zenn.dev/ohno/books/356315a0e6437c/viewer/5a9c0c

## Incompact3dのソースコードを落としてくる

現在，Incompact3Dのバージョンはv4.1だったが，現時点でバージョンアップされてから2か月しか経過していない点や取り扱いが結構変わってる都合から，v4.0を導入したい．

v4.0を落としてくる方法は次の通り
```
mkdir Incompact3d
cd Incompact3d
git init
git remote add origin https://github.com/xcompact3d/Incompact3d.git
git fetch --depth 1 origin v4.0
git reset --hard FETCH_HEAD
```

## Incompact3dをコンパイルする
ソースコードを落としてきただけでは計算を実行できないため，コンパイルを行う．
コンパイルはシンプルに以下のコマンドで実行される．
```
make
```
あまりに貧弱スペックなノートPCでもなければ，数分でコンパイルは終わる．

## 以下、こちらの記事を見て例題ケースを試してもらえれば…
「例題計算(taylor-green-vortex)の実行」から以下を参照
ここまでくれば引っかかることはそんなにないかなぁと思います．

https://qiita.com/yotakagi77/items/b6b66348017d63b1372d#%E4%BE%8B%E9%A1%8C%E8%A8%88%E7%AE%97taylor-green-vortex%E3%81%AE%E5%AE%9F%E8%A1%8C

## 諸言
以上，先駆者のインストール手順記事に捕捉する形で記載してみました．
慣れた人にとっては取るに足らない内容なはずなんですが、研究を始めたばかりの学部4年や修士1年の人を中心とするUbuntu初心者には苦労する部分もあるかなぁ…と思ったので記事化してみました．

#### 引用一覧
https://github.com/xcompact3d/Incompact3d (GitHub - xcompact3d/Incompact3d: Current CPU version of our solver for the Navier-Stokes equations)
https://qiita.com/yotakagi77/items/b6b66348017d63b1372d (Xcompact3d(Incompact3d)をインストールして使ってみる #OSS - Qiita)
https://zenn.dev/ohno/books/356315a0e6437c/viewer/5a9c0c (OpenMPI｜計算科学のためのWindowsセットアップ)
https://yo.eki.do/notes/git-only-single-commit/ (コミット・タグを指定してその時点でのツリーだけをgit cloneしてくる)
サブドメインにWordPressで開発環境を構築する

## はじめに

ホームページの改修などの際にいきなり本番環境で行うと、予期せぬ影響が出てしまうことがあるので今回WordPressの開発環境をサブドメインで構築します。

## 動作環境
+ MacBook Air M1 2020
+ Xserver
+ WordPress　

## 作業手順
1.　サーバでサブドメインを設定する

2.　サブドメインにWordPressをダウンロードする

3.　本番環境のファイルをアップロードする

【対処法】ファイルがうまくアップロードされない

4.　サブドメインでちゃんと表示されるか確認する

【対処法】　固定ページが表示されない

5.検索エンジンにインデックスされないようにする

## 1.サーバでサブドメインを設定する

Xserverレンタルサーバー＞サーバー管理＞サブドメイン設定＞ドメインを選択＞サブドメイン設定追加＞サブドメイン名を入力して追加します。

サブドメインを作成すると本番環境/public_html直下に作成したサブドメインのフォルダが作成されます。

## 2.サブドメインにWordPressをダウンロードする

サーバー管理＞WordPress簡単インストール＞ドメインを選択＞WordPressインストール＞設定対象ドメインを選択します。

ブログ名・ユーザー名・パスワードなどを入力してインストールします。

WordPressがインストールされると、サブドメインのフォルダの中にWordPressのファイル構造が作成されます。

## 3.本番環境のファイルをアップロードする

今回はホームページのテーマのファイルのみをアップロードします。

テーマファイルはドメイン名＞public_html＞wp-content＞themesの中に入っています。

**サブドメインで構築するには、public_html直下のサブドメインのフォルダ＞public_html＞wp-content＞themesの中にアップロードします。**

ファイルのアップロードはXserverのファイルマネージャから行いました。

この時アップロードする階層まで移動してからアップロードボタンを押します。

ボタンを押すとこの画面が出てきます。
![スクリーンショット 2024-02-24 16.34.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3721753/0231c42b-99f7-944a-bbf0-8bf8ebfbabfd.png)

（フォルダを選択）を押してフォルダをアップロードしました。

### 問題
しかし、アップロードされたファイルは想定と違いました。

フォルダが丸ごとアップロードされると思いましたが、実際はそのフォルダに含まれているいくつかのファイルしかアップロードされませんでした。

その後何度かやり直し、似たような問題の検索も行いましたが解決方法が根本的な原因の解決には至りませんでした。

### 対処法
この問題を解決するために手作業でファイルをアップロードしました。

下の階層のフォルダ作成し、その中にファイルをアップロードしました。

まとめて選択してアップロードするとファイルは一部抜けた状態でアップロードされるので、アップロードされたものとローカルのファイルとで見比べて抜けているものを再びアップロードしました。

この時テーマのフォルダのみの構築だったので手作業で出来ましたが、もっと大きいフォルダをアップロードする時に手作業は時間が掛かりすぎるので、次の機会までに原因解明をしたいと思います。

## 4.　サブドメインでちゃんと表示されるか確認

アップロードが完了したらサブドメインで実際に表示されるか確認します。

確認するとしっかりトップページが表示されました。

### 問題
しかし動作を確認すると、他のページへのリンクを押すと全てトップページに遷移されるという問題が発生しました。

アップロードしたファイルの内容は一切変更しておらず、リンク先も正しいことを確認しました。

### 対処法

表示したいファイルの冒頭に下記の記述をします。

```
<?php
/*
Template Name: ファイル名
*/
?>
```
その後WordPressの固定ページでテンプレートを指定します。

この作業によって全てのページが表示されるようになりました。

## 検索エンジンにインデックスされないようにする

このままでは同じサイトが2つある状態になり、SEOに影響が出てしまうのと開発中の環境が誰でもアクセスされるとセキュリティ的に危険なのでサブドメインがインデックスされないようにします。

Xserverのサーバーパネル＞アクセス制限からユーザーIDとパスワード設定すると簡単にアクセスを制限できます。

## おわりに
今回サブドメインでWordPressの環境を構築してみました。

WordPressを触るのが初めてだったのでわからないことだらけでしたがとても勉強になりました。

### 参考文献
[特定の固定ページのみデザインを変えたい！ページテンプレートを作成する方法](https://site-manage.net/archives/2275)

[WordPress のテスト環境を作るのは超簡単【Xサーバー】
](https://lunalunadesign.net/2021/07/1872/)
【目指せトップYouTuber】AmiVoiceを使って 動画に字幕を付けよう

## プロローグ
これはとある人物の物語である。

「そうだ、トップYouTuberになろう。」
…神のお告げにより彼はトップYouTuberを目指すのであった。

しかし彼には１つ問題がある。
彼には時間がないのだ。

彼は日中、普通に仕事をしているので、
Qiitaの記事を書く時間どころか動画編集する時間もないのだ。

どうしよう…彼は思い悩んだ。

そんな時、神は一言こう言った。
「……AmiVoice API。」

彼はハッとした。
そうか、私には**AmiVoice API**があるじゃないか。
動画を読み込ませて自動で文字起こししてくれるようなアプリを自作すればいいじゃないか。

※イメージ：　動画を読み込む　→　音声のみ抽出　→　文字情報に変換

彼は机の上に置いてあった無料利用クーポン（5/21まで）を握りしめ、
文字起こしアプリの開発に移るのであった。

## 作業工程

### 1. Amivoice APIの登録
まず以下のサイトにアクセスした。
メールアドレスの登録、個人情報の登録、クレカ情報の登録の3ステップで
APIが利用できるようになった。

https://acp.amivoice.com/blog/qiita_api240424/

### 2. WPFでインターフェースを作成する
次に自分のやる気を出すために、それっぽい画面を作成することした。
今回は以下のサイトの画面レイアウトを真似させていただいた。（彼には時間がないのだ）

https://resanaplaza.com/2023/06/24/%E3%80%90%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E6%BA%80%E8%BC%89%E3%80%91c%E3%81%A7%E5%8B%95%E7%94%BB%E5%86%8D%E7%94%9F%E3%81%97%E3%82%88%E3%81%86%E3%82%88%EF%BC%81%EF%BC%88mediaelement%EF%BC%89/

既にあるMediaElementを画面左側に移動させ、新たにTextBoxを画面右側に追加した。

![VideoEditor画面レイアウト.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/15ca0edc-cd8f-d12e-3eb3-59a7c7c625e0.jpeg)


### 3. C#を使ってAmivoice APIを実行する
AmiVocie公式が出している記事を参考にMainWindow.xaml.csに組み込んでいく。
※この時点でダウンロード可能なプログラムやソースコードが記事に載っていることに気付いてしまったが、今回は都合が悪いので無視することにした。

APIの実行結果をTextBoxに表示するようにすればアプリの完成である。

https://acp.amivoice.com/blog/2022-02-21-111343/

### 4. デモ（画像のみ）

完成系はこちらである。

…本当は早口言葉を撮影したデモ動画をお見せしたかったが、
画像以外のファイルを埋め込められないことにQiitaの記事を書いている最中に気づいた。
大変申し訳ない気持ちでいっぱいである。

一応、左下の「フォルダ」アイコンから動画を選択すると
その動画内で喋った内容がTextBoxに表示されるようになった。

音声認識の精度が高いのはもちろんのこと、
API内で**識別する話者の数**も設定できるのでコラボ撮影時に使えると思った。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/66591bd5-6062-5e43-f2db-1854d75c2cc0.png)

## エピローグ
その後、彼は一心不乱に動画を撮影した。
文字起こしは自作のアプリに任せ、次々にYouTubeに動画をアップロードしていった。

そして数年後…

彼は原宿を歩いていた。
彼の周囲の人はざわめく。その中の一人が彼に近づきこう尋ねた。
「すみません、もしかしてトップYouTuberのヒ○キンさんですか？」

おしまい。
※この物語はフィクションです
[Swift] StringとかのSubscriptで0, 1, 2, ...を使いたい！

# 結論
無理です。

# 無理でも
なのでその手助けをする新しいstructを作ります。

## ずばっとソース
以下です。
```swift
struct NormalizedIntIndexCollection<Base: Collection>: RandomAccessCollection {
  
  let base: Base
  
  let startIndex = 0
  let endIndex: Int
  
  init(_ base: Base) {
    self.base = base
    self.endIndex = base.count
  }
  
  subscript(_ index: Int) -> Base.Element {
    let i = base.index(base.startIndex, offsetBy: index)
    
    return base[i]
  }
}
```
## 使い方
極めて簡単です。

```swift
let str = "Hello World!"

let c = NormalizedIntIndexCollection(str)

print(c[4])
// prints o
```

簡単ですね。

## Normalizedって？

実はIndexがIntでないCollection以外でもNormalizedIntIndexCollectionはすごく便利です。

### ArraySliceの罠
```swift
let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let slice = array[2...6]

print(slice[0])
// Crushed. Out of Range
```
やっちゃいますねー。
こういうときもNormalizedIntIndexCollectionの出番です。

以下ソース
```swift
let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let slice = array[2...6]
let c = NormalizedIntIndexCollection(slice)

print(c[0])
// prints 2
```
Normalizedです！

## ほかにも
僕の中で先日話題沸騰となったLazyFilterSequenceにももちろん使えます！

```swift
let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let filtered = array.lazy.filter { !$0.isMultiple(of: 2) }

print(filtered[0])
// prints 0

let c = NormalizedIntIndexCollection(filtered)

print(c[0])
// prints 1
```

やったね！

## もうちょっと使いやすく

Collectionにextensionを付けます。
```swift
extension Collection {
  var normalizedIntIndexed: NormalizedIntIndexCollection<Self> {
    NormalizedIntIndexCollection(self)
  }
}
```

これを使うと
```swift
let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let filtered = array.lazy.filter { !$0.isMultiple(of: 2) }

print(filtered.normalizedIntIndexed[0])
// prints 1

print("Hello World!".normalizedIntIndexed[6])
// prints W
```

...便利？

## まとめ

直接整数インデックスでアクセスするのは無理なので、別途補助タイプを用意するしかありません。
今回用意した補助タイプはオリジナルのCollectionをプロパティに持つことで新しくArrayなどを生成するコストはかかっていません。
なお、必要最低限の実装しかしてませんので、場合によっては無駄なコストが発生します。いい感じにfixしてやってください。

あと、**名前が長すぎる**
Docker内で「ProfileNotFound(profile=profile_name) botocore.exceptions.ProfileNotFound: The config profile (xxxxx) could not be found」が出た時の対処法

## 概要

ローカルで起動したコンテナ内からboto3を使用しようとしたら、表題のようにプロファイルが存在しないエラーが出て、少しハマったので、記録として残しておく。


## ハマった流れ

ローカル環境でDynamodbローカルを使用しようと思い、Dockerを構築した。
コンテナの起動がうまくいき、Dynamodb　Adminなどにもアクセスできたから、「よし、boto3でDynamodbにCreateTableしてみよう」と思い、boto3のsessionを下記のとおり作成した。
```python
session = boto3.session.Session(profile_name=settings.AWS_PROFILE)
```

そしたら、Dockerに怒られてしまった。
```sh
raise ProfileNotFound(profile=profile_name) botocore.exceptions.ProfileNotFound: The config profile (xxxxx) could not be found
```

エラー内容を見ると、 `.aws/credentials`に、指定されたプロファイル名が無いみたいなエラーだったため、ちゃんと環境変数に登録したプロファイル名と同等のプロファイル名がcredentialsファイルの中に記載されているかを確認した。
すると環境変数に記載してあったプロファイル名が記載されていた。。。


## 解決

imageをbuildしなおしたりコード変えたり色々試したけど一向にエラーが変わらない、、、ってなったのでもうDockerの中からホストマシーンに登録されたファイルが参照できてないのでは？？っていう仮説に辿り着きました。

そして色々調べてみると、やはり仮説は当たっており、コンテナのボリューム内にホストマシーンのcredentialsファイルをマウントしてあげる必要があることがわかりました（よく考えればそうだような、、、って思いました）
この方の[記事](https://zenn.dev/ibaraki/articles/4189b05c7abd6c)が参考になります。
```yaml
  volumes:
    - $HOME/.aws/credentials:/root/.aws/credentials:ro
    - $HOME/.aws/config:/root/.aws/config:ro
```
上記の通り、composeファイル内に記載して、コンテナを起動したら、プロファイルが存在しないエラーが消え、無事boto3のセッションを作ることができました。

## まとめ
自身が使用しているツールの基礎知識をしっかり理解しておけば、調査に必要以上に時間を取られることがなかったなぁと反省しているのと、Dockerが勝手に認証情報などを参照できないようになっていることを知り、改めて独立した実行環境なんだなぁと実感しました。

あとこの記事を記載した理由は、表題のエラー内容で検索したら添付している方のリンクに全然辿りつかず、時間を要したため、同じような方がいた際に一助になるかと思い書きました。誰かのためになれば幸いです。
sidekiq-cron で設定した定期実行処理が schedule ファイルから削除しても停止しない

[sidekiq-cron](https://github.com/sidekiq-cron/sidekiq-cron) で動かしていた定期実行ジョブを停止しようと際に詰まったので備忘録。

## 背景

```rb:config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
  config.on(:startup) do
    schedule_file = "config/schedule.yml"

    if File.exist?(schedule_file)
      schedule = YAML.load_file(schedule_file)

      Sidekiq::Cron::Job.load_from_hash!(schedule, source: "schedule")
    end
  end
end
```
```yml:config/schedule.yml
test_hello_world:
  cron: "*/1 * * * * " #　1分ごとに実行
  class: "HelloWorldWorker"
  queue: "schedule"
  description: "1分に1回 Hello World! を出力します。"
```

```diff:config/schedule.yml
-  test_hello_world:
-    cron: "*/1 * * * * " #　1分ごとに実行
-    class: "HelloWorldWorker"
-    queue: "schedule"
-    description: "1分に1回 Hello World! を出力します。"
```

上記のように、もともと設定されていたスケジュールを削除しても定期実行処理が停止しないという現象に遭遇。

```rb
Sidekiq::Cron::Job.find("test_hello_world")
=> #<Sidekiq::Cron::Job:xxxxxxxxxxxxxxxxxx
 @active_job=false,
 @active_job_queue_name_delimiter="",
 @active_job_queue_name_prefix="",
 @args=[],
 @cron="*/1 * * * * ",
 @date_as_argument=false,
 @description="1分に1回 Hello World! を出力します。",
 @errors=[],
 @fetch_missing_args=true,
 @klass="HelloWorldWorker",
 @last_enqueue_time=nil,
 @message="{\"queue\":\"schedule\",\"class\":\"HelloWorldWorker\",\"args\":[]}",
 @name="test_hello_world",
 @parsed_cron=#<Fugit::Cron:xxxxxxxxxxxxxxxxxx @cron_s=nil, @day_and=nil, @hours=nil, @minutes=nil, @monthdays=nil, @months=nil, @original="*/1 * * * * ", @seconds=[0], @timezone=nil, @weekdays=nil, @zone=nil>,
 @queue="schedule",
 @queue_name_with_prefix="schedule",
 @source="dynamic",
 @status="enabled",
 @symbolize_args=false>
```

↑ Sidekiq を再起動してもまだ残っている

## 原因および解決方法

https://github.com/sidekiq-cron/sidekiq-cron?tab=readme-ov-file#destroy-jobs

```rb
# destroy all jobs
Sidekiq::Cron::Job.destroy_all!

# destroy job by its name
Sidekiq::Cron::Job.destroy "Job Name"

# destroy found job
Sidekiq::Cron::Job.find('Job name').destroy
```

上記の通り、Job を `destroy` しないとダメだったらしい。（schedule ファイルから削除するだけでは不十分？）

```rb
Sidekiq::Cron::Job.find("test_hello_world").destroy
2024-05-17T08:01:05.754Z pid=243 tid=5tb INFO: Cron Jobs - deleted job with name: test_hello_world
=> 99

Sidekiq::Cron::Job.find("test_hello_world")
=> nil
```

↑無事消えた。

GUI で操作したい場合、下記のようなルーティングを設定することで Sidekiq ダッシュボード（`/sidekiq`）内に「cron」タブが現れるので、そちらから無効化/削除も可能。

```rb
require "sidekiq/web"
require "sidekiq/cron/web"

Rails.application.routes.draw do
  mount Sidekiq::Web, at: "/sidekiq"
end
```

![スクリーンショット 2024-05-17 17.07.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688854/67d6ef6b-3dce-d10b-0e01-2725c8ebc6dc.png)
【VPS】【nginx】人生で初めてVPSを借りてブラウザ表示しようとした時につまづいた事とやってみた感想

## はじめに
　今回は冬休みにインターンでサーバーサイドに関することを学んだので実際にVPSを借りて試してみようと思い始めました。社員さんの方からVPSを勧められ使ったことはありませんでしたがブラウザ表示するところまでできたので、その時につまづいた事や感想を記載していこうと思います。

 ## さくらVPS
　今回はさくらインターネットさんのVPSを使用しました。公式で契約するところからwordpressをブラウザ上で表示するところまでをイラスト付きで説明されていたので周辺知識を整理しながら実行できたので困った時に見る記事としてとてもありがたかったです。
[さくらのVPS講座](https://knowledge.sakura.ad.jp/7938/?_gl=1*yisdjm*_gcl_aw*R0NMLjE3MTU4NDEzMjkuQ2p3S0NBand1cEd5QmhCQkVpd0EwVWNxYUd5Y250SmdYd1ZPdVQyMWRickdEbFZVTEVaR19wZXdTOTYybXZhMWxkbDEza1JuSWtLcGRob0NCWXNRQXZEX0J3RQ..*_gcl_au*MTIzNzgzNTAwMS4xNzE1ODQxMjQ0)
　記事ではサーバーOSに**centos**,httpサーバーアプリケーションに**Apach**を使用されていましたがインターン先で**ubuntu**や**nginx**を使用していたのでそちらを使用しました。
 ## つまづいた事
 nginxをインストール後ブラウザ上でIPアドレスを入力し以下の画面を見たかったのですが表示できませんでした。
 ![スクリーンショット 2024-05-16 20.43.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554505/1e5327e5-9804-8b6f-6e48-d21f22f2e128.png)

## 試したこと
　「さくらのVPS記事」ではファイファーウォールの設定を行っていたので以下のコマンドを叩きポートの解放を行いましたがうまく表示できませんでした。
 ```
$ firewall-cmd --add-service=http --zone=public --permanent
 ```
※うまく表示した後このポートの開け閉めで実際に表示の可不可を実感できたのはよかったです。

## 原因の解明
　さくらVPSにはブラウザ上で操作できるサーバーのコントロールパネルがありサーバーの各種設定や一覧などが行える便利な機能があります。デフォルトではフィルターがかかっており**SSH接続のみ許可がされている**状況だったためブラウザで表示しようとしてもできなったみたいです。初めてVPSを使用したのでサーバーの設定を全てコマンド上で行えると勘違いしていましたが今度からは公式に用意してもらえているコントロールパネルなども注意してみようと思いました。

 ## 初めて契約してみた感想
 　社員の方からお薦めされた時、一瞬学習の一環で有料のサーバーを借りることはお金がもったいないと思っていましたが仮想マシン上にサーバーをたて、localhost:~でブラウザ表示するよりスマホからもアクセスできるなどの**本物感**（実際にサーバーを扱ってる！！！）を味わうことができたので良かったです。自分のマイカー、マイホームをもった時もこんな感覚なんだろうなと思いました。
　レンタルサーバーとは違ってVPSだど自分で必要なパッケージを選択したりその都度installしたりするなど自分で管理している感覚を持てたり今まではブラックボックスだったサーバーを実際に触って理解できたりと社員の方がおすすめするのもわかる気がしました。
Reactで個人開発 ビジネスマッチングアプリ③

# 進捗
[前回の記事](https://qiita.com/urakata_engineer/items/f7665dee5ad9d56451a8)から変わった部分はあまりありません。

というより、画面はほとんど実装していません。

今回は、フロントエンドから呼び出すAPIをバックエンドで管理するため、

Laravel 11系を使って環境を作りました。

これを終えると、いよいよログイン認証まわりを作っていこうかと思っています。

（Auth0を使用する予定）

# 手順
①Laravelプロジェクトを作り、

②テーブルを作成し、

③カールを叩いて疎通確認。

④その後、フロントエンドから呼び出せることを確認して完了

という流れです。


## ①Laravelプロジェクト作成
※Composer入っていること前提です。
```bash
composer create-project --prefer-dist laravel/laravel my-project
```

## ②テーブル作成
ローカル環境のDBに接続し、migrationを使ってテーブルを作成します。

まずは.envを自身のローカル環境に設定。

その後、migrationを使って、テーブルを新たに作成。

```bash
php artisan make:migration create_tags_table --create=tags // マイグレーションファイルが作成されるのでカラム追加する

php artisan migrate
```

テーブル作成されていることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3511372/f6558d7b-e2be-a5bf-1588-5e13b2bc5c27.png)

## ③カールを叩いて疎通確認
ローカルのサーバーを立ち上げて疎通確認を行う。

```bash
php artisan serve // これでサーバが立ち上がり、http://127.0.0.1:8000でリッスンされる
```

テストコントローラを作成し、GETのAPIを作ってみる。
```bash
php artisan make:controller Api/TestController // コントローラーのテストメソッドを一つ作ってみる
```

別シェルで呼び出してみる（今回はTestControllerにtestというメソッドを作りました）
```bash
curl http://localhost:8000/v1/test

{"message":"\u30c6\u30b9\u30c8\u30b3\u30fc\u30c9\u3067\u3059","number":0}
```
文字列と数値を返すAPIを用意しました。文字列がエスケープしていますが、ちゃんと帰ってくることを確認できます。

## ④フロントエンドから呼び出せることを確認して完了
いよいよ、フロントエンドからこれを呼び出す準備をします。

まず、APIを呼び出すためにaxiosをインストールします。

```bash
npm install axios
```

ライブラリを追加したら、.envに環境変数を定義します。
```env
REACT_APP_API_URL=http://localhost:8000/v1
REACT_APP_OTHER_VARIABLE=some_value
```

最後にAPIを呼び出す処理を書き、疎通確認を行います。
（ある程度コード割愛していますし、インデントがずれちゃってます）
```JavaScript
import React, { useEffect } from 'react';
import axios from 'axios';

function App() {
    useEffect(() => {
    const fetchData = async () => {
      try {
        console.log('API疎通確認');
        const res = await axios.get(`${process.env.REACT_APP_API_URL}/test`);
        console.log(res);
      } catch (e) {
        console.error(e);
      } finally {
        console.log('API疎通完了');
      }
    };

    fetchData();
  });
  
~~~

}
```

ちゃんとブラウザでAPIレスポンスを取得できることを確認できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3511372/bc2514e5-815c-888e-259c-e14a40a91f6c.png)


# CORSエラーについて
フロントエンドからバックエンドにAPIをリクエストする際、

オリジンが異なる、すなわち別のリソースへアクセスする場合、

CORSエラーが発生します。

[CORSとは？（参照先）](https://qiita.com/higakin/items/fabe6a23d564b20ad558)

:::note info
ブラウザはSORS(Same-Origin Resource shareing)という仕組みを実装していて、異なるオリジン（Cross-origin）間へのリソースへのアクセスを制限しています。
なぜ、制限しているかというと、クロスサイトサージェリーなどのセキュリティ攻撃を防止するためです。
で、CORS(Cross-origin resource sharing)が何なのかというと、このSORSの制約を一部解除することで異なるオリジンへのリソースのアクセスを許可したものです。
:::

バックエンドAPIのレスポンスヘッダーに情報を加えることで解決できるようですが、

一時的な解決方法として私は、CORSエラーを無視するChrome拡張機能を使用しました。

- [CORS Unblock](https://webextension.org/listing/access-control.html)
Qiskit 1.0のインストール手順 (Windows版)

[Qiskit 1.0](https://www.ibm.com/quantum/qiskit) をWindowsにインストールします。（macOS版は[こちら](https://qiita.com/kifumi/items/8f3617051635f986cc5f)です。）
[公式インストール手順](https://docs.quantum.ibm.com/start/install)をもとに行います。

注意点：以前のバージョンのQiskitをご自身の環境にインストールしたことがある方は、上書きアップグレードをしないでください。エラーが発生しやすくなります。


# 0. 「Python」のインストール
こちらのページ[「Windows版Pythonのインストール」](https://www.python.jp/install/windows/install.html)を参考に、Pythonをインストールします。

# 1. 「PowerShell」を起動
以下の操作で、「Windows PowerShell」を起動します。
- 画面左下の[スタート] メニューを開き、「Windows PowerShell」と入力し、[Windows PowerShell] を選択した後、[開く] を選択します。

# 2. Pythonの新しい仮想環境を作成する
以下のコマンドで `qiskit_env` の部分にご自分の使いたい仮想環境名（ディレクトリー名）と必要であればそのパスを入れ、実行します。

```
python -m venv qiskit_env
```

# 3. 仮想環境をActivateする
以下のコマンドで `qiskit_env` に作成した仮想環境名を入れて実行します。
```
qiskit_env\Scripts\Activate.ps1
```
正しく仮想環境に入れていれば、以下の図のように、PowerShellのコマンドラインの左端に作った仮想環境名が `(仮想環境名)` という状態で現れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151117/2894e5a6-e6b0-19ad-29e0-609489c3bb5c.png)


# 4. pip のインストール
[pip](https://pip.pypa.io/en/stable/installation/)がインストールされているか確認します。
```
pip --version
```
インストールされている場合は、以下のようなメッセージが出ます。
```pip 24.0 from C:\Users\...\qiskit_env\Lib\site-packages\pip (python 3.12)```
インストールされていない場合は、以下のようなメッセージが出ます。
```'pip' is not recognized as an internal or external command, operable program or batch file.```
インストールされていなかった場合は、以下のコマンドでpipをインストールします。
```
py -m ensurepip --upgrade
```

# 5. Qiskit のインストール
以下のコマンドでQiskitをインストールします。
```
pip install qiskit
```
# 6. 必要なライブラリーをインストール
Qiskit本体以外に必要となるライブラリーをインストールします。
```
pip install qiskit-ibm-runtime jupyter qiskit-aer qiskit[visualization]
```

# 7. Qiskit で Hello world
続けて、QiskitのHello worldを実行して、Qiskitが正しく動くか確認してみましょう。
以下のコマンドで、Jupyter notebookを立ち上げます。
```
jupyter notebook
```
以下のようにEdgeなどのウェブブラウザーが起動します。右上の「New」をクリックし、「Python 3」を選んで、新しいNotebookを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151117/ede8f62f-ce17-95b1-c774-48b720567093.png)


[公式QiskitドキュメントのHello world](https://docs.quantum.ibm.com/start/hello-world) から最初のセルのコードをコピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151117/f28ca8d6-99ac-e749-2fa6-daaaf1632445.png)

自分のNotebookのセルに貼り付けます。「Shift」+「Enter」かまたは、上の方にある右向き三角アイコンで実行できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151117/7ceccdb1-66eb-80ee-3a35-d1dffbab177f.png)

正しくQiskitが動いている場合、以下の回路図が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151117/ff7df460-6907-9956-fb16-27f7c22a79df.png)

ファイルを閉じるには、左上の「File」→「Close and Shut Down Notebook」→「Ok」で終了できます。
Jupyter notebookの環境を修了するには、PowerShellに戻り「Ctrl」+「c」を押します。
PowerShellで以下のコマンドを実行すると、仮想環境から抜けることができます。
```
deactivate
```

# 8. インストール後、再度、Qiskitを使う時
次にQiskitを使う時は、以下のようにしてください。
### 1. PowerShellから仮想環境の立ち上げ
```
qiskit_env\Scripts\Activate.ps1
```
### 2. Jupyter notebookの立ち上げ
```
jupyter notebook
```
ここで新しいPython3のNotebookを立ち上げて、Qiskitを使うことができます。

### 3. Jupyter notebookの終了
必要なNotebookをSaveした後、PowerShellで「Ctrl」+「c」。
### 4. 仮想環境の終了
```
deactivate
```

以上です。お疲れ様でした！
ワイ専用のタスク管理アプリを作りました

## 初めに
https://qiita.com/G_R_/items/83f39cc9fdac7014f688

上のページで求めていたタスク管理アプリを探したのですが、結局見つからなかったので作成し始めてみました。
MVPが完成したので機能を紹介したいと思います。
## 全体像
![Todo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429048/ec2e1836-a8d1-45cf-fb24-0bea7975c0ce.gif)

左側がカンバン、右側に一日のタイムスケジュールを表示しています。

### 機能１：タスクのタイムボックスを設定できる
タスクの想定作業時間を設定することが出来ます。
タスクを追加するときの左右ボタンはデフォルトのタイムボックスが異なっており、
左は15分のタスク、右は45分のタスクです。
もちろんタスクを追加してから見積もり時間を変更することも可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429048/9385051d-a822-32f9-333b-d4ab03125bbb.png)

:::note info
この機能により、 一日の作業ボリュームを把握し、**計画しやすくなります**
:::

### 機能２：タスクの実施日時を設定できる
タスクの作業予定日時をYYYY/MM/DD HH:MMまで設定できます。
右のタイムスケジュールでドラッグしても良いですし、カンバンからカレンダーで設定することもできます。

_カンバンで設定する場合_
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429048/9a890995-8594-aabd-cb78-04497b7bd93e.png)

:::note info
この機能により1日の計画を立てることで今以降の作業を気にするがなくなるため、**目の前の作業に集中できます**
:::

### 機能３：タスクの実作業時間を可視化できる
タスクを進行中に動かすと、タスクカード下部のバーが青くなっていきます。
想定作業時間を超えると今度は赤くなっていき、想定作業時間の二倍の時間作業をしていると全てが赤くなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429048/2028c38c-d491-eb9b-7147-b7135c050870.png)

:::note info
この機能により**時間を意識してタスク作業を行うことになり生産性がUPします**
:::

### 機能４：ネットワーク通信なし
データはローカルに保存しており、ネットワーク通信は発生していません。
機密情報が知らぬサーバ上に保存される、なんてことはありません。

### 細かい機能
- タスクをクリックすることでモーダルウィンドウが開き、タスク詳細を参照更新できます
- カンバンとタイムスケジュールの境界は左右に移動できます
- 開始日時が設定されていないタスクを計画済みに移動すると「今の日付＋5分後」でデフォルト設定します
- タスクを完了に移動するとタイムスケジュール上のタスクもグレーアウトします
- タスクを右クリックすることでタスクの表示色を変更できます
    - 例えば作業と打ち合わせで表示を分けたいときに有効

## 実装したけど削除した機能
- タイムスケジュール上でタスクの予定開始時間を変更すると、後続のタスクも全てずれる
    - 打ち合わせの時間変更などで時間が変わった時、全てのタスク開始時刻がズレてしまうため削除
- 45分以上のタスクが連続している場合、タスクの切れ目で15分の空き時間を自動で設定される
    - 私には15分の空き時間なんてなかったため削除

## 終わりに
気が向いたら設計・実装編をアップします。
更に気が向いたら機能をアップデートします。
Htmlで雛形を生成した時のlangの標準をjaにする

# 雛形とは
htmlで`html:5` か `!`と入力してEnterまたはTabを押すと、htmlの基礎構文がでてきます。
![スクリーンショット 2024-04-17 10.50.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3714044/4794118d-1ecc-8b49-e662-7be380ca6382.png)

これの、`<html lang="ja">`の部分が標準では`en`になっているため、いちいち`ja`に変更するのがめんどくさい...

ということで、これの設定を変えようっていう内容です！

# 設定方法
VSCodeを開いた状態で、 `command + ,`(windowsの場合は`ctrl + ,`)ショートカットを実行します。
検索欄に「variables」と入力し、検索すると以下のようなものが出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3714044/1cb53941-d7d8-76e1-f43a-71c28914e9fe.png)

lang項目の値を`ja`に変更することで、自動的にhtmlのlang属性も`ja`に変更させることができます！

今回は`ja`でしたが、他にも`en`や`es`など、多言語も指定できます！
言語コード一覧はこちらを参考にするといいかもです！

[https://www.kanzaki.com/docs/html/lang.html](https://www.kanzaki.com/docs/html/lang.html)
プロセスの関係、状態、終了

# 親が子を生成し、木構造になる
```
systemd(1)-+-ModemManager(605)-+-{ModemManager}(625)
           |   
           ....
           |               |-gnome-terminal-(2427)-+-bash(2438)---su(2449)---bash(2450)---pstree(2535)
...
```
pstreeコマンドを使えば```プロセスの親子関係を木構造で表示```してくれます。
pstreeは、デフォルトでは```コマンド名だけ```を表示するのですが、-pオプションをつけて```PID```も表示するようにしておくと便利です。
# 出典
https://gihyo.jp/book/2022/978-4-297-13148-7
# ps auxでプロセス全ての情報を取得する
```
root@***********# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.3  0.3 103512 13148 ?        Ss   16:59   0:02 /sbin/init s
...
root        3911  0.0  0.0   9920  3288 pts/0    R+   17:13   0:00 ps aux
```
### 気づき
STAT プロセスの状態がRは実行状態、Sはスリープ状態
一つずつのプロセスの状態がわかる。

### オプション
```
R    running or runnable (on run queue)
S    interruptible sleep (waiting for an event to complete)
...
s    is a session leader
+    is in the foreground process group
```
# 出典
man ps
# プロセスの終了
親のシステムコールで子のプロセスのメモリを回収する
```
#!/bin/bash
false &
wait $!
echo "falseこまんどが終了しました: $?"
```
falseプロセスの終了を待ち合わせる。falseコマンドのPIDは$!変数から得られる
wait後にfalseプロセスの戻り値は$?変数から得られる
# 出典
https://gihyo.jp/book/2022/978-4-297-13148-7

これらのシステムコールはいずれも、呼び出し元プロセスの子プロセスの  状態変化を待ち、状態が変化したその子プロセスの情報を取得するのに 使用される。
### 出典
https://manpages.ubuntu.com/manpages/focal/ja/man2/wait.2.html#:~:text=%E3%81%93%E3%82%8C%E3%82%89%E3%81%AE%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%B3%E3%83%BC%E3%83%AB%E3%81%AF%E3%81%84%E3%81%9A%E3%82%8C%E3%82%82%E3%80%81%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97%E5%85%83%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%81%AE%E5%AD%90%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%81%AE%20%20%E7%8A%B6%E6%85%8B%E5%A4%89%E5%8C%96%E3%82%92%E5%BE%85%E3%81%A1%E3%80%81%E7%8A%B6%E6%85%8B%E3%81%8C%0A%20%20%20%20%20%20%20%E5%A4%89%E5%8C%96%E3%81%97%E3%81%9F%E3%81%9D%E3%81%AE%E5%AD%90%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%81%AE%E6%83%85%E5%A0%B1%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B%E3%81%AE%E3%81%AB%20%E4%BD%BF%E7%94%A8%E3%81%95%E3%82%8C%E3%82%8B%E3%80%82

# 気づき
このスクリプトが親でfalse＆が子のプロセスなのか。
子がスリープ状態になったからwaitで取得できてその後のechoもできるのか。
システムコールは凄そう
PartytownのCROSエラー回避

Partytownを使っている。
下記のURLを参考に設定するも、あるときから、ブラウザのコンソールに
あるときからgoogle analyticsのCORSエラーが発生。
https://nystudio107.com/blog/creating-a-reverse-proxy-for-partytown-with-aws-cloudfront

SimpleCORSの設定が悪さをしていたようで、
カスタムレスポンスヘッダーを作成し、そのカスタムレスポンスヘッダを対象の
ディストリビューションに設定したらうまくいった。
大体の項目をONにすればOK。

なぜ、あるときからエラーがでたのかは原因わからず。
Oracle RMAN使用まとめ

RMANバックアップを調べていくうちに頭が爆発しそうになったので自分の頭の整理のためにその仕様について(雑に)まとめました。
RMANバックアップにはいろんな種類がある。

・フルバックアップ
データファイル、制御ファイル、spfile等が含まれる。
増分バックアップのベースとしては使えない

・増分バックアップ：レベル0
フルバックアップと一緒、でも増分バックアップのベースにできる。

・増分バックアップ：レベル1
フルバックアップの差分。

・差分増分バックアップ
レベル0バックアップおよび前回のレベル1バックアップをもとに更新されたブロックをバックアップする。
累積増分バックアップと比べてファイルサイズは少なく、リストア時間は長い
redoログは最も新しく取得されたものを適用。

・累積増分バックアップ
常にレベル0のバックアップを参照し、更新されたブロックをバックアップする。
差分増分バックアップと比べてファイルサイズがでかく、リストア時間は短い。
redoログは最も新しく取得されたものを適用。

・増分更新バックアップ
rman側に常にレベル0と取得したレベル1を合わせたバックアップコピーを用意し、そこから更新されたものをバックアップして統合するを繰り返すバックアップ。
ファイルサイズも大きくなく、リストア時間も少ない。
コマンドは差分累積どっちでもよい。
redoログは最も新しく取得されたものを適用。

その他躓いたところ
・どのバックアップでもリストアコマンドは変わらない。
・list backupコマンドで表示されるフルバックアップは制御ファイル、spfileバックアップ（これらのバックアップには増分の概念がないのでフルと表示されるっぽい）
・二世代保存ポリシーを持っていてもアーカイブログのバックアップファイルが一部消される(1世代目以前のアーカイブログが不要と見做されるため。)
PlaywrightのDocker imageとactions/cache


Github Actions上で動くPlaywrightを少しでも早くするために、ブラウザを毎回インストールする方法からDocker imageを使う方法に変更しました。
imageのバージョンはpackage.jsonに記載しているバージョンと同じものにします。

(色々あってライブラリのインストールとテスト実行は別々のジョブにしている)

``` yaml
jobs:
  setup:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0
    - name: Cache node modules
      uses: actions/cache@v4
      id: cache-node-modules
      with:
        path: node_modules
        key: node_modules-${{ hashFiles('yarn.lock') }}
        restore-keys: node_modules-
    - name: Install dependencies
      if: steps.cache-node-modules.outputs.cache-hit != 'true'
      run: yarn install --frozen-lockfile

    test:
        needs: setup
+       container: mcr.microsoft.com/playwright:v1.43.1-jammy
        runs-on: ubuntu-latest
        steps:
        - uses: actions/checkout@v4
          with:
            fetch-depth: 0
        - name: Get node modules
          uses: actions/cache/restore@v4
          with:
            path: node_modules
            key: node_modules-${{ hashFiles('yarn.lock') }}
            restore-keys: node_modules-
        - name: Run Playwright tests
          run: |
            CI=true yarn run test
```

## なぜかキャッシュが見つからない
いざ実行するとキャッシュが見つからずコケてしまった…
```
Run actions/cache/restore@v4
  with:
    path: node_modules
    key: node_modules-xxxx
    restore-keys: node_modules-
    enableCrossOsArchive: false
    fail-on-cache-miss: false
    lookup-only: false
/usr/bin/docker exec  xxxxxx sh -c "cat /etc/*release | grep ^ID"
Cache not found for input keys: node_modules-xxxx, node_modules-
```
別のジョブではキャッシュを取得できたので、キャッシュはあるもののコンテナ内からなぜか取得できていない様子。

## 解決策
Playwrightとactions/cache両方のissueを読み漁ってやっと問題にたどり着きました。

actions/cacheではzstdが必須だが、PlaywrightのDocker imageには含まれていなかったのが原因でした。

ということでzstdをインストールするstepを追加して解決。
``` yaml
 test:
        needs: setup
        container: mcr.microsoft.com/playwright:v1.43.1-jammy
        runs-on: ubuntu-latest
        steps:
+       - name: Install zstd
+         run: |
+           apt-get update
+           apt-get install zstd
        - uses: actions/checkout@v4
          with:
            fetch-depth: 0
        - name: Get node modules
          uses: actions/cache/restore@v4
          with:
            path: node_modules
            key: node_modules-${{ hashFiles('yarn.lock') }}
            restore-keys: node_modules-
        - name: Run Playwright tests
          run: |
            CI=true yarn run test
```

インストールする分若干時間が延びてしまいますが、これで`npx playwright install --with-deps`を実行するより大幅に短縮できました。
エクセルメモ

```excel
=IF((E6 - D6) >= TIME(6, 0, 0),
    IF((E6 - D6 - TIME(0, 45, 0)) >= TIME(8, 0, 0),
        IF((E6 - D6 - TIME(0, 45, 0) - TIME(0, 15, 0)) >= TIME(8, 0, 0),
            E6 - D6 - TIME(0, 45, 0) - TIME(0, 15, 0),
            TIME(8, 0, 0)),
        E6 - D6 - TIME(0, 45, 0)),
    E6 - D6)
```
Qiskit 1.0のインストール手順 (macOS版)

[Qiskit 1.0](https://www.ibm.com/quantum/qiskit) をmacOSにインストールします。（Windows版は[こちら](https://qiita.com/kifumi/items/d36d0601d963a17bcf93)です。）
[公式インストール手順](https://docs.quantum.ibm.com/start/install)をもとに行います。

注意点：以前のバージョンのQiskitをご自身の環境にインストールしたことがある方は、上書きアップグレードをしないでください。エラーが発生しやすくなります。

# 1. 「ターミナル」を起動
以下のいずれかの操作で、「ターミナル」を起動します。
- DockでLaunchpadのアイコンをクリックして、検索フィールドに「ターミナル」と入力してから、「ターミナル」をクリックします。
- Finder で、「/アプリケーション/ユーティリティ」フォルダを開いてから、「ターミナル」をダブルクリックします。

# 2. Pythonの新しい仮想環境を作成する
以下のコマンドで `qiskit_env` の部分にご自分の使いたい仮想環境名（ディレクトリー名）と必要であればそのパスを入れ、実行します。

```
python3 -m venv qiskit_env
```

# 3. 仮想環境をActivateする
以下のコマンドで `qiskit_env` に作成した仮想環境名を入れて実行します。
```
source qiskit_env/bin/activate
```
正しく仮想環境に入れていれば、以下の図のように、ターミナルのコマンドラインの左端に作った仮想環境名が `(仮想環境名)` という状態で現れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151117/7525a607-c6c4-7b82-98b9-4fa785aae442.png)

# 4. pip のインストール
[pip](https://pip.pypa.io/en/stable/installation/)がインストールされているか確認します。
```
pip --version
```
インストールされている場合は、以下のようなメッセージが出ます。
```pip 24.0 from /Users/../../qiskit_env/lib/python3.12/site-packages/pip (python 3.12)```
インストールされていない場合は、以下のようなメッセージが出ます。
```zsh: command not found: pip```
インストールされていなかった場合は、以下のコマンドでpipをインストールします。
```
python3 -m ensurepip --upgrade
```

# 5. Qiskit のインストール
以下のコマンドでQiskitをインストールします。
```
pip install qiskit
```
# 6. 必要なライブラリーをインストール
Qiskit本体以外に必要となるライブラリーをインストールします。
```
pip install qiskit-ibm-runtime jupyter qiskit-aer
```
表示に必要なライブラリーをインストールします。以下のどちらかを実行してください。
- zshシェルの方：
```
pip install 'qiskit[visualization]'
```
- bashシェルの方：
```
pip install qiskit[visualization]
```
# 7. Qiskit で Hello world
続けて、QiskitのHello worldを実行して、Qiskitが正しく動くか確認してみましょう。
以下のコマンドで、Jupyter notebookを立ち上げます。
```
jupyter notebook
```
以下のようにChromeなどのウェブブラウザーが起動します。右上の「New」をクリックし、「Python 3」を選んで、新しいNotebookを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151117/57f9b06c-d797-67f4-44d8-d61946521602.png)

[公式QiskitドキュメントのHello world](https://docs.quantum.ibm.com/start/hello-world) から最初のセルのコードをコピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151117/f28ca8d6-99ac-e749-2fa6-daaaf1632445.png)

自分のNotebookのセルに貼り付けます。「Shift」+「Enter」かまたは、上の方にある右向き三角アイコンで実行できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151117/7ceccdb1-66eb-80ee-3a35-d1dffbab177f.png)

正しくQiskitが動いている場合、以下の回路図が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151117/ff7df460-6907-9956-fb16-27f7c22a79df.png)

ファイルを閉じるには、左上の「File」→「Close and Shut Down Notebook」→「Ok」で終了できます。
Jupyter notebookの環境を修了するには、ターミナルに戻り「Ctrl」+「c」のあと、「y」と入れて「Enter」キーを押します。
ターミナルで以下のコマンドを実行すると、仮想環境から抜けることができます。
```
deactivate
```

# 8. インストール後、再度、Qiskitを使う時
次にQiskitを使う時は、以下のようにしてください。
### 1. ターミナルから仮想環境の立ち上げ
```
source qiskit_env/bin/activate
```
### 2. Jupyter notebookの立ち上げ
```
jupyter notebook
```
ここで新しいPython3のNotebookを立ち上げて、Qiskitを使うことができます。

### 3. Jupyter notebookの終了
必要なNotebookをSaveした後、ターミナルで「Ctrl」+「c」のあと、「y」と入れて「Enter」キー。
### 4. 仮想環境の終了
```
deactivate
```

以上です。お疲れ様でした！
AppServiceのEasyAuthを試してみた

AppServiceのEasyAuthというのがあると聞いて試してみた。
ただ、ドキュメントを見たけれど相変わらずドキュメントを分かりづらい。

Azure App Service および Azure Functions での認証と承認
https://learn.microsoft.com/ja-jp/azure/app-service/overview-authentication-authorization

認証を有効にしてログインするには
　https://[app-name].azurewebsites.net/.auth/login/github
みたいなURLにアクセスすればいいらしい。

IDプロバイダーの登録をどうやってやればいいかが分からなかったので調べてみたら、下記に手順が書いてあった。上記のドキュメントにリンクがあると分かりやすいんだが。

　GitHub ログインを使用するように App Service アプリまたは Azure Functions アプリを構成する
　https://learn.microsoft.com/ja-jp/azure/app-service/configure-authentication-provider-github

ログアウトは
　https://[app-name].azurewebsites.net/.auth/logout
にアクセスすると一旦ログアウトされるが、このままだと再度ログインしようとしたときに前の設定が残っててそのままログインしてしまい、ユーザー変更とかができないらしい。
仕組みの部分はもう少し読まないと上手く運用できなそうですが今日はここまで
Azure FunctionsのCORS設定

Azure Functions に CORS 設定を追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661284/b25828a9-8e1e-abe0-3a61-1c683160ac4b.png)

Azure CLIのコマンドは下記。
az functionapp cors add -g {myRG} -n {myAppName} --allowed-origins https://myapps.com


ただしコマンドの場合は、サブスクリプションが複数ある場合違うサブスクが選択されていると当然操作ができないので
az account show
でアカウントが正しいかを確認し、もし違うサブスクが選ばれている場合には
az account set -s "YOUR_SUBSCRIPTION Name"
を実行するとよい


# 参考
- [チュートリアル:Azure App Service で CORS を使用して RESTful API をホストする](https://learn.microsoft.com/ja-jp/azure/app-service/app-service-web-tutorial-rest-api)

- [Azure functions に CORS 設定を追加する](https://qiita.com/kewpie134134/items/9e22ca962a1437560af9)

- [Azure CLI でサブスクリプションを選択する](https://qiita.com/TsuyoshiUshio@github/items/8b904c547f1e5b132a6a)
error CS1061: 'FirebaseApp' does not contain a definition for 'SetEditorDatabaseUrl'エラーが出た時の解消法

## 背景

firebaseのrealtime databaseをimportして機能を実装しようとしていたらこんなエラーが出ました。

```
error CS1061: 'FirebaseApp' does not contain a definition for 'SetEditorDatabaseUrl' and no accessible extension method 'SetEditorDatabaseUrl' accepting a first argument of type 'FirebaseApp' could be found (are you missing a using directive or an assembly reference?)
```

おや？

## 解決法

ググってみるとversionが上がっていく段階で消えた関数のようです。

```
FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("{url}");
```

↓

```
FirebaseDatabase.GetInstance("{url}");
```

とすればOKです。