OmniAICreator/Qiita-1.07M huggingface dataset:
Xojo web1.0 で HTMLViewer で pdf を表示

Xojo 2020r1 から PDF Document クラスのサポートがなされていて PDF を Xojo から作成することができます。

しかしながら自分は専ら Xojo 2019 を使っていて、PDF を作るときは以下のような PDF 生成手法を組み合わせていました。

「LibreOfficeでPDF文書を自動生成」
https://qiita.com/nanbuwks/items/8ea939ad497fec29c069

さて、そういった Xojo 2019 環境において生成した PDF を Xojo からビューするにはどうしたらいいでしょうか?

Xojo 2019 においても HTMLViewer で Web ページを表示できますが、今回はその HTMLViewer で PDF が表示できるかどうか試してみます。

なお、アプリは Web アプリとして作成し、WebHTMLViewer を使ってテストをしています。

# 環境

- Xojo 2019 Release 3.2
- Web アプリプロジェクト (Web1.0)
- MS-Windows 10 Pro

# アプリ作成

まずは Web アプリを選んで新規作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/f6a2ae30-46d4-c441-3f86-06cdfd6cbaad.png)

TextField, WebButton,HTMLViewer を貼り付けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d6dc0c62-6784-cd0e-2c40-d0822ecc5d9e.png)

Button1 を押したときに以下のコードを実行するようにします。

```
Dim url As String
url = TextField1.Text
HTMLViewer1.URL = url

```

url は 単なる String ではダメで、配列にしてないといけませんでした。(何故?)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a6d0f989-c992-c691-c238-11c83ace0c74.png)

# テスト

実行してみます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/aacad1b9-2f01-f7aa-a6f4-7ffd67a77869.png)

www.google.com を表示しようとしましたができませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/115e486f-b200-f3ff-b9c5-38cbd42dff06.png)

表示できないページが多いですが、wikipedia,wikimedia などは表示できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/5de7ba6d-bf1a-a148-2230-1334a1cd7caf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ea35468a-799d-d999-fbf6-37acbf1070ca.png)

wikimedia に登録されている pdf は HTMLViewer 内で表示できました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/0db2505d-9be6-a949-8548-c80c03a05d0a.png)

しかしながら、ダウンロードするように設定されている pdf は、HTMLViewer でもダウンロードされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/fb1420f0-443e-ebbc-76a9-2aa8ce3ee508.png)

これを踏まえて、LAN 中の Web ページを表示してみます。特に設定していなければ、Web ページは表示できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1763d0fb-d607-b4c7-0751-b2ab08c8091e.png)

HTTPDocumentDirectory に置いてある pdf を指定すると、普通に表示できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1d2bc531-fc2e-fca8-d305-d7c99e262648.png)


なお、 file:: スキームは試していません。
Hexabase TypeScript SDKを使ってデータストアのデータを更新する

[Hexabase（ヘキサベース）](https://www.hexabase.com/)は企業においても安心して利用できるBaaS（Backend as a Service）を提供しています。多くのBaaSがそうであるように、主にフロントエンド開発者に利用してもらいたいと考えています。そこで現在、TypeScript SDKの開発が進められています。

この記事ではHexabase TypeScript SDKのインストールと、データストアからのデータ取得方法を紹介します。[以前にデータを一覧取得する方法は解説しました](https://qiita.com/goofmint/items/f579f19805efd0967bce)が、今回はデータの更新方法について解説します。

## インストール

インストールはnpmやyarnを使って行います。

```
# npmの場合
npm install @hexabase/hexabase-js

# yarnの場合
yarn add @hexabase/hexabase-js
```

## インポート

インポートすると、 `HexabaseClient` というオブジェクトが取得できます。

```jsx
import { HexabaseClient } from "@hexabase/hexabase-js";
```

## 初期化

HexabaseClientを初期化します。

```jsx
const client = new HexabaseClient();
```

### 認証

Hexabaseでは業務利用を想定しているため、利用する際に認証情報が必須になります。最初はメールアドレスとパスワードで認証し、その後はトークンを使ってGraphQLにアクセスします。 `client` を使って処理します。

初回の認証は次のようになります。emailとパスワード、またはトークンが必須です。

```jsx
await client.login({email, password, token});
```

後はこの `client` に対して処理を行います。

## データストアへのアクセス時に必要な情報について

データストアへアクセスする際には以下の情報が必要です。

- データストアID `datastoreId`
- （オプション） プロジェクトID `projectId`

さらにデータ取得を行う際の情報（ページ数、取得件数など） `params` が指定できます。以下がアクセス例です。

```jsx
const project = client.currentWorkspace.project(projectId);
const datastore = project.datastore(datastoreId);
const items = await datastore.items();
const item = items[0];
```

## データを取得する

データを取得する際には `get` メソッドを使ってください。

```jsx
item.get('Title');
```

## データを更新する

データを更新する際には、まず `set` メソッドを使います。

```jsx
item.set('Title', '新しいタイトル');
```

その後、 `save` メソッドを使って保存します。

```jsx
await item.save();
```

この流れはデータを新規作成する際も同じです。

```jsx
const item = datastore.item();
await item
  .set('Title', 'はじめて保存するタイトル')
  .save();
```

## まとめ

データストアはクラウドデータベースとして、様々な型をサポートしたテーブルが利用できます。ぜひ皆さんのWebアプリケーションで利用してください。Hexabase TypeScript SDKを使えば、VueやReactなどと連携したWebアプリを素早く開発できるようになります。2023年04月現在絶賛開発を進めていますので、ぜひ試していただいてフィードバックいただければ嬉しいです！

[hexabase/hexabase-js](https://github.com/hexabase/hexabase-js)
Podman Desktop のインストール(for Mac)

# はじめに

このページではMac版のPodman Desktopのインストール手順について記載しています。
Windows版は[こちら](https://qiita.com/youn0810/items/4e7ca4050413f3c6df08)を参照ください。

## インストーラーのダウンロード

下記リンク先を開き、中央にある **Download Now** をクリックします。

https://podman-desktop.io/

![スクリーンショット 2023-04-25 12.48.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118463/87a403ce-b7bc-0415-dfb2-f68f04582390.png)

macOS用のページが表示されたら再度 **Download Now** をクリックします。

![スクリーンショット 2023-04-25 12.48.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118463/d25bec25-6b93-739e-0583-9a30e74349e9.png)

:::note info
本記事ではインストーラーを使用しますが、パッケージマネージャーのbrewでのインストールも可能です。
brewを使用する場合は、下記コマンドをターミナルで実行してください。
```cmd
brew install podman-desktop
```
:::

ダウンロードが完了したら、**podman-desktop-{バージョン}-universal.dmg** を実行し **Podman Desktop.app** を **Applications** に移動します。
> 記事執筆時点は podman-desktop-0.14.1-universal.dmg でした。

![スクリーンショット 2023-04-25 12.57.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118463/3b7f13bf-d5b6-58b2-ed60-e67c5fbd72fe.png)

## Podman Desktop起動

それではインストールしたPodman Desktopを起動してみましょう。
ご利用の端末にPodmanの環境がある場合は、`Podman is running`と表示されます。
まだPodmanの環境がない場合は、`Podman Desktop was not able to find an installation of Podman`と表示されるので、右側にある **Install** をクリックします。

![スクリーンショット 2023-04-25 10.00.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118463/35c4187e-92f4-138a-6350-e20976de40ac.png)

**Yes** をクリックします。

![スクリーンショット 2023-04-25 10.00.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118463/fd4e127e-c70a-5c47-7fd0-d14f16898006.png)

指示に従い進めます。

![スクリーンショット 2023-04-25 10.00.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118463/da4aed35-9fd9-d743-9553-33ccb61df8c0.png)

![スクリーンショット 2023-04-25 10.00.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118463/1bc02ca9-f75a-8cff-4f0a-bbb7787e8114.png)

![スクリーンショット 2023-04-25 10.00.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118463/ee5f8313-2e3a-a9d2-71df-e69aecc94e6d.png)

![スクリーンショット 2023-04-25 10.00.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118463/7bb7693a-13e0-f106-6034-020f6340e352.png)

![スクリーンショット 2023-04-25 10.00.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118463/7d4b89c5-1770-febe-ce5d-84a84f6ed683.png)

インストールが完了すると、先ほどのDashboard画面で`Podman is running`と表示されました。

![スクリーンショット 2023-04-25 10.00.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118463/5ee01cb4-52be-384f-bedf-36a31c4fbf7f.png)

## 触ってみよう

こちらのGitHubにて操作方法を公開しています。

https://github.com/IBMDeveloperTokyo/podman_desktop/blob/main/README.md
Pythonでset型に配列を追加したい場合の対処法

# はじめに

最近参加できていなかったABC291のC問題を解いていたときに，要素の検索が高速で行えるset型に配列データを追加したいタイミングがありました．

https://atcoder.jp/contests/abc291/tasks/abc291_c

しかしPythonではlist型の配列をset型に追加することはできません．
これまでにも同様のことで何度か悩んだことがあったので，ここでまとめておきたいと思います．

# 結論

さっそく結論から述べると，list型ではなく**tuple型**にすることで追加することが可能となります．

```Python
a = set()
a.add((1, 2))
print(a)
```

出力は以下のようになり，うまく追加できていることがわかります．

```Python
{(1, 2)}
```

もちろん2次元以上の配列も同様に追加できます

```Python
a = set()
a.add((1, 2, 3, 4))
print(a) # {(1, 2, 3, 4)}
```

複数の配列を追加することも可能です．

```Python
a = set()
a.add((1, 2))
a.add((3, 4))
print(a) # {(1, 2), (3, 4)}
```

ちなみにlist型で追加しようとすると...

```Python
a = set()
a.add([1, 2])
print(a)
```

このようなエラーが出てきます．

```Python
TypeError      Traceback (most recent call last)
      1 a = set()
----> 2 a.add([1, 2])
      3 print(a)

TypeError: unhashable type: 'list'

```

# 最後に

今回は何度か悩まされたset型への配列の追加の問題に対処する方法についてまとめてみました．

~~list型は追加不可でtuple型は追加可能なのは，list型はミュータブルであるため，list型のデータが書き換えられた場合にset型のハッシュ値を振り直す必要があるので，イミュータブルなtuple型しか受けつけないのかなと個人的には腑に落ちました．~~

list型は追加不可でtuple型は追加可能なのは，tuple型はハッシュ可能でありlist型はハッシュ不可能であることからきているそうです．
(@shiracamus 様にコメントにてご指摘いただきました．
ありがとうございます．)

データ構造にそこまで詳しくないので，誤りがあればコメントにてご指摘いただけると幸いです．
Pryでデバッグをする。Pryで組み込みクラスのメソッドを調べる

# Pryでデバッグをする方法と組み込みメソッドを調べる方法を学んだので共有します。
## Pryとは
そもそもPryとはGemの一種でRubyで使える外部パッケージです。
REPLと呼ばられるコードを1行ずつ実行していく対話型の仕組みを持っています。
## 結論
- デバッグについては標準で使えるruby/debugを使ってもどちらでもいいと思いました。
- 組み込みクラスを調べる方法は便利です。irbでのやり方を知らないだけかもしれませんが

# ここから本文です。

## 今回Pryについて調べてわかったこと

- REPLで対話型デバッグができる
- REPLで組み込みクラスやメソッドの説明が見れる

## 必要なGem
Gemfileに記入してください

```ruby
#本体
gem 'pry'
#デバッグ用
gem 'pry-byebug'
#Rubyのドキュメントの情報
gem 'pry-doc'
```

## デバッグの仕方

```ruby
#ファイルの先頭に記載
require 'pry-byebug'

#デバグを開始する位置で
binding.pry
```

プログラムを実行するとブレークポイントで一時停止し、対話しながら実行できるようになる

step　1行処理をする。メソッドの場合は中に入る

next　1行処理をする。メソッドの場合は中に入らない

ls　今見れる変数やオブジェクトの一覧を表示

<変数名>　中身の値を教えてくれる

continue　次のブレークポイントまで進める。

exit　プログラムを最後まで実行する

## 組み込みクラスやメソッドの説明を見る

```console
#REPLを起動
$ pry

#ドキュメントを読み込む
$ require 'pry-doc'

#メソッドの一覧を表示する
$ ls オブジェクト名

#メソッドの使いかたを見る
$ show-doc <クラス名>#<メソッド名>

#クラスの使い方を見る
$ show-doc <クラス名>

#コードを見る
$ show-source <クラス名>#<メソッド名>

#終了
$ exit
```

### 補足

pryをrailsで使う等、開発環境のみで使う場合はGemfileにグループを記入する

```ruby
group :development, :test do
    gem 'pry'
end
```

以上となります。
以下参考
[【Rails】 Pryを使ってデバッグをしてみよう！](https://pikawaka.com/rails/pry)
ChatGPT
DiffusionBee使ってみた

# DiffusionBeeとは
Stable Diffusion(画像生成AI)を手軽に使えるアプリ
https://diffusionbee.com/

# 使ってみた
欲しい画像の単語を入力して「Generate」ボタンを押すだけ（日本語は未対応！！）

## 4単語
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526938/24c5fe3d-6f9e-4177-dbcd-ab48c5af561e.png)
画像じゃない >o<

## 2単語
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526938/d07c86b8-0332-f322-0191-37c6dc7adfae.png)
いい感じ

## 3単語
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526938/7455f32c-20df-27c3-1491-7053700fab2f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526938/8cf65196-238a-ef80-ef38-93da5436705d.png)
文字だらけ

# 他の方が作った画像も見れる
https://arthub.ai/

# 職人が作った美少女の単語をコピーして作ってみる
単語↓
> <lora:koreanDollLikeness_v10:0.3>,<lora:taiwanDollLikeness_v10:0.2>(8k, RAW photo, best quality, masterpiece:1.2), (realistic, photo-realistic:1.37), ultra-detailed,
1 girl,cute, solo,beautiful detailed sky,detailed cafe,night,sitting,dating,(nose blush),(smile:1.1),(closed mouth)
medium breasts,beautiful detailed eyes,(collared shirt:1.1), bowtie,pleated skirt,(short hair:1.2),floating hair

## 職人の作品
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526938/bf0a9ef1-0d9c-34f0-1a11-a759a40223f9.jpeg" width=200>

## 単語をコピーして作ってみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526938/63e49dc8-fbfe-5fc0-dc1b-2991267e46a5.png)

全然違うじゃねえかww

と思ったら、こういうことらしい。
>同じプロンプトをコピーして利用しても、設定やモデルデータの違いなどが影響するので同じ画像が生成されるわけではありません
【C#】単体テスト作成方法

C#で単体テストをする方法。
-
<h4>動作環境</h4>
<ul>
    <li>windows11</li>
    <li>VisualStudio 2019 Professional</li>
    <li>.NET Framework</li>
</ul>

---
<h3>プロジェクトの作成</h3>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325724/695f2638-c6fa-473f-3fdb-9ff9b06a2d62.png)

まずは新しいプロジェクトを作成する
今回はWindowｓFormで作る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325724/986a8376-3cdd-cf81-177a-ac7ef3b4821f.png)

新しいプロジェクトが作成できたら

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325724/eb3e9f0a-8c5b-2789-9dfb-3118644cce66.png)

ソリューションのところを右クリックして
追加→新しいプロジェクトを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325724/e2a1af70-c336-3614-79e3-a56a420b3643.png)

単体テストプロジェクトを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325724/f660f766-cbdd-cf79-34f6-24fa79bf9f6b.png)

新しいプロジェクトを作成する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325724/156bcdc4-9438-5afd-a1c3-0819b0a7a852.png)

作成できたら作成したプロジェクトの参照を右クリックして参照の追加を選択
最初に作ったプロジェクトを追加する


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325724/25ad2db4-7911-7dd1-3bfb-3b537dc5a117.png)
ここで参照のところに最初に作ったプロジェクトがあればOK
黄色い▲マークが付いていたらダメ
最初のプロジェクトとテストプロジェクトのターゲットフレームワークが異なっている等の原因が考えられる

---
<h3>テストの作成</h3>

最初のプロジェクトにCalculation.csを追加し、次のコードを追加する。

```c#:Calculation.cs
namespace hogeApp
{
    public static class Calculation
    {
        public static int Sum(int a, int b)
        {
            return a + b;
        }
    }
}
```
テストをするほどの関数ではないが引数aとbの合計を返す関数を作成

テストプロジェクトのUnitTest1.csに先ほどのSum()関数のテストコードを書いていく
```c#:UnitTest1.cs
namespace hogeAppTest
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            //テストしたい関数を呼び出して返り値を格納
            int sum = hogeApp.Calculation.Sum(2,5);

            //(想定した値, 実際の返り値)を引数に指定
            Assert.AreEqual(7,sum);
        }
    }
}

```

ここまで記述できたら画面左にあるテストエクスプローラーからテストを実行する
※テストエクスプローラーが無い場合は画面上部のテストからテストエクスプローラーを追加できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325724/b5fbd806-d70d-b6cb-899a-27d32ca667e9.png)

2+5=7で想定した値が返ってきているので
テストが成功している

次は想定した値を違う値(100)とかにしてテストを実行してみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325724/4e4d6b8a-ae53-4aae-32db-2128576c158a.png)

当然想定している値ではないのでテストが失敗している

どのような失敗をしているのかはエラーになっているテストをクリックしていくとわかる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325724/3d11d328-77bd-5a5f-cab6-8c4072579340.png)

メッセージのところに
```
Assert.AreEqual に失敗しました。<100> が必要ですが、<7> が指定されました。
```
とあるので詳細がわかる


これでテストプロジェクトが作成できたので、
ここからテストコードを追加していけばOK
[OCI]Autonomous Database の最新のバックアップからのクローンは使えるのか

# はじめに
Autonomous Database にはクローン機能があり、**フル・クローン** / **リフレッシュ可能クローン** / **メタデータ・クローン**が作成できます。

また、フル・クローン / メタデータ・クローンの場合、**データベース・インスタンス（実行中インスタンス）からのクローニング** / **バックアップからのクローニング**を選択することができます。

さらに、バックアップからのクローニングの場合、過去60日以内のタイムスタンプを指定する**ポイント・イン・タイム・クローン** / 自動バックアップのリストから選択する**リストからのバックアップの選択** / **最新のバックアップ・タイムスタンプ** を選択することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/6d0eb1b4-ae72-6455-5356-a20723a3d442.png)
「最新のバックアップ・タイムスタンプのバックアップからのクローニング」のユースケースとしては、データベースが使用できなくなった場合、または最新のバックアップに基づいてクローンを作成するなんらかの理由がある場合に使用します。
なお、クローンはソースと異なるExadata筐体上に作成されます。

Autonomous Database インスタンスとは別の環境に保管されているバックアップを使用するので、Autonomous Database インスタンスが障害等で使用不可になってしまった場合に有効なクローニングの手段です。

今回は、**最新のバックアップ・タイムスタンプ**とはどれくらい最新なのか、ということを検証してみたいと思います。

# 検証方法
1. Autonomous Database インスタンス`ATP4Clone`を作成
1. 以下のようにSAMPLE表と、SERIALシーケンスを作成
    ```sql
    CREATE TABLE SAMPLE(ID int, time timestamp);

    CREATE SEQUENCE SERIAL MAXVALUE 200000;
    ```
1. SAMPLE表に1秒ごとに1行INSERTするスクリプト(check.sh)を実行
    ```check.sh
    #!/bin/bash

    sql_flg=/tmp/sql.flg
    touch $sql_flg

    (
    while [ -a ${sql_flg} ]
    do
     echo "insert into sample values(serial.nextval, systimestamp);"
     echo "commit;"
     sleep 1
    done
    
    echo "exit"
    
    )|sqlplus  -s  admin/Welcome12345#@ATP4Clone_tp
    exit
    ```
1. ある時点(3分後)で障害が発生しAutonomous Database が使用不可になったと仮定し、その2分後にDBを停止、停止後にクローン作成
1. クローン側に接続し、どの時点(T1)までINSERTされているか確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/e9930628-be0a-dbd1-1d85-415e6e624c05.png)

# 結果
クローン側に接続し、以下のSQLでSAMPLE表のデータを確認してみます。
```sql
SELECT * FROM SAMPLE ORDER BY ID DESC;
```

```sql
 ID TIME                     
--- ------------------------ 
129 2023-04-25T15:38:40.211Z 
128 2023-04-25T15:38:39.210Z 
127 2023-04-25T15:38:38.209Z 
126 2023-04-25T15:38:37.208Z 
125 2023-04-25T15:38:36.207Z
```

スクリプト実行から2分後にDBを停止しました。停止までのラグがあり、実際DBが停止した2分9秒のデータまで残っていることが分かります。

結果としては、データ損失は0だったことになります。

今回の検証では、実際にDBに障害は起こしておらず、停止させただけのため、内部的にREDOログのバックアップは行われています。
Autonomous Database-Sharedでは、ログのバックアップ頻度は1分でクローン作成時間より短いため、データ損失が0という結果になったと考えられます。

なお、クローン側でDBA_PDBSディクショナリのLAST_RECOVER_TIME列を参照してみると、どの時点のデータまでクローン側に反映されているか分かります。
```sql
SELECT LAST_RECOVER_TIME FROM DBA_PDBS;
```

```
LAST_RECOVER_TIME 
----------------- 
2023/4/25 15:41:13
```

DB停止が15:38:40、クローン作成終了が15:43:20だったので、やはり内部的にREDOログのバックアップは取られ続けていることが分かります。

本検証からログのバックアップが直前まで取られていることが分かったので、ドキュメント通り障害発生時のRPOはバックアップ頻度同様最大1分と考えられます。

なお、クローン作成中はダウンタイム(RTO)となるため、ここを許容できるかがポイントになってくるかと思います。いくつかのパターンで検証した結果、クローン作成時間はデータ量に比例し、約25分/TBでした。

Autonomous Data Guard構成の場合、同一リージョン内ではRTOは数秒～2分、クロスリージョンでは15分となるので、クローン作成に伴うダウンタイムが許容できない場合は、Autonomous Data Guardをご検討いただくと良いかもしれません。

# 参考
<a href="https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/autonomous-clone-backup.html#GUID-20D2D970-0CB4-472F-BF89-1EE769BFB5E8" target="_blank" rel="noopener noreferrer">バックアップからのAutonomous Databaseのクローニング</a>
＝＝とequalsの違いは？


# ＝＝とequalsの違いは？

1. ### `==` と `equals` の違いは、次のようになります

    `==` 演算子は、比較しているオブジェクトの参照が同じかどうかをチェックします。つまり、比較しているオブジェクトが同じオブジェクトであるかどうかをチェックします。 一方、 `equals` メソッドは、オブジェクトの内容が同じであるかどうかをチェックします。

2. ### 例1

    ```java
    String str1 = "Hello World";
    String str2 = "Hello World";
    
    boolean isEqual = str1.equals(str2);//true
    boolean isSameRef = (str1 == str2);//true
    ```

    これら 2 つの文字列オブジェクトがメモリ内の定数プールに格納され、実際には同じメモリ アドレスを指します。 これは、Java の文字列は不変オブジェクトであるため、同じ内容の複数の文字列オブジェクトを作成すると、それらはすべて定数プールに格納され、同じメモリ アドレスを指して、メモリ スペースの浪費を回避します。

    したがって、"=" 演算子を使用してこれら 2 つの文字列オブジェクトを比較すると、同じメモリ アドレスを指しているため、true が返されます。 equals() メソッドを使用してこれら 2 つの文字列オブジェクトを比較すると、同じ文字列コンテンツが格納されているため、true が返されます。

3. ### 例2

    ```java
    String str1 = new String("Hello");
    String str2 = new String("Hello");
    
    boolean isEqualUsingEquals = str1.equals(str2); // true
    boolean isEqualUsingOperator = (str1 == str2); // false
    ```

    この例では、str1 と str2 には同じ文字列コンテンツが含まれていますが、異なるメモリ アドレスを指しています。 Java では、**new キーワード**を使用して作成されたオブジェクトは、**毎回メモリ内に新しいインスタンス**を作成するためです。
    
    したがって、「=」演算子を使用してこれら 2 つの文字列オブジェクトを比較すると、異なるメモリ アドレスを指しているため、false が返されます。 equals() メソッドを使用してこれら 2 つの文字列オブジェクトを比較すると、同じ文字列コンテンツが含まれているため、true が返されます。
    
    ### 4.まとめ
    
    これらの例は、「=」演算子が 2 つのオブジェクトの参照が同じかどうかを比較し、equals() メソッドが 2 つのオブジェクトに含まれる内容が等しいかどうかを比較することを示しています。 String 型のオブジェクトの場合、通常、「=」演算子を使用するのではなく、equals() メソッドを使用して、含まれている文字列が等しいかどうかを比較します。
【Issueは神/世界は広い】Nextjs 13.3.0で作成したアプリをAmplify Hostingした時に画像が表示されない

## TL；DR
Nextjsのバージョンを`13.3.0`から`13.3.1`に上げた。

該当するCore Changeは以下の部分で、詳しい部分はあまりわかっていない。
[Fixed image-optimizer crashing when using outputFileTracing](https://github.com/vercel/next.js/releases/tag/v13.3.1#:~:text=Fixed%20image%2Doptimizer%20crashing%20when%20using%20outputFileTracing%3A%20%2348513) 
[PR#48513](https://github.com/vercel/next.js/pull/48513)

## この記事で伝えたいこと

上記の対応は同様のエラーが出た方向けに記載してます。よかった、治った、万々歳の方はこの記事は終了です。

...
..
.

私がこの記事で本当に言いたいことは

 <h3>GitHubのIssueは神</h3>

ということです。

## 経緯
タイトルの通り、Nextjsで作成したアプリをAmplify Hostingで公開したときに画像が表示されなかった。
ローカル環境では表示できていた。

↓参考
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089299/c3f07f20-3edc-6078-6d74-8473d7da2a05.png)

なんじゃこりゃ〜と躍起になって調べていたら、普通にGithubのIssueが立っていました。

https://github.com/aws-amplify/amplify-hosting/issues/3428

この記事から芋づる式に原因を突き止めることができ、解決方法にも辿り着きました!!
(このContributorの方に直接感謝したい。)

## 感動ポイント1 Github Issueは神

最初に当たった情報は`Apmlify Hosting`側のIssueでした。
しかし、Amplify側の人が「Nextjs側のバグかもしれないね!!」とIssueやPRを確認し情報を更新してくれており、fixされたから更新してみてね!!的なことでクローズしていることで私はバージョンアップボタンをポチっと押すだけで問題は解決したわけです。
つまり、Nextjs側に問題があるらしいからそっちをみてね!!じゃ!!バタンっ!!でクローズされていたら私は特定にさらに時間がかかっていたことでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089299/4ecf6be9-c66a-ee4e-ba2c-4bdaa9b8c0b2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089299/7f815acb-3f2f-033d-1dde-dae5d91d9a5f.png)

GithubのIssueが神というかAmplifyのエンジニアが優秀ということもありそうですが、こんなにも簡単に原因を特定して修正できるなんて素晴らしいと感動してました。

## 感動ポイント２ 世界は広い

先ほどAmplifyのエンジニアが優秀だけでは？と話をしましたが、Issueで感動した点は`圧倒的な情報量`です。

日本語で記事を調べていたときは検索が全然ひっかからず(私はググり力が足りないのものありますが)、英文で検索をかけたら簡単にIssueにつながりました。さらに、Apmlify HostingのIssueからNextjsのIssueやPR、releaseまで確認し該当するキーワードで検索をかけると英語の記事がかなりあって、バージョンあげようね!!と簡単に検索できてしまいました。
「これがグローバルか...!!」と安直ながら思った次第でございます。

### 最後に
私は英語は得意なわけではないですが、エンジニアたるもの情報のキャッチアップはできるだけ最先端で取れるようになりたいなと思いました。

(バージョンアップは慎重に!!)
AWS Nitro Enclaves 超初心者のエラー回避備忘録



## 内容

```
nitro-cli run-enclave --cpu-count 2 --memory 5120 --eif-path hello.eif --debug-mode --enclave-cid 16
```

nitro-cli の run-enclave コマンドにて、以下のようなエラーが出たときのこと。

```
If you open a support ticket, please provide the error log found at "/var/log/nitro_enclaves/err2023-04-25T01:48:49.334673532+00:00.log"
```

にて、log をチェックすると、

```
Create VM ioctl failed
The enclave cannot be created because no CPUs are available in the pool
```

となっていた。


## 解決策

おそらくエンクレーブが既に使用中なので、それをチェックして必要であれば削除します。

```
nitro-cli describe-enclaves
```

```
  {
    "EnclaveName": "mytest",
    "EnclaveID": "i-07bdc1796ceb8d416-enc18779365aef52a0",
    "ProcessID": 26137,
    "EnclaveCID": 16,
    "NumberOfCPUs": 2,
    "CPUIDs": [
      1,
      3
    ],
```

のようになっていれば、

```
 nitro-cli console --enclave-id i-07bdc1796ceb8d416-enc18779365aef52a0
```

のようにしてプロセスをチェックしてみましょう。
削除するには、

```
sudo nitro-cli terminate-enclave --enclave-id i-07bdc1796ceb8d416-enc18779365aef52a0
```

を実行します。

```
{
  "EnclaveName": "my_test",
  "EnclaveID": "i-07bdc1796ceb8d416-enc18779365aef52a0",
  "Terminated": true
}
```

削除が成功したら、再度エンクレーブを使用してみましょう。
AndroidStudio で新規プロジェクト作成時の Incompatible because this component declares an API of a component compatible with Java 11 and the consumer needed a runtime of a component compatible with Java 8 と出た時

## 概要

何回も何回もググっては時間を使っていたので書きます。

AndroidStudio にて新しいプロジェクトを作成した時に、

```
  - Variant 'apiElements' capability com.android.tools.build:gradle:7.4.2 declares a library, packaged as a jar, and its dependencies declared externally:
      - Incompatible because this component declares an API of a component compatible with Java 11 and the consumer needed a runtime of a component compatible with Java 8
```

のようなエラーが吐き出されbuild （Hello, world) ができないときの対処法です。


## 解決策

上のツールバーの

AndroidStudio --> Preferences --> Build, Execution, Deployment --> Build Tools --> Gradle

を開いて、

Gradle JDK:

をドロップダウンから11 に変更。

Apply --> OK

で解決します。


![Screen Shot 2023-04-25 at 10.23.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/b28cc8c1-bf34-ab61-9423-ee0a74684ca0.png)


以上です。
nodenvでNode.jsのバージョンを管理する際のコマンドまとめ

# Node.jsのバージョンを管理する為の備忘録
nodenvの導入方法は割愛しますが、慣れるまではこれを見て覚えようと思ったので、備忘録として運用に必要なコマンドをまとめておきます。
```shell
# nodenvのバージョン確認
$ nodenv -v

# nodenvでインストール可能なバージョンの一覧を取得
$ nodenv install -l

# インストールしたnodeのバージョンを確認
$ nodenv versions

# 必要なnodeのバージョンをインストール
$ nodenv install ******

# nodeのバージョンを確認
$ node -v

# グローバルのバージョンを設定
$ nodenv global ******

# cd 【プロジェクトディレクトリ】のバージョンを設定
$ nodenv local ******

# ローカルバージョンの設定を解除
$ nodenv local --unset

# シェルの再起動
$ exec $SHELL -l

# nodeの向き先を確認
$ which node

# リフレッシュ
# nodenv-package-rehashをインストールすれば不要
$ nodenv refresh

# node.jsをアンインストールする
$ nodenv uninstall ******

# インストールされているルート確認
$ nodenv root

# nodenvをアップデートする
# anyenv-updateのインストールが必要
$ nodenv update
```
DeepLで翻訳作業中のストレスを軽減！コピーした文章から改行文字を消すChrome拡張機能の公開

# Delete-LineFeed-DeepL
DeepL常習者のみなさんこんにちは。
DeepLでの翻訳作業を楽にする拡張機能を作りました。

論文のPDFからコピーした際、変な改行が入って翻訳がちょっと崩れた経験ありませんか？
数行なら手作業で行けますが、大量にあるとダルいですよね。コピペした文章から改行を除去してくれる別のサイトはありますが、毎回移動してコピペするのもなかなか大変です。こんな悩みを解消する拡張機能です。

↓論文からコピペしたときこんな感じになることありません？
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343363/e4feee28-9b9d-d271-70ae-03a23857ef2a.jpeg)

## この拡張機能の機能
- クリップボード内のテキストから改行を除去する
- DeepLのページ上で変換作業が完結する
- ボタンをクリックするだけでOKだからとっても簡単

# Chrome拡張機能の導入方法
1. [Github](https://github.com/TaniPotato/Delete-LineFeed)からクローンするか、Zipでダウンロード
2. Chrome起動後、[拡張機能の設定サイト](chrome://extensions)に移動
3. サイト右上のデベロッパーモードをONにする
4. 「パッケージ化されていない拡張機能を読み込む」をクリック
5. 1でDLしたフォルダを読み込む。Zipの場合は解凍をしてから読み込む。

# 使用例
1.論文からテキストをコピーした状態で、DeepLにアクセス
2.ファイルの翻訳の右に「改行を削除」ボタンがあるのでクリックする。
3.初回のみクリップボードへの許可を求めるホップアップが出るので「許可する」をクリック
4.DeepLにペーストする

![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343363/44083056-3877-ff62-fea3-a07028573211.jpeg)

# 最後に
本拡張機能のソースコードは誰でも見れるので、セキュリティ等に不安がある人は確認してから使用してください。
特に大学院生など大量の論文を解読するときにDeepLにお世話になる人は多いと思います。そのような方々の助けとなれば幸いです。なお、今回作成するにあたってChatGPTにコーディングを手伝ってもらいました。ほとんどプログラム書いてくれたので助かりましたね～。
GAされたDatabricks Workspace Filesを試してみる

こちらの機能を試してみます。

https://qiita.com/taka_yayoi/items/ff068885af8f84faa1d2

# Pythonモジュールの作成

これまでは[Repos](https://qiita.com/taka_yayoi/items/b89f199ff0d3a4c16140)配下でしか`.py`ファイルを作成できませんでしたが、ワークスペースのどこでもファイルを作成できます。これだけでも相当便利。
![Screenshot 2023-04-25 at 14.22.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/3669bf50-1d3a-cb29-4ea6-652a8b4e87c7.png)
![Screenshot 2023-04-25 at 14.22.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/cae61ced-837b-7b52-e284-9c4396451fb0.png)

```py:mymodule.py
def funcname():
       print(__name__)
```

ノートブックを作成して、モジュールをインポートします。

```py:notebook
import mymodule
mymodule.funcname()
```

```
mymodule
```

カスタムPythonライブラリの開発が捗ります。

# データの格納

DBFSを気にすることなしに、ノートブックと同じ場所に手軽にファイルをアップロードできます。
![Screenshot 2023-04-25 at 14.17.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a3682277-eefc-a519-1ebd-66740a31bbbd.png)

```py:Python
import pandas as pd

df = pd.read_csv("/Workspace/Users/takaaki.yayoi@databricks.com/20230425_workspace_files/japan_cases_20220818.csv")
display(df)
```
![Screenshot 2023-04-25 at 14.24.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a234bfac-1057-4034-4a26-33f6a0106005.png)

# initスクリプトの作成

:::note
**注意**
本機能がリリースされるまでに若干のタイムラグがあります。
:::


これまでは、クラスターのinitスクリプトを利用するにはDBFSに`.sh`を書き出してから設定する必要がありましたが、もっとお手軽に作成、設定ができるようになりました。

こちらを参考に。

https://qiita.com/taka_yayoi/items/6ac6b521698da47a3c25

ワークスペースで直接initスクリプトを記述します。

```sh
#!/bin/bash
apt-get --yes install libsndfile1
```
![Screenshot 2023-04-25 at 14.50.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/310c3f82-4f5f-cc1b-43ff-c9f47e3af103.png)

クラスターの**initスクリプト**の送信先で**Workspace**を選択し、initスクリプトのパスを入力して追加します。この際、パスは`/Users/`以降を記述してください。
![Screenshot 2023-04-25 at 14.54.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/5926bacb-ac3f-7cc7-1ec9-ffe200ba47f3.png)

クラスターを起動するとinitスクリプトが実行されます。
![Screenshot 2023-04-25 at 14.58.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/7a51232d-427d-7f70-2578-159b5547757f.png)

```
%pip install librosa
```

```py:Python
# Beat tracking example
import librosa

# 1. Get the file path to an included audio example
filename = librosa.example('nutcracker')

# 2. Load the audio as a waveform `y`
#    Store the sampling rate as `sr`
y, sr = librosa.load(filename)

# 3. Run the default beat tracker
tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr)

print('Estimated tempo: {:.2f} beats per minute'.format(tempo))

# 4. Convert the frame indices of beat events into timestamps
beat_times = librosa.frames_to_time(beat_frames, sr=sr)
```

```
Downloading file 'Kevin_MacLeod_-_P_I_Tchaikovsky_Dance_of_the_Sugar_Plum_Fairy.ogg' from 'https://librosa.org/data/audio/Kevin_MacLeod_-_P_I_Tchaikovsky_Dance_of_the_Sugar_Plum_Fairy.ogg' to '/root/.cache/librosa'.
Estimated tempo: 107.67 beats per minute
```

動きました！


### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
java初心者がいく～nextLine()とnext()の違い～

# はじめに
java初心者が議事録的に書いています。

# NextLine()とnext()の違い
javaで入力するときにScannerを用いるが、例えば数字を入力した直後に文字列を入力させたいときは以下のようにnext()を使わないといけない。

```java
System.out.print("数字を入力：");
int num = scanner.nextInt();

System.out.print("文字列を入力：");
String str = scanner.next();

System.out.println("出力結果");
System.out.println("数字" + num);
System.out.println("文字列"+ str);
```

```:出力結果
数字を入力：11
文字列を入力：a
出力結果
数字：11
文字列：a
```

ではNextではなくNextLineを使うとどうなるでしょうか

```:出力結果
数字を入力：11
文字列を入力：結果
数字：11
文字列：
```

となってしまう。
これはNextLine()が改行をスキャンしてしまうからである。
数字を入力完了した後Enterキーを押すと思うが、その時の改行がNextLine()にスキャンされてしまい結果的に文字列になにも入力されていないようにみえるのである。
NextLine()に対してNext()は改行を無視して文字列をスキャンできる。（厳密には文字列がスキャンされるまで改行はスキャンされない）
そのため今回は改行をスキャンしないNextを使用しないとおかしくなる。
ちなみにNextIntも数字を入力するまで改行をスキャンしない。

（ちなみに文字列と数字の入力を逆にしたらNextLineでも問題なくいける。理由は上記の内容を理解していたらわかるよね！）
matomo

Google Cloud Consoleにログインし、プロジェクトを選択
GCP Marketplaceから、Matomoをインストールしてください。デプロイ方法は、VMインスタンスで単一のVMを選択し、デプロイ用の.zipファイルをアップロードする　https://console.cloud.google.com/marketplace/product/click-to-deploy-images/matomo?project=able-folio-288707#:~:text=%E3%82%AB%E3%82%BF%E3%83%AD%E3%82%B0%E3%81%AB%E8%BF%BD%E5%8A%A0%3A-,%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4,-%E7%94%A8%E3%81%AE%20.zip
MatomoをデプロイしたVMインスタンスのIPアドレスをメモする。
Matomoにアクセスして、管理者アカウントを作成する。
Matomoの管理画面で、設定>ウェブサイトを開き、新しいサイトを作成する。この際、WebサイトのURLや名称などの情報を入力します。また、Matomoから提供されるトラッキングコードをメモする。

Reactで構築されたWebアプリにMatomoのトラッキングコードを追加します。React GAなどのライブラリを使用することで、簡単にトラッキングコードを追加することができます。トラッキングコードを追加することで、Matomoにページビューなどの情報を送信することができます。

Matomoの管理画面で、作成したサイトのダッシュボードを確認することで、Reactで構築されたWebアプリのアクセスログの解析を行うことができる。
ランダムパスワード生成サイトを作りました

Next.js、tailwindcss、Javascriptで[PassGen.jp](https://passgen.jp)というランダムパスワード生成ツールを作りました。

これは実際は[FrontendMentor](https://www.frontendmentor.io/challenges/password-generator-app-Mr8CLycqjh)のチャレンジプロジェクトです。

練習だけで終わりたくないので、実際にドメインを買って、
オンラインにしました。

Googleの初のページに入れるように目指します。
そのため、SEO等を勉強します、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231230/b8c29eb7-256d-0ca8-4869-e72c77869473.png)

ソースコード: 
https://github.com/mariosaputra/password-generator

バックエンドの参考：
https://github.com/aleksFedotov/password-generator
レポート提出のためのPDFが生成できるツール群

これはメモ書きです。

レポートはPDFで提出することが多い。そういうときに使える言語やツール、またはそれらを組み合わせた技術をまとめてみる。

## リスト

言語、ツール、それらを束ねた組み合わせを示し、以降は組み合わせの良しあしなどを書く。

言語
- Markdown
- LaTeX
- [Typst](https://github.com/typst/typst)

ツール
- Pandoc
- Word
- pLaTeX, UpLaTeX, LuaTeX, XeTeX, pdftex

それらの組み合わせ
- LaTeX + Compiler
- Markdown + LaTeX + Pandoc
- Markdown + VScodeの拡張機能: [Markdown PDF](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf)
- Typst

## Markdown + LaTeX + Pandoc

本文はMarkdownで書いて、Pandocの内部でtexファイルに変換、最終的にPDFとして出力する方法。

```markdown
---
title: いい感じのタイトル
author: Qiita太郎
---

## ヘッダー

オイラーの公式はインラインで書くと $\exp{i\theta} = \cos{\theta} + i \sin{\theta}$ であり、ブロックで書くと

$$
\exp{i\theta} = \cos{\theta} + i \sin{\theta}
$$

```

このように書いて、

```console
$ pandoc --pdf-engine=lualatex -V documentclass=ltjsarticle -o output.pdf main.pdf
```

と実行すれば、以下のようなpdfが手に入る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368139/a2c302b5-949d-e6cf-4b59-816e2ed710e5.png)

下記のような簡単なMakefileを用意するだけで`make`コマンドで全部pdfを生成できて便利。

```makefile
MD=$(shell ls **/*.md)
PDF=$(MD:.md=.pdf)

all: $(PDF)

%.pdf: %.md
	pandoc --pdf-engine=lualatex -V documentclass=ltjsarticle -o $@ $<

clean:
	rm **/*.pdf
```

この方法は、Markdownで気楽に書けるのが大変よい。一方で少しだけレイアウトや見た目を変更したいというだけでも、専用のpandocのfilterを作成したりしないといけなかったりして、地獄を見る。レポートのレイアウトや見た目にそこまでシビアではない課題をこなすときに重宝する。

pdfへの変換にはLaTeXのツールセットに依存しているため、ローカルにTexの環境を用意してあげないといけないのが面倒。

## LaTeX + Compiler

見た目やレイアウトに要件がある場合には、そのままLaTeXを使うのがよさげ。

日本語を使わなくていいなら、pdftexがコマンド一発でbibliographyまで処理してくれるので楽。日本語を使わないといけないなら、LuaLaTeXがコマンド一発で同じくbibliographyまで処理してくれるので楽。

慣れていないと不必要なpackageを`\usepackage`してビルドが通らなかったり、不親切なエラーメッセージに悩ませられたりする。

## Typst

Typstはおそらく最近でてきた、レポートなどが書けるツール。

- CLIを実行すると専用GUIエディターが起動する。
- Rustで書かれていて、シングルバイナリ(!!!!!!)

Rustの文字列はUTF-8だからか、特に設定しなくても日本語の入出力に対応している。

ドキュメントがすっきりまとまっているので、今から「レポートを書くためにWordから別のものに乗り換えたい」という人にはおすすめしようかなと考えている。

## Word

嫌われがちだけど、機能を適切に使いこなせば大変優秀なツール。Gitとの親和性は最悪なので、データ解析やグラフのプロットと同じリポジトリで論文を書くというスタイルは難しい。Word本体の機能に共同編集、同時編集の機能があるようなので、そういった機能を利用したほうがよさそう。
[AWS Q&A 365][Kinesis]AWSのよくある問題の毎日5選 #39

# 1. Kinesis Producer Library (KPL)とは何ですか？
答え：Kinesis Producer Library（KPL）は、Amazon Kinesis Data Streamsが提供するライブラリで、データストリームへの書き込みプロセスを簡素化するものです。バッチ処理、集約、自動再試行などの機能を提供し、データ取り込みの効率性と信頼性を向上させます。

# 2. KPLを使用する利点は何ですか？
答え：KPLには、データ取り込みの効率性と信頼性の向上、データレコードのバッチ処理と集約、障害時の自動再試行、および複数のプラットフォームやプログラミング言語のサポートなど、いくつかの利点があります。

# 3. KPLの主要な概念は何ですか？
答え：KPLの主要な概念には、バッチ処理、集約、パーティショニング、自動再試行が含まれます。バッチ処理と集約はAPI呼び出しの回数を減らし、データ取り込みの効率を向上させます。パーティショニングは、スケーラビリティを向上させるために、データを複数のシャードに分散します。自動再試行により、障害が発生してもデータが取り込まれるようになります。

# 4. KPLはプロデューサーコードとどのように統合できますか？
答え：KPLは、Amazon Kinesis Data Streamsが提供するKPL APIを使用してプロデューサーコードに統合できます。プロデューサーコードはKPL APIを使用してKPLを設定および初期化し、それを使用してデータレコードをデータストリームに書き込むことができます。

# 5. KPLはどのようなプラットフォームをサポートしていますか？
答え：KPLは、Amazon Linux、Windows、macOS、およびさまざまなLinuxフレーバーなど、複数のプラットフォームをサポートしています。また、Java、Python、C++など、複数のプログラミング言語もサポートしています。
[AWS Q&A 365][Kinesis]Daily Five Common Questions #39

# 1. What is the Kinesis Producer Library (KPL)? 
Answer: The Kinesis Producer Library (KPL) is a library provided by Amazon Kinesis Data Streams that simplifies the process of writing to data streams. It provides features such as batching, aggregation, and automatic retries to improve the efficiency and reliability of data ingestion. 

# 2. What are the advantages of using the KPL? 
Answer: The KPL provides several advantages, such as improved efficiency and reliability of data ingestion, batching and aggregation of data records, automatic retries in case of failures, and support for multiple platforms and programming languages. 

# 3. What are the key concepts of the KPL? 
Answer: The key concepts of the KPL include batching, aggregation, partitioning, and automatic retries. Batching and aggregation help to reduce the number of API calls and improve the efficiency of data ingestion. Partitioning helps to distribute the data across multiple shards for better scalability. Automatic retries help to ensure that data is ingested even in the case of failures. 

# 4. How can the KPL be integrated with producer code? 
Answer: The KPL can be integrated with producer code by using the KPL API provided by Amazon Kinesis Data Streams. The producer code can use the KPL API to configure and initialize the KPL, and then use it to write data records to the data stream. 

# 5. What are the supported platforms for the KPL? 
Answer: The KPL is supported on several platforms, including Amazon Linux, Windows, macOS, and various flavors of Linux. It also supports several programming languages, including Java, Python, and C++.
プレースホルダって？

# プレースホルダって？
プレースホルダは、プログラミングやデータベースにおいて、ある値や情報を後で入力するために一時的に置いておくための記号や変数のことを指します。

一般的には、データベースクエリーにおいて、SQLインジェクション攻撃を防ぐために使用されます。プレースホルダを使用すると、SQLクエリーを実行する前に、変数の値を確実にエスケープ処理することができます。これにより、攻撃者がクエリーに悪意のあるコードを挿入することができなくなります。

また、プログラミングにおいても、プレースホルダを使用することがあります。たとえば、Pythonの場合、文字列フォーマットにおいて、{}をプレースホルダとして使用し、後で変数の値を代入することができます。

また、Webアプリケーション開発において、フォームの入力値を取得する際にも、プレースホルダを使用することができます。たとえば、HTMLのformタグ内において、input要素のname属性にプレースホルダを指定することで、後で入力された値を簡単に取得することができます。

プレースホルダを使用することで、値の入力忘れや誤りを防ぐことができます。また、コードの可読性を高め、保守性を向上させることができます。ただし、適切な方法でプレースホルダを使用しないと、脆弱性を生み出すこともあるので、注意が必要です。


特に、SQLインジェクション攻撃を防ぐために、プレースホルダを使用する際には、以下のようなポイントに注意する必要があります。

1. 使用するデータベースに応じたプレースホルダの形式を使用する。
1. プレースホルダに入力されるデータの型に合わせた変換を行う。
1. プレースホルダに入力されるデータに対して、適切なバリデーションを行う。
1. プレースホルダを使用するだけでなく、データベース接続時に適切な権限設定を行う。
これらの対策を実施することで、SQLインジェクション攻撃を防ぐことができます。



SQLインジェクション攻撃を防ぐためにプレースホルダを使用する例を示します。

例えば、以下のようなSQLクエリーを実行する場合を考えてみます。

```sql
SELECT * FROM users WHERE username='John' AND password='password';
```
このクエリーにおいて、usernameとpasswordはユーザーが入力する値となります。しかし、このままでは入力値によっては、SQLインジェクション攻撃を受ける可能性があります。

そこで、プレースホルダを使用して、入力値をエスケープ処理することで、SQLインジェクション攻撃を防ぎます。以下は、プレースホルダを使用したSQLクエリーの例です。

``` sql
SELECT * FROM users WHERE username=? AND password=?;
```
このクエリーにおいて、?がプレースホルダとなります。実行時には、?に対応する値を別途指定することで、クエリーを実行します。この際、値はエスケープ処理が適用され、SQLインジェクション攻撃を防ぐことができます。

プログラミング言語によってプレースホルダの形式や使用方法は異なるため、具体的な例については、言語ごとに異なります。例えば、Pythonでのプレースホルダの使用方法は以下のようになります。

```Python
import mysql.connector

mydb = mysql.connector.connect(
  host="localhost",
  user="yourusername",
  password="yourpassword",
  database="mydatabase"
)

mycursor = mydb.cursor()

sql = "SELECT * FROM customers WHERE address = %s"
adr = ("Yellow Garden 2", )

mycursor.execute(sql, adr)

myresult = mycursor.fetchall()

for x in myresult:
  print(x)
```
上記の例では、%sがプレースホルダとなります。実行時には、プレースホルダに対応する値をタプルで指定することで、クエリーを実行します。


また、JavaScriptでのプレースホルダの使用方法は、以下のようになります。

```javascript
const sql = "SELECT * FROM customers WHERE name = ?";
const name = "John";

connection.query(sql, [name], (err, result) => {
  if (err) throw err;
  console.log(result);
});
```
上記の例では、?がプレースホルダとなります。実行時には、プレースホルダに対応する値を配列で指定することで、クエリーを実行します。

これらの例では、プレースホルダを使用することで、入力値のエスケープ処理や、SQLインジェクション攻撃を防ぐことができます。ただし、注意点として、プレースホルダを使用しても、適切なバリデーションや権限設定を行わなければ、完全にセキュリティを保障することはできません。
【レビューで指摘されがちシリーズ】型パターン（宣言パターン）を使おう！

レビューで指摘された内容をそのまま放流するシリーズ。[まとめページ](https://qiita.com/lx-sasabo/items/c2d2e5ccae10ff3ecabd) もあります。

こんな C# のコードがありました。

```C#
class Animal { }
interface IHuman { }

class Man : Animal, IHuman { }
class Cat : Animal { }

class Hoge
{
    // IHuman に対して何かしらを行うメソッド
    static void DoSomething(IHuman human) { }

    // 引数 anumal が IHuman をもつようなら DoSomething() を行う
    // IHuman をもたない場合は何もしない
    static void Method(Animal animal)
    {
        if (animal is not IHuman)
        {
            return;
        }

        var human = (IHuman)animal;
        DoSomething(human);
    }
}
```

これに対しレビューでコメントをもらいました。

> 型パターンをつかえば、キャストしなくて良さそうに思いました。

ああ、なんで気づかなかったんでしょう。こう書けます。

```C#
    static void Method(Animal animal)
    {
        if (animal is IHuman human)
        {
            DoSomething(human);
        }
    }
```

気づかなかった理由の一つとして、型パターンは switch 文のときに使うという思い込みがあったように思います。（言い訳です。「型パターンが使えそうです」の指摘は何回も指摘をくらっているので、いい加減マスターしたいです。この記事がきっかけで自分の意識が変わることを神頼みしておきます…）

https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/patterns#declaration-and-type-patterns

公式によると上記の `anumal is IHumnan human` のように `human` として変数宣言を行う方法を「宣言パターン」というそうです。
「型パターン」というのは型をチェックするまでが「型パターン」のようです。

![パターン - is および switch 式を使ったパターン マッチング。 _ Microsoft .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/d82d2525-3372-f91e-5c50-00cb1abba41f.png)
Flutter1.0でamplifyのAuthを使ってCognito認証しようとしたら `No builder registered for SecureStorageInterface`が発生した時の対処


# TL;DR;

ガイド通りに設定したのに`No builder registered for SecureStorageInterface`ってエラーが出てよくわかりませんでした。

Authのplugin追加時にストレージのオプションを設定して解決できました。

```dart
      AmplifyAuthCognito authPlugin = AmplifyAuthCognito(
        secureStorageFactory: AmplifySecureStorage.factoryFrom(
          webOptions: WebSecureStorageOptions(
            persistenceOption: WebPersistenceOption.inMemory,
          ),
        ),
      );

      await Amplify.addPlugins([
        authPlugin,
      ]);
```

iOSとAndroidだけのプロジェクトであっても、storageFactoryの指定が必要なので、必要ないwebのオプションだけ指定して追加する必要がある。


# はまったこと


[Amplifyのガイド](https://docs.amplify.aws/lib/auth/managing_credentials/q/platform/flutter/)には「iOSはxxx, Androidはxxxが利用されます。カスタマイズしたい人はオプションでオーバーライドしてね。」というな書き方がされているので、それに従ってプラグインの追加だけの実装をしたら以下のエラーが発生しました。


```
CredentialStoreStateMachine | Emitted error: Bad state: No builder registered for SecureStorageInterface
```
SecureStorageの保存先が定義されていないというような内容


# 解決した内容

[flutterのamplify_auth_cognitoの実装サンプル](https://pub.dev/packages/amplify_auth_cognito/example
)に丁寧にコメントされてました。
今回のプロダクトはiOSとAndroidだけのビルドだけで、Flutterのデフォルトの実装(ios=keychain, android=EncryptedSharedPreferences)で問題ないので個別の設定は不要なのですが、SecureStorageのファクトリーをなにかしら指定しないと落ちるので、適当にダミーで一番手っ取り早いwebのオプションを指定して回避できました。

```dart
  AmplifyAuthCognito authPlugin = AmplifyAuthCognito(
    secureStorageFactory: AmplifySecureStorage.factoryFrom(
      webOptions: WebSecureStorageOptions(
        persistenceOption: WebPersistenceOption.inMemory,
      ),
    ),
  );

  await Amplify.addPlugins([
    authPlugin,
  ]);
```

Flutterに関してはAmplifyに関することであってもFlutterのドキュメントの方がよく書かれている印象です。
困ったらFlutterのドキュメントを漁りましょう。


# 参考文献

- https://pub.dev/packages/amplify_auth_cognito/example
- https://docs.amplify.aws/lib/auth/managing_credentials/q/platform/flutter/
【NextJS】wbrと white-space: "pre-wrap"を使って(ほぼ)ライブラリレス爆速スタイリング

# 本編
唐突ですが記法が特殊なNextJSのスタイリングで私なりのベストプラクティスを記事にしてみますたー。

## 1.デバック時にコンポーネントの境目をわかりやすく。
```tsx
const Devmode = process.env.NEXT_PUBLIC_TEST === 'DEV' ? "#000" : "#fff";
const DevmodeBack = process.env.NEXT_PUBLIC_TEST === 'DEV' ? "#fff000" : "#000";
```
localhostでのデバック時のみコンポーネントごとに色が変化するようにしていて、
アプリケーション公開時には自動的に背景が黒一色になるように実装しています。
NextJSの```style={{}}```であればcssにも変数を組み込めるのでENVと組み合わせられて便利です。

## 2.```<wbr/>```タグと```whiteSpace: "pre-wrap"```でテキストの改行を自動化

```<wbr/>```を使えば改行でもレスポンシブ的な挙動を実現できます。
ただwhiteSpace: "pre-wrap"をスタイルとして設定する必要があり、すこし工夫が必要です。

```tsx
<div className={style.Inner} style={{
                        color: "#000",
                        width: "100%",
                        height: "100%",
                        display: "flex",
                        justifyContent: "center",
                        alignItems: "center",
                        whiteSpace: "pre-wrap",
                    }}>
```

```tsx
 <h1 style={{
     margin: `0px ${w}px 0 ${w}px`,
    }}>
        projectV is a metaverse & web3 project that aims to create a new world through<wbr/>
        the fusion of the real and virtual worlds <wbr/>
        by VARIUS<wbr/>
</h1>
```

# 今回の記事で使ったソースコード


https://github.com/nknighta/V/blob/main/src/element/elementHome.tsx
w-screen(width: 100vw)を使用すると左右の余白が当たらなくなる件について

開発でtailwindcssを使用、詰まったので書き残し
概要：w-screenを使用すると余白（右側）が空かないので対処する
## Tailwind CSSとは
Tailwind CSSは、ユーティリティファースト（Utility-first）のCSSフレームワークで、Web開発者が迅速かつ簡単に効率的なデザインシステムを構築できるように設計されています。
[ドキュメントはこちら](https://tailwindcss.com/docs/installation)
## 詰まったところ
w-screenを使用すると、画面幅に応じて自動で幅を設定してくれるとても親切なものなのですが、余白（padding）を開けようとすると、左側にしか余白ができない、、なぜだ
## 原因
要素の幅が画面幅に固定されてしまっているため
## 対処法
CSSの関数[calc](https://developer.mozilla.org/ja/docs/Web/CSS/calc)を使う。

対応前のコード（抜粋）
```html
<div class="w-screen px-4 lg:w-[1000px] lg:mx-auto">
 <!-- 内容 -->
</div>
```

対応後
```html
<div class="w-[calc(100vw-32px)] px-4 lg:mx-auto lg:max-w-[1000px]">
 <!-- 内容 -->
</div>
```
w-screen(100vw)で画面幅いっぱいに広げつつ、32px(16px × 2)の余白を作り出すため、calcでその分だけ引いてあげる。

ちょっとしたことだけど、大事だなーと思った、CSSって難しいですね。以上
【ChatGPT】ChatGPTを使って、日本語インドネシア語の例文作成・翻訳を自動化した話

2023年に入り、巷でかなり話題になっているのがAI技術のChatGPT関連の情報ですね。

今回は、ChatGPTを活用して、日本語とインドネシア語の例文作成作業・翻訳作業を自動化したので、その方法について詳しく紹介していきます。

## 成果物はこちら

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">【インドネシア🇮🇩語学習者必見】<br>インドネシア語アプリ<a href="https://twitter.com/BINTANGO88?ref_src=twsrc%5Etfw">@BINTANGO88</a> では、素材のデータにChatGPTを活用<br><br>動きは動画で<br>1️⃣単語入力<br>2️⃣インドネシア語での例文を作成<br>3️⃣例文の日本語訳を生成<br>※生成後微調整<br><br>こちらのスプシの雛形が欲しい方は、RTとリプ📩に🙋‍♀️をいただければ後日🎁 <a href="https://t.co/NfPZ4Ls51q">pic.twitter.com/NfPZ4Ls51q</a></p>&mdash; 菊池哲平@jogja🇮🇩 | 海外×エンジニア (@tpi29) <a href="https://twitter.com/tpi29/status/1646459056792674304?ref_src=twsrc%5Etfw">April 13, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 準備するもの
こちらの方法は、スプレッドシートとOpenAI社のAPIを活用しているため、以下の2点が必要になります。

- Googleアカウント(スプレッドシートの利用のため)
- OpenAI社のアカウント
【画像付き】OpenAI（ChatGPT）のAPIキー取得手順
https://programming-zero.net/openai-api-key/

## 作成手順
作成手順については、以下の記事でより詳細に紹介しております。

[![chatgpt-auto-translate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/d8735b5b-79b9-ed70-4707-73c8a7c8114b.png)](https://jogjalanjalan.com/chatgpt-japanese-indonesian-translate/)

https://jogjalanjalan.com/chatgpt-japanese-indonesian-translate/


## 工夫した点
スクリプトを投げる際に、以下のように条件を指定したりすることでより違和感のない文章を作成するように指示しました。

```
"インドネシア語の例文「" + prompt + "」を日本語に翻訳してください。（文体：ですます調、表現方法：教科書のような違和感のない優しい丁寧な日本語表現）"
```

## 参考記事

https://jogjalanjalan.com/chatgpt-japanese-indonesian-translate/

https://note.com/seimeitsuzaki/n/n07fa00f41961
GitHubの使い方をChatGPTに教えてもらったのでまとめてみた

# Git - ChatGPT

## 初心者向けGitの使い方と運用方法

### Gitの基本的な使い方

1. **Gitのインストール**

   公式サイトからGitをダウンロードしてインストールします。

2. **リポジトリの作成**

   ターミナルで以下のコマンドを使用して新しいリポジトリを初期化します。

    ```bash
    $ git init
    ```

3. **ファイルの追加**

   Gitで管理したいファイルを追加します。

    ```bash
    $ git add ファイル名
    ```

4. **コミット**

   ファイルの変更を保存するには、以下のコマンドを使用します。

    ```bash
    $ git commit -m "コミットメッセージ"
    ```

### Gitの運用方法

1. **ブランチの作成**

   開発環境ごとにブランチを作成します。

    ```bash
    $ git branch ブランチ名
    ```

2. **ブランチの切り替え**

   作業するブランチを変更します。

    ```bash
    $ git checkout ブランチ名
    ```

3. **プッシュ**

   変更履歴をリモートリポジトリにアップロードします。

    ```bash
    $ git push リモート名 ブランチ名
    ```

4. **プル**

   リモートリポジトリの変更を取得します。

    ```bash
    $ git pull リモート名 ブランチ名
    ```

### ブランチの削除

```bash
$ git branch -d ブランチ名
```

もしマージされていない変更がある場合は、強制的に削除します。

```bash
$ git branch -D ブランチ名
```

リモートリポジトリにも反映させる場合は次のコマンドを使用します。

```bash
$ git push リモート名 :ブランチ名
```

### 開発環境のブランチの構成

一般的な開発環境のブランチ構成例：

- **master**: 安定したバージョンを管理
- **develop**: 開発中の最新バージョンを管理
- **feature**: 個々の機能の開発を管理
- **release**: リリース前の最終確認用
- **hotfix**: 緊急の修正用

### 個人開発のブランチ構成

1. **master**: 安定したバージョンを管理
2. **feature**: 個々の機能の開発を管理

### 複数のfeatureブランチを作成する方法

1. **featureブランチの作成**

   ```bash
   $ git checkout -b feature/A
   ```

2. **機能の開発**

   feature/Aブランチで機能Aの開発を行います。

3. **feature/Aブランチをmasterにマージ**

   ```bash
   $ git checkout master
   $ git merge --no-ff feature/A
   ```

4. **次のfeatureブランチの作成**

   ```bash
   $ git checkout -b feature/B
   ```

5. **機能の開発**

   feature/Bブランチで機能Bの開発を行います。

6. **feature/Bブランチをmasterにマージ**

   ```bash
   $ git checkout master
   $ git merge --no-ff feature/B
   ```

### masterとmain、どちらを使うべきか

Git 2.28以降、デフォルトブランチの名称がmainに変更されています。現在ではmainブランチを使用することが一般的です。ただし、状況に応じてmasterブランチを使用することもできます。どちらを使用する場合でも、コードの品質を維持し、十分なコードレビューを行うことが重要です。
param is missing or the value is emptyエラーにハマった件について

このエラーはしばらく見ていなかった上に、そんなに詰まるようなところでもないのですが、今回はハマってしまった、、、

結論を伝えると、
scopeの問題でした。

controllerのnewアクションとcreateアクションを書いた後に、
以下のように記述して、submitを押すと、今回のエラーが出てきました。

このエラーの時は大体、以下の場合なので、「はいはい、また出たね」という感じでした。
* パラメータを送れていない
* タイポしている


```hoge.haml
= form_with url: user_path, method: :post, local:true  do |f|
  = f.check_box :hoge_id
  = f.hidden_field :user_id, value: current_user.id
  = f.submit "Submit", disable_with: 'Submiting...'
```

しかし、
パラメータを確認してみると、以下のようになっていて、渡ってきている、、、
```
{"utf8"=>"✓", "authenticity_token"=>"省略", user_id"=>"1", "hoge_id"=>"1", 省略}
```
以下はストロングパラメータだが、タイポかなと思って確認するが、それも違う、、、
```users_controller.rb
 private
    def user_params
      params.require(:user).permit(:user_id, :hoge_id)
    end    
```

じゃあ、何が違うのか、、、と色々と試行錯誤してみましたがエラーが解消されず。

そして、あることに気がつきました。
「scopeが違う、、、」と。

どういうことかというと、先ほどのストロングパラメータではざっくりいうと
「userモデルにuser_idとhoge_idを保存することを許可するよ」ということです。
```users_controller.rb
 private
    def interview_sheet_params
      params.require(:user).permit(:user_id, :hoge_id)
    end    
```
しかし、先ほどのパラメータだとおかしくて、正しくは、以下のようにならなければいけません。

```
{"utf8"=>"✓", "authenticity_token"=>"省略", "user"=>{"user_id"=>"1", "hoge_id"=>"1"}, 省略}
```



重要な部分だけ取り出すと、以下の部分です。

__上が間違いで下が正しい書き方です。__

要は、userモデルの中にuser_idとhoge_idが入っているよというのが下です。
上だと、どのモデルに送るのかが明示されていないので、データが存在しない振る舞いになるわけですね。
```
user_id"=>"1", "hoge_id"=>"1"
```
```
"user"=>{"user_id"=>"1", "hoge_id"=>"1"}
```

じゃあ、どうしたら良いかというと、scopeを使いましょう。
以下のようにscopeでモデル名を指定すれば、paramsが上から下のようになります。
```
= form_with url: user_path, method: :post, scope: :user, local:true do |f|
```

railsは色々と勝手にやってくれる反面、時々思った挙動にならないこともあるので、注意が必要ですね。
webエラーの簡単な説明


### webで見るエラーの簡単な説明

以下の表は、一般的なWebエラーの簡単な説明を含むテーブルです。

| ステータスコード | エラーの種類                       | 説明                                                                     |
|-----------------|------------------------------------|--------------------------------------------------------------------------|
| 100             | Continue                           | リクエストの先頭行が受信され、クライアントが継続することを通知する情報レスポンス |
| 200             | OK                                 | リクエストが成功し、要求されたリソースが正常に返されたことを示す         |
| 201             | Created                            | リクエストが成功し、新しいリソースが作成されたことを示す                 |
| 204             | No Content                         | リクエストが成功し、レスポンスボディにはコンテンツが含まれていないことを示す |
| 300             | Multiple Choices                   | 複数のリソースが利用可能であることを示し、ユーザーに選択する機会を与える   |
| 301             | Moved Permanently                  | リクエストされたリソースが移動されたことを示し、クライアントを新しい場所にリダイレクトする |
| 302             | Found                              | リクエストされたリソースが一時的に別のURLに配置されたことを示し、クライアントを新しい場所にリダイレクトする |
| 304             | Not Modified                       | クライアントにキャッシュされたバージョンのコンテンツが使用されていることを示す |
| 400             | Bad Request                        | リクエストが不正であることを示し、リクエストを処理できない               |
| 401             | Unauthorized                       | リクエストされたリソースにアクセスするための認証情報が不足している       |
| 403             | Forbidden                          | アクセスしようとしたページにアクセスする権限がない                       |
| 404             | Not Found                          | リクエストされたURLが見つからなかった                                     |
| 500             | Internal Server Error              | Webサーバーが処理中にエラーが発生した                                     |
| 502             | Bad Gateway                        | Webサーバーが上流のサーバーから正しいレスポンスを受け取れなかった         |
| 503             | Service Unavailable                | Webサーバーが一時的に利用できない                                         |