OmniAICreator/Qiita-1.07M huggingface dataset:
Nextjsでタブ機能を作ってみた

# はじめに
備忘録として残しています．
もっと良い書き方があれば，指摘していただけると幸いです．

# 見た目
![スクリーンショット 2024-07-12 215426.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736836/677b478c-73e2-3bb5-e516-77104289c9d5.png)

# コード
```page.tsx
"use client";

import { useState } from "react";
import Tab from "@/components/Tab";

const Page = () => {
  const [active, setActive] = useState(0);
  const tabNames = ["タブ1", "タブ2"];

  return (
    <div>
      <Tab active={active} setActive={setActive} tabNames={tabNames}>
        <h1>{tabNames[active]}</h1>
      </Tab>
    </div>
  );
};

export default Page;
```

```Tab.tsx
import { ReactElement } from "react";
import styled, { css } from "styled-components";

const Ul = styled.ul`
  display: flex;
  padding-left: 0;
  margin-bottom: 10px;
  border-bottom: 1px solid #ddd;

  & > li {
    position: relative;
    display: block;
    float: left;
    margin-bottom: -1px;
  }
`;

const Li = styled.li<{ $isActive: boolean }>`
  > button {
    position: relative;
    display: block;
    padding: 10px 15px;
    margin-right: 2px;
    line-height: 1.4286;
    color: #555;
    text-decoration: none;
    background-color: #eee;
    border: 1px solid transparent;
    border-radius: 4px 4px 0 0;

    & :hover :active {
      outline: 0;
    }
  }
  ${({ $isActive }) =>
    $isActive &&
    css`
      > button {
        color: #337ab7;
        cursor: default;
        background-color: #fff;
        border: 1px solid #ddd;
        border-bottom-color: transparent;
      }
    `}
`;

const Tab = ({
  children,
  active,
  tabNames,
  setActive,
}: {
  children: ReactElement;
  active: number;
  tabNames: string[];
  setActive: React.Dispatch<React.SetStateAction<number>>;
}) => {
  return (
    <div>
      <Ul>
        {tabNames.map((tabName, index) => (
          <Li key={index} $isActive={index === active}>
            <button
              type="button"
              role="tab"
              onClick={() => {
                setActive(() => (active === index ? active : index));
              }}
            >
              {tabName}
            </button>
          </Li>
        ))}
      </Ul>
      {children}
    </div>
  );
};

export default Tab;
```

# 説明
Liコンポーネントとmap関数を使って，タブを表現しています．
変数activeには現在アクティブなtabのインデックスが代入されています．
activeとクリックされたボタンのindexを比較して，active状態を切り替えられるようにしました．
onClickの中身について，ボタンがクリックされるたびにレンダリングが実行されると思いますので，改良する必要があるかと思います．
Sequence Makerで測定器とUSB通信できない時はここをチェック！

## はじめに
Sequence MakerはExcelから測定器を制御可能にするアドインです。Sequence Makerはいろいろなインターフェイスに対応しているのですが、なかなかうまく測定器と通信できない時があります。この記事ではUSB通信がうまくいかない時のチェック項目を解説していきます。Sequence Makerについての詳細は以下の記事を参照ください。

https://qiita.com/sequencemaker/items/8e6a370ab0a793a06a3b

:::note warn
***お断り***
本記事の内容はSequence Maker開発元の公式見解ではなく、あくまでも個人が趣味の範囲内で執筆しているものです。記事の内容について開発元へ問い合わせることはお控えください。ご質問・要望などは各記事のコメント欄へお願いいたします。
:::

## 接続ケーブルをチェック！
### ✅パソコンと測定器は正しく接続されていますか？
USB通信する際にはパソコンと測定器をUSBケーブルで接続します。USBケーブルは一般に市販されているものでOKです。値段もそんなに高くはありません。測定器の多くはType-BまたはMini-Bと呼ばれるコネクターが多いと思いますが、最近ではType-Cを採用しているものも増えてきました。コネクターにあったケーブルを使用しましょう。1つだけ注意点があります。

:::note alert
**注意**
USBケーブルを間違えてLANコネクターに刺さないようにしましょう。
ほぼ確実にLANコネクターが死亡します。
サイズがほぼ一緒なので、手探りで差し込んだりすると刺さってしまいます。
:::

以下の記事も参考にしてください。

https://qiita.com/sequencemaker/items/08d1fb66d1ba284e00a4#gpib

## ドライバーをチェック！
### ✅ドライバーは正しく認識されていますか？
測定器の種類によっては専用のUSBドライバーをインストールする必要があります。マニュアルなどで確認しましょう。専用ドライバーは測定器メーカーのWebサイトからダウンロードできることが多いです。「型名 USBドライバー」といったキーワードで検索すると見つかると思います。

ドライバーがインストールできたら、デバイスマネージャーで正しく認識されているか確認しておきましょう。

### ✅メモリ整合性の設定がONになっていませんか？
Windowsのメモリ整合性の設定がONになっていると、USBドライバーがうまく認識できない場合があります。デバイスマネージャー上では黄色のビックリマークが表示されます。プロパティからデバイスの状態を見ると

```
ドライバーが壊れているか、ドライバーがない可能性があります。（コード39）
```

と表示されます。このような場合はメモリ整合性の設定をOFFにして、Windowsを再起動してみましょう。メモリ整合性の設定は以下にあります。

Windowsの設定　→　更新とセキュリティ　→　Windowsセキュリティ　→　デバイスセキュリティ　→　コア分離　→　コア分離の詳細　→　メモリ整合性

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/c89a51a0-b5a0-6774-2c89-2e5e9be06f8a.png)


## 通信設定をチェック！
### ✅測定器の通信設定はUSBになっていますか？
測定器によってはUSB以外にもRS-232CやLANなど他のインターフェイスを搭載しているものがあり、その場合どのインターフェイスを使用するか選択式の場合があります。測定器のマニュアルを参照し、使用するインターフェイスの設定が「USB」になっていることを確認しましょう。

### ✅Sequence Makerのインターフェイス設定は正しいですか？
USB接続の場合は以下のいずれかのインターフェイスを使用します。

- 仮想COM（CDC）の場合：「RS-232C/USB」から使用するCOMポートを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/10571c7d-4b87-a1a3-8692-ccae07bb9dce.png)


- TMC（Test and Measurement Class）の場合：「VISA」から使用するVISAアドレスを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/ad2f233b-cdda-98a5-7d7c-3f49b71bb88f.png)
TMCを使う場合は、予めNI VISAやKeysight IOライブラリ・スイートをインストール必要があります。

:::note warn
**注意**
VISAは複数インストールするといろいろなトラブルの元になるので、1種類だけにしておきましょう。
:::

https://www.ni.com/ja/support/downloads/drivers/download.ni-visa.html#521671

https://www.keysight.com/jp/ja/lib/software-detail/computer-software/io-libraries-suite-downloads-2175637.html

### ✅TMCの場合は「EOMを使用する」のチェックを入れてみる、または外してみる
測定器によっては、EOMを使用する製品と使用しない製品がありますので、試しに切り換えてみてください。

## まとめ
USBはケーブルもコネクターに刺さる物を選べば良いですし、アドレス設定なども無いので、比較的簡単に繋がる気がします。あとはUSBドライバーをちゃんと入れる点だけ注意しましょう。
[Android] Roomライブラリの入れ方

ローカルデータベースであるRoomを入れようとしたんですが、ハマったので知見を残しておきます。

build.gradle.kts(Module :app)に入る


```
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    <!--これを追加する -->
    id("kotlin-kapt")
}
```
```
dependencies {
    implementation("androidx.core:core-ktx:1.13.1")
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.3")
    implementation("androidx.activity:activity-compose:1.9.0")
    implementation(platform("androidx.compose:compose-bom:2023.08.00"))
    implementation("androidx.compose.ui:ui")
    implementation("androidx.compose.ui:ui-graphics")
    implementation("androidx.compose.ui:ui-tooling-preview")
    implementation("androidx.compose.material3:material3")
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.2.1")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
    androidTestImplementation(platform("androidx.compose:compose-bom:2023.08.00"))
    androidTestImplementation("androidx.compose.ui:ui-test-junit4")
    debugImplementation("androidx.compose.ui:ui-tooling")
    debugImplementation("androidx.compose.ui:ui-test-manifest")
<!--この文章を追加する-->
    var roomVersion = "2.6.0"
    implementation("androidx.room:room-ktx:$roomVersion")
    kapt("androidx.room:room-compiler:$roomVersion")

}
```
Qiita CLIを使って使い慣れたVScodeで記事を書く

# はじめに
知らないうちに[Qiita CLI](https://github.com/increments/qiita-cli)なるものができてたので、使ってみます。

ちなみに私は数年前、これと似たような位置付けの[Qiita Sync](https://github.com/ryokat3/qiita-sync)なるもの使ってみて、「結局Web UIのほうが書きやすいや～」となってやめた記憶があります。


# 環境
- Node.js v20.12.2
- Windows11 23H2

:::note info
Qiita CLIではNode.js 18.12.0以上のバージョンが必須ですが、この記事では導入方法については触れません。
:::

# 環境構築
作業用のディレクトリを作成し、パッケージを入れ、ログインします。

```bash
mkdir qiita
cd qiita

npm install @qiita/qiita-cli --save-dev
npx qiita init
npx qiita login
```

事前準備はこれだけ。

# つかってみる
記事を作ります。

```bash
npx qiita new [FileName]
```

実行すると、publicディレクトリ配下に、`[FileName].md`というファイルが生成されています。

デフォルトの中身はこんな感じ。

```md
---
title: newArticle001 # 記事のタイトル
tags:
  - "" # タグ（ブロックスタイルで複数タグを追加できます）
private: false # true: 限定共有記事 / false: 公開記事
updated_at: "" # 記事を投稿した際に自動的に記事の更新日時に変わります
id: null # 記事を投稿した際に自動的に記事のUUIDに変わります
organization_url_name: null # 関連付けるOrganizationのURL名
slide: false # true: スライドモードON / false: スライドモードOFF
---
# new article body
```
YAML Front Matter関連の記述だけですね。
ここに、タイトルやタグなどをyamlと同等の形式で記述します。

プレビューは、`npx qiita preview`で確認できるようです。


実際に、この記事は、Qiita CLIを利用して、VScode上で書いていますが、意外といい感じですよね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3283241/61649048-c0de-8216-d2c9-743125e3e29f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3283241/d9eab978-38ba-8b14-daa8-572bc9568fa0.png)


公開は、`npx qiita publish [FileName]`で行えるようです。

# おわりに
私自身、エディタに対してそこまでのこだわりはないのですが、Copilotによる補助などもあり、これはこれで便利なのかなと思いました。

個人的に引っかかる点があるとするならば、画像の取り回しでしょうか。
Qiita CLI本体には画像のアップロード機能はないようですので、画像をアップロードする際は、別途Qiitaのページからアップロードする必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3283241/e1d1d8b4-9682-00a0-9bcc-274e3e4f12b6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3283241/bdba04e3-2f8b-5201-14c5-2fe1ae724f1b.png)

画像のアップロードまでできると、もっと使いやすくなるのかな～と感じました。

それでも、オフラインの環境で書き溜めができたり、VScodeの拡張機能を使って書きやすくなったりと、使い所はいろいろあるかなと思います。

それでは。
【FileMaker】誰得って、自分得のエラー処理文言

今回は、[Qiita Engineer Festa 2024](https://qiita.com/official-campaigns/engineer-festa/2024)からのお題で出ていた、「[この記事誰得？](https://qiita.com/yu_uk/items/a008cf18213dde699a0f)」です。

タイトルで、「自分得」って入れましたが、みんな得になってほしいエラー処理での文言統一です。

# どの言語？
FileMaker

# どのレベルの人に向けての記事？
FileMakerでスクリプトを組み始めた人

# エラー処理の文言をカスタム関数に登録する
これが、最強なんですわ。
自分でクライアントのAppを開発する時は、自分仕様の開発規約のファイルに色々と実装して保持しています。
今回は、その中から、エラー処理の文言をカスタム関数に登録すると、めっちゃ楽だよ、と言う話です。

# 登録するカスタム関数
こんな感じでベーシックに持っています。
![スクリーンショット 2024-07-12 22.58.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/4d81ce28-613d-1cbc-5214-5215bc9dbd4c.png)
開発するAppによっては、ベーシックなものを追加していくわけです。

この中で毎回活躍するのは、エラー処理時の文言になります。
システムエラーの時とか、
![スクリーンショット 2024-07-12 22.42.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/f3a942f9-342f-7461-a914-3d4afeb0171e.png)

検索でレコードがヒットしない時とか、
![スクリーンショット 2024-07-12 22.42.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/60ac1801-df89-8083-d5da-6edf42e811ee.png)

# スクリプトでの使い方
スクリプトでは、エラーコードごとにカスタム関数に登録したエラーメッセージを出します。
![スクリーンショット 2024-07-12 22.49.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/5ef706bb-1707-78f2-9e67-fea8c44ebeaf.png)

# エラー文言が統一されることの利点
これは、エラー文言を少し変えてほしい、などの要望がクライアントからあった時に、いちいちスクリプトを修正しなくても済みます。
再テストは、ほぼゼロになります。
ほぼ、というのは、何がゼロにならないかというと、エラー文言の中で、エラー情報を出力したい時、カスタム関数に登録した文言がちゃんとエラー情報を追加した内容になっているか、というのを確認する必要があるからです。

また、同じ動作で同じ文言が表示されるため、操作しているユーザもエラーが出た時にどうすればいいか迷わなくて済む、と言う利点もあります。
データがヒットしない場合、
「データはありませんでした。」
「データは0件です。」
「ヒットする検索条件を設定してください。」
とまちまちのメッセージが出てきたら、エラーコードが違うんじゃないか？とクライアントの不安要素にもなりがちです。

ということで、カスタム関数を使ったことない人も、これを機会に使ってみてください。
AtCoder 勉強記録[C++] その18

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)
# 本日解いた問題
## C - Coupon
[C - Coupon](https://atcoder.jp/contests/abc246/tasks/abc246_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n, k, x;
  cin >> n >> k >> x;
  vec a(n);
  ll res = 0;
  rep(i, n) {
    cin >> a[i];
    res += a[i];
  }
  ll cnt = 0;
  for(int i = 0; i < n; i++){
    cnt += a[i]/x;
  }
  cnt = min(cnt, k);
  k -= cnt;
  res -= cnt*x;
  for(int i = 0; i < n; i++){
    a[i] %= x;
  }
  sort(a.rbegin(), a.rend());
  for(int i = 0; i < n; i++){
    if(k==0) break;
    res -= a[i];
    k--;
  }
  cout << res << endl;
}
```
### 解法
すべての商品に対して、値段が0にならずに使用できるクーポンの数は`A/X`個数である。そのため、可能な限り値下げを行い、その後値下げした商品の値段が大きい順にクーポンを使用することで効率的にクーポンを使用できる。
## C - 1 2 1 3 1 2 1
[C - 1 2 1 3 1 2 1](https://atcoder.jp/contests/abc247/tasks/abc247_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
bool g[10][10];

auto makes(string s, int n){
  string sn = to_string(n);
  string res;
  res = s + " " + sn + " " + s;
  return res;
}

int main() {
  ll n;
  cin >> n;
  string res = "1";
  for(int i = 2; i <= n; i++){
    res = makes(res, i);
  }
  cout << res << endl;
}
```
### 解法
始めの文字列を1とする。文字列を引数とし次の文字列を出力する関数を定義することで答えが出力できる。
## C - Poem Online Judge
[C - Poem Online Judge](https://atcoder.jp/contests/abc251/tasks/abc251_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n, t;
  cin >> n;
  string s;
  map<string,pair<ll,ll>> tmp;
  rep(i, n) {
    cin >> s >> t;
    if(tmp.count(s) == 0){
      tmp[s].first = t;
      tmp[s].second = i+1;
    }
  }
  ll con = 0;
  ll res = 0;
  for(auto const&[k, v]: tmp){
    if(con < v.first){
      con = v.first;
      res = v.second;
    }
  }
  cout << res << endl;
}
```
### 解法
`map`を利用することで解いていく。`map`の`key`にポエムを入れ、`value`を`pair`とし、`first`に得点、`second`に提出順を入れることで結果が求まる。
Next.jsで外部URLの画像を安全に表示する方法

## 背景
Next.jsを使用していて、特定の公開URLから画像を表示させたい場合があります。以下のコードではうまくいきませんでした。
```
<Image
  src="https://oaidalleapiprodscus.blob.core.windows.net/xxx"
/>
```

## 解決策

Next.jsの設定ファイル（next.config.mjs）を修正して、特定のドメインからの画像取得を許可しました。
```
/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'oaidalleapiprodscus.blob.core.windows.net',
        port: '',
        pathname: '**',
      },
    ],
  },
};

export default nextConfig;
```
この設定を適用することで、以下のように画像を表示することができるようになります。
```
<Image
  src="https://oaidalleapiprodscus.blob.core.windows.net/xxx"
/>
```
ABC250Dを解いた


筆者はレート600前後の茶色コーダ

7/11開催のADTで登場した以下のABCの過去問題を解いていく

https://atcoder.jp/contests/abc250/tasks/abc250_d

ADT(ALL)のページ

https://atcoder.jp/contests/adt_all_20240711_3/tasks/abc250_d

# 実装コード

$p\times q^3$ なので使う最大の素数は適当に$N^{\frac{1}{3}}$とみつもってエラトステネスのふるいをして
素数を列挙してみる。あとは素数なので組み合わせ被りを気にせず数え上げたらACした。

```python
import sys
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)

def sieve(n):
    is_prime = [True for _ in range(n+1)]
    is_prime[0] = False

    for i in range(2, n+1):
        if is_prime[i-1]:
            j = 2 * i
            while j <= n:
                is_prime[j-1] = False
                j += i
    table = [ i for i in range(1, n+1) if is_prime[i-1]]
    return is_prime, table

def main():
    N = rI()

    _, primes = sieve(int(N**(1/3)))
    M = len(primes)

    ans = 0
    for i,p in enumerate(primes):
        b = ans
        for j in range(i+1,M):
            num = p * (primes[j]**3)
            if num > N:
                break
            ans += 1
        if b == ans:
            break
    print(ans)
if __name__ == '__main__':
    main()

```


# まとめ
ABC250Dを解いた、エラトステネスのふるいを利用して素数を列挙して順番に数え上げた。

# 感想
この問題は解説見ずにとけた早解き寄りの問題だった。
このような問題は切り口をみつければ簡単に解けるがそれまでがなかなか大変ですね。

# 余談

エラトステネスのふるいってなかなか名前覚えられないの自分だけ？
サーバー管理の落とし穴：ネットワーク切断で引き起こした大失敗

# サーバー管理における痛恨の失敗談

こんにちは、私は現在学校でサーバー管理を担当しています。今回は、過去の失敗談をシェアすることで、皆さんが同じミスを犯さないように役立てていただければと思います。

## 事件の概要

ある日のこと、私は職員室で業務をこなしながらサーバー室のサーバーをリモートで操作していました。リモートデスクトップを利用して、ラック型のサーバーにアクセスしていたのです。サーバーは以下の構成でした

- **ファイルサーバ**
- **プロキシサーバ**
- **バックアップサーバ**

全てWindows Server 2019で運用していました。

## ネットワークトラブル発生

その日、ネットワークが不調になり、ネットに繋がったり繋がらなかったりする状況が続きました。夕方ということもあり、人も少なく、私は思い切ってプロキシサーバをオフにしてローカル環境の問題を確認しようとしました。

## 予期せぬクレーム

すると、突然別の部署の先生からネットに接続できないとのクレームが…。どうやら、その先生は学生とのオンライン面接の練習を行っていたのです。私の判断でインターネット接続を切断したことが、大きな問題を引き起こしてしまいました。

## リモート接続の悪夢

急いでリモートで接続しようとしましたが、何故か接続できません。プロキシサーバオフにしちゃいましたからね。こういう時に限ってサーバー室の鍵が見当たらないのです。なんとかスペアキーを借りてサーバー室に入りましたが、サーバーのコンソールの切り替えが3台分しかなく、普段からリモートで接続していたためプロキシサーバ　は繋いでいませんでした。なのでコンソールに繋ぎ直す必要が。
配線が絡まっており非常に難儀しました。
ログインするにも何故かログイン出来ない。パスワードが※なので気づくにかなり時間がかかりましたがNumLockがオンになっていたんです。トホホ。。。

## 教訓

あの時は、上司や先生からかなり怒られました。インターネットを止める際は、たとえ数分であっても周知することの重要性を痛感しました。分かっていたんですけどね。。。例えば、ファイルサーバでデータのコピーが行われている最中にネットワークを切断すると、データが消失する可能性もあります。今考えただけでも非常に恐ろしいことです。

この初歩的なミスのおかげで、以降は以下の点に注意するようになりました：

- **周知徹底**：インターネットを止める際には必ず関係者全員に事前に通知する。
- **適切なタイミング**：メンテナンスは誰もいない時間帯に行う。

## 結論

この失敗談は、若い頃の私が犯したミスですが、今では良い教訓となっています。皆さんもサーバー管理において同様の失敗をしないよう、事前の周知と適切なタイミングでのメンテナンスを心がけてください。

Qiita読者の皆さんには笑われてしまいそうな内容ですが、失敗から学び成長することが大切です。今後の皆さんの参考になれば幸いです。


## 余談

結果的に、ネットワークの不調の原因は「ネットワークループ」でした。別の部署でループが発生していたのです💦
これも含めて、トラブルシューティングの重要性を学んだ一件でした。

以上、私の失敗談でした。
torch.Tensor.to() でGPUに変数が転送できない？model.to(device)とは返り値が違う

## はじめに
NNモデルをGPUに転送する際には `model.to(device)` で転送することができます．
一方，単なる配列を転送する際にはこれではうまくいかなかったので，備忘録として記録します．

## 環境
* Python 3.11
* torch 2.3.0+cu118

## 方法
これだとうまくいかない．
```Python
tensor = torch.rand([2,3])
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

print(tensor.device)
# cpu

tensor.to(device)
print(tensor.device)
# cpu
```
`model.to(divece)` と違い，配列をGPUに転送する際には返り値をもらってくる必要がある．
```Python
tensor_gpu = tensor.to(device)
print(tensor_gpu.device)
# cuda:0
```

`torch.Tensor.to` の返り値は `Tensor` であるのに対し，`torch.nn.module.to` の返り値は `Self` であることが原因である．

## 参考文献
* `torch.Tensor.to` https://pytorch.org/docs/stable/generated/torch.Tensor.to.html
* `torch.nn.Module.to` https://pytorch.org/docs/stable/generated/torch.nn.Module.html#torch.nn.Module.to
Go言語のデータ型チートシート

# Go言語のデータ型チートシート

こんにちは、皆さん！今回は、Go言語で使用できるさまざまなデータ型をまとめました。

## Go言語のデータ型

| データ型       | サイズ       | 説明                                                                 |
|----------------|--------------|----------------------------------------------------------------------|
| `bool`         | 1ビット      | 真偽値（`true`または`false`）                                         |
| `int`          | 32ビットまたは64ビット | 符号あり整数。サイズは実行環境に依存                                |
| `int8`         | 8ビット      | 符号あり整数。範囲は-128から127                                      |
| `int16`        | 16ビット     | 符号あり整数。範囲は-32768から32767                                  |
| `int32`        | 32ビット     | 符号あり整数。範囲は-2147483648から2147483647                        |
| `int64`        | 64ビット     | 符号あり整数。範囲は-9223372036854775808から9223372036854775807      |
| `uint`         | 32ビットまたは64ビット | 符号なし整数。サイズは実行環境に依存                                |
| `uint8`        | 8ビット      | 符号なし整数。範囲は0から255                                         |
| `uint16`       | 16ビット     | 符号なし整数。範囲は0から65535                                       |
| `uint32`       | 32ビット     | 符号なし整数。範囲は0から4294967295                                  |
| `uint64`       | 64ビット     | 符号なし整数。範囲は0から18446744073709551615                        |
| `uintptr`      | 32ビットまたは64ビット | ポインタのアドレスを格納するための符号なし整数。サイズは実行環境に依存 |
| `float32`      | 32ビット     | 単精度浮動小数点数                                                   |
| `float64`      | 64ビット     | 倍精度浮動小数点数                                                   |
| `complex64`    | 64ビット     | 実部と虚部がそれぞれ`float32`の複素数                                |
| `complex128`   | 128ビット    | 実部と虚部がそれぞれ`float64`の複素数                                |
| `byte`         | 8ビット      | `uint8`のエイリアス。バイトを表す                                     |
| `rune`         | 32ビット     | `int32`のエイリアス。Unicodeコードポイントを表す                      |
| `string`       | 可変         | 文字列。UTF-8エンコーディングされたバイトのシーケンス                  |
| `array`        | 固定長       | 同じ型の要素の固定長のシーケンス                                      |
| `slice`        | 可変長       | 同じ型の要素の可変長のシーケンス                                      |
| `map`          | 可変長       | キーと値のペアのコレクション                                          |
| `struct`       | 可変         | フィールドの集合                                                     |
| `interface`    | 可変         | メソッドの集合                                                       |
| `chan`         | 可変         | ゴルーチン間の通信に使用されるチャネル                                |
| `function`     | 可変         | 関数の型                                                             |

## まとめ

Go言語には、さまざまなデータ型が用意されており、それぞれ異なる用途に適しています。型安全思考！！型が好きになってきました。TypeScriptなり型を使用するのは必須に近づいてきている昨今(20240712現在)なので型についての理解を深めていきましょう！！
先輩の言葉にハッとした、しくじりエンジニア

今回は、[Qiita Engineer Festa 2024](https://qiita.com/official-campaigns/engineer-festa/2024)からのお題で出ていた、「[しくじりエンジニア！私みたいになるな！](https://qiita.com/official-events/fd39ed8cc0dcc9829621)」のポエムです。

# どんな種類のしくじり？
技術的なしくじりではなく、コミュニケーション的なしくじりです。

# 登場人物
私：プログラマーコースのある専門学校を卒業して新卒入社
同期（Aさん)：門外漢の学校から新卒入社
先輩：門外漢の職種から中途入社

# いつ？
あれは私が就職して初年度か2年目の頃。

# 誰が？
私が

# 誰に？
同期に

# 何があった？
「なんでこんなこともわかんないの？」と言い放った。

# なんで？
プログラムのとある箇所で説明の仕方を変えても変えても理解してもらえなかったから。

うわ、今思うだけでも私、サイテー
自分で言うのもなんだけど、新しい技術に触れるのが好きで、割とサラッと仕事をこなしてた時期だった。

# その後どうした？
同期は固まってしまい、空気が重くなり、見かねた先輩が私に忠告した。

「あのね、
あなたはすでにわかっていることでも、Aさんの理解のスピードは違うの。
ましてや予備知識なしでこの業界に飛び込んできたのは私もそうだから、Aさんの焦る気持ちもわかる。
それにね、
その人に合わせてわかるように説明するって、難しいと思うんだよね。
知識のレベルが違うから。
そこんとこ、努力してみて。」

頭から冷水被ったようにハッとし、同期に謝った。

# 今は？
「その人に合わせてわかるように説明する」に頭を使うようになった。

# しくじったおかげで今がある
あの体験がなかったら、きっと老害極まりない人になってたに違いない。
言霊ってよく言ったもんで、今でも人と話す時はあの体験が頭をよぎります。
先輩、ありがとうございました。
Rails APIモードでDevise Token Authがうまく動かない！？解決までの道のり

最近Railsで APIを作ろうと思って、Rails APIモードとDevise Token Authを使ってみたんですが、思わぬところでつまづいてしまいました。今回は、その問題を解決するまでの過程を、私なりにまとめてみました。

## 最初の状況
まず、こんな感じでプロジェクトを始めました：

- ` rails new my_api --api`  でAPIモードのRailsプロジェクトを作成
- Gemfileに` gem 'devise_token_auth' `を追加
- `bundle install `を実行
- `Devise Token Auth`の設定を行う

ここまではスムーズに進んだんですが、rails s でサーバーを立ち上げて、routesを確認しようとブラウザから http://localhost:3000/rails/info/routes にアクセスしたら

```
NoMethodError (undefined method `mount_devise_token_auth_for' for #<ActionDispatch::Routing::Mapper:0x00007f8f1c0b0a60>)
```
というエラーが！

## 原因を探る
最初は「もしかして、Gemfileに書き忘れたかな？」と思って確認したんですが、ちゃんと書いてありました。
次に、`config/routes.rb` を見直してみました：
```ruby
Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      mount_devise_token_auth_for 'User', at: 'auth'
      # 他のルーティング...
    end
  end
end
```
これも一見問題なさそう...。
ここで、「そもそもAPIモードって何が違うんだろう？」と思い、調べてみることにしました。

### APIモードの特徴を理解する
Railsガイドを読んでみると、APIモードには以下のような特徴があることがわかりました：

 - セッション管理が無効
 - クッキーの扱いに制限がある
 - ブラウザ向けの機能が多く無効化されている

これを見て、「あれ？DeviseってセッションとかCookieを使うんじゃなかったっけ？」と思い、Devise Token Authのドキュメントも読み直してみました。

## なんちゃって解決法
1. APIモードを少し緩める
`config/application.rb` に以下を追加：
```ruby
config.api_only = false
config.middleware.use ActionDispatch::Cookies
config.middleware.use ActionDispatch::Session::CookieStore
```
これで、セッションとクッキーが使えるようになるはず...！

2. CORSの設定
APIとフロントエンドが別々のサーバーで動く可能性を考えて、CORSの設定もしておきました：

``` ruby
# Gemfile
gem 'rack-cors'

# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'
    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head],
      expose: ['access-token', 'expiry', 'token-type', 'uid', 'client']
  end
end
```

3. Deviseの設定調整
`config/initializers/devise.rb` に以下を追加：
``` ruby
config.navigational_formats = [:json]
```

### 結果
これらの変更を加えたら...動きました！ブラウザからアクセスしても、あのエラーが出なくなりました。

### 学んだこと

- APIモードは便利だけど、認証系のgemを使う時は注意が必要
- セッションやクッキーの扱いを理解することが大切
- CORSの設定は早めにしておくと後々楽

### 参考にしたサイト：

[Rails Guides: APIモードについて](https://guides.rubyonrails.org/api_app.html)
[Devise Token Auth GitHub](https://github.com/lynndylanhurley/devise_token_auth)
[rack-cors gem]()
アンガーマネジメント

# はじめに
エンジニア、というよりは子供が魔の二歳児真っ只中であり、妻も私もピリピリしがちなので、アンガーマネジメントを学んでみた。

その結果諸々を、記載したい。。。

# 概要
**怒らないようにする**という単純なものではなく、
**怒りと上手に付き合って怒りをコントロールしていくんだぜ**というものです。

ひいては感情のコントロールが重要となってきます。

参考文献
　https://www.all-different.co.jp/column_report/column/angermanagement/hrd_column_94.html
　
　https://www.smbc-card.com/like_u/life/anger_management.jsp

　https://www.angermanagement.co.jp/about

# アンガーログ
怒りの記録「アンガーログ」をつけておくことが有効な手段の一つとされています。

何に対して腹を立てやすいのか、その傾向が分かるようになり、あらかじめどのように行動したらよいかが見えてきます。

というわけで、怒りの記録を１週間ほどつけてみました。

現状だと家庭関係が多い傾向にありますね。。

[子供関係]
・子供（２歳）がオムツを返させてくれなかったこと
・子供がお着替えしなかったこと
・子供が私の股間を蹴ったことorz、メガネや顔を蹴ったこと

 [嫁関係]
・嫁がよく分からん感じに怒ったこと
・で、怒られたのを我慢していたら、顔が死んでいたらしくそれもまた怒られ、私も怒るスーパー負のループ

[その他]
・自分の意見が無視されたこと
・頑張って説明しても、一ミリも理解してくれなかったこと
・歩きタバコしてる人がいる時(特に子供と一緒に行動してる時！)
・子供を抱っこしてる時に、子供の目線の位置間近で平気日傘さす奴


法的な話や区の条例は以下の通り（区の条例は独身自体に住んでいた北区を例として挙げてみる）

※受動喫煙防止法

https://www.hokeniryo.metro.tokyo.lg.jp/kensui/tokyo/kangaekata_public.html

※参考：東京都北区の条例

https://www.city.kita.tokyo.jp/kankyo/jutaku/kankyo/kituenn/rozyoukituenn.html



# 怒りへの対処方法

### 深呼吸
深呼吸することで冷静さを取り戻しやすくなります。

※居眠り防止のところにも出てきた深呼吸
　<font color="Red">呼吸メッチャ大事</font>

### 怒るのではなくリクエスト
怒りの言葉ではなく、<font color="Red">「相手にして欲しいこと」をリクエストする形で伝える</font>


### 「XXXすべき」という価値観は不要！
自分の中に「XXXすべき」といった理想や価値観へのこだわりが多く、強いほど、怒りが生まれやすくなります。

色んな人が色んな考え方があって良いと思うし、色んな人がいるのが組織です。
そのため、<font color="Red">"べき"という考え方を捨てる</font>

# 最後に
私が紹介したのはアンガーマネジメントの一部で、私が特に重要だと思ったことを挙げてみました。

家庭も仕事もそつなくこなすのが一流だと思うので、家庭も含めてアンガーマネジメントを引き続き使っていこうと思う。

以上
【2024マラソン25】クリスタを複数端末でクラウド同期すると作業が捗る

# 何の記事？
クリスタをスマホやタブレットなど、複数端末で操作する場合に効率よく進める方法について書きました。

# 誰向け？ どんな役にたつ？
- クリスタを複数端末で使いたい人
- クリスタを複数端末で使う場合の設定について、気になる人

# あらすじ
iPhoneのクリスタは時間を限定すれば、無料で使えることを知りました。
そこで、スマホに向いている作業や複数端末で作業を進める場合、どうしたら効率よく進められるかを考えました。

# 編集環境
## 使用機器
- iPad Pro 11インチ
- magic keyboard
- Apple pencil
- iPhone

## プラン
clip studio paint ex
1デバイスプラン

# オススメ設定

## 自動同期をONにする

https://tips.clip-studio.com/ja-jp/articles/886#52e0980f

クリスタを立ち上げた際、電波などがつながっていると、クラウド同期の作品を自動的に同期してくれる設定です。
デフォルトはオフになっているので、自分でオンにする必要があります。

私の場合、イラストを書くのはWi-Fiがある所でしかしないので、自動同期をオンにしています。
手動で同期をし忘れてしまうと言うことがないので、スマホでもタブレットでも最新のファイルに触れるのはとても助かっています。

## 今どこ？……を範囲レイヤで書いておく

https://tips.clip-studio.com/ja-jp/articles/921

範囲レイヤーを使って、前回どこまで進めていたかや次に何をやる予定だったかを書いておくとはかどります。
使い方は、範囲レイヤーを作った後、そのレイヤーに書き込んで、自分がわかりやすい色をレイヤーカラーで設定するだけです。

ファイルを開いてすぐ続きの作業に取り掛かれるので、ちょっとした時短になります。また、範囲レイヤは結合して保存した際に書いた内容が写ってしまうことがないため、わざわざ非表示にすると言う必要がありません。

## スマホでやる作業、タブレットでやる作業をわける
### スマホ
- レイヤ名前つけ
- 曲線ツールなどの指でも精度が落ちない作業
- 素材配置
- ラフ
- 塗り分け
- 加工

細かな作業はタブレットなどに任せたほうがとても楽です。
逆にレイヤーの名前を整理したり、曲線ツールなど──指でも精度が出せるもの、ラフや3D素材の配置、塗りわけのベタ塗り、最終的な加工など、細かさを要求されない作業においては、スマホでも十分進めることができます。
スマホでもすきま時間に作業が進められることでだいぶ時短になります。

### タブレット
- 線画や細かな色塗り

基本的にはタブレットだとすべての作業を行って問題がないのですが、スマホで上記の作業を行う前提でタブレットでしかできない作業をすると言うふうに計画立てて進めていくと、スムーズにイラスト制作を進めていくことができます。



クリスタはちょっとした設定を変えるだけで、イラストを描くのが進めやすくなるので、また試してみて、効率が上がるものが見つかったら、ここで共有していきたいと思います。
CMakeでGoogleTestを導入したときに入力補完が有効にならない時の対応

## これはなに？
タイトルの通り、CMakeでGoogleTestを導入した際に、NeoVimの入力補完が有効にならないことがあったので、備忘録として残しておきます。

## 環境
- Windows WLS2
```
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.4 LTS"
```

- エディタ: Neovim
  - 入力補完を表示するため、clangdを使用しています
  - 細かい設定はこちら

https://github.com/OTakumi/nvim-lua

## GoogleTestの導入
C++で開発をする際、GoogleTestを使用し、単体テストを書くことがあると思います。
まずは、導入方法を記載しますが、基本的には公式のサンプル通りに書けば、テストを実行することはできます。

https://google.github.io/googletest/quickstart-cmake.html

```cmake
cmake_minimum_required(VERSION 3.14)
project(my_project)

# GoogleTest requires at least C++14
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(FetchContent)
FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

enable_testing()

add_executable(
  hello_test
  hello_test.cc
)
target_link_libraries(
  hello_test
  GTest::gtest_main
)

include(GoogleTest)
gtest_discover_tests(hello_test)
```

## 開発時にエラーが出る
上記のように、公式のCMakeのままでも、テスト自体を実行し結果を得ることはできるのですが、エディター上でライブラリが見つからないエラーとなり、入力補完が効かない状態となりました。
なので、まずCMakeに、
```diff_c_make
cmake_minimum_required(VERSION 3.14)
project(my_project)

# GoogleTest requires at least C++14
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(FetchContent)
FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

enable_testing()

+ find_package(GTest REQUIRED)

add_executable(
  hello_test
  hello_test.cc
)
target_link_libraries(
  hello_test
  GTest::gtest_main
)

include(GoogleTest)
gtest_discover_tests(hello_test)
```

を追加し、ライブラリを自動で見つけるようにします。
しかし、これでもエラーは解消されませんでした。
いろいろ調べた結果、stackoverflowの以下のやり取りを見つけました。

https://stackoverflow.com/questions/24295876/cmake-cannot-find-googletest-required-library-in-ubuntu

記事を読むと、以下の記述があったので、"libgtest-dev"をインストールすることで、エラーを解消することができました。
> This happened to me when I install gtest but not gtest-devel. On Ubuntu, I'd guess you need something like sudo apt-get install libgtest-dev

## おわりに
一番の原因は、ライブラリが足りていないことでした。
CMakeは奥が深い。

調べている中ではあまり情報が見つからなかったので、この記事が誰かの助けになれば幸いです。
【Python】dictとjsonの変換

dictとstr(json)の変換. 忘れるので記録

## 1. json -> dict
`json.loads()`を使います
```py
import json

s = '{"name":"bob", "age":25, "language":["en", "ja", "it"]}'
d = json.loads(s)

print(type(d)) # <class 'dict'>
print(d) # {'name': 'bob', 'age': 25, 'language': ['en', 'ja', 'it']}
```

## 2. dict -> json
`json.dumps()`を使います
```py
import json

d = {"name":"bob", "age":25, "language":["en", "ja", "it"]}
s = json.dumps(d)

print(type(s)) # <class 'str'>
print(s) # {"name": "bob", "age": 25, "language": ["en", "ja", "it"]}
```
Azure Pipelines: App Service に deploy する yaml

# 背景

Azure DevOps から、App Service へ deploy した際の yaml の備忘録

# yaml

provision も同様に可能

肝は、az auth を azd でそのまま使うようにする <code>auth.useAzCliAuth</code> 

provision をしない場合は、.env, config.json は、deploy 前に準備しておく必要がありそう

```yaml: Azure Deploy

- task: AzureCLI@2
displayName: 'Deploy App'
timeoutInMinutes: 30
inputs:
  azureSubscription: '{Survice Connection}'
  scriptType: 'bash'
  scriptLocation: 'inlineScript'
  inlineScript: |
    azd config set auth.useAzCliAuth "true"
    azd deploy --no-prompt --debug
continueOnError: false
env:
  AZURE_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID)
  AZURE_ENV_NAME: $(AZURE_ENV_NAME)
  AZURE_LOCATION: $(AZURE_LOCATION)

```

# azd の環境ファイル

.azure 直下の config.json
- azd env の default 設定を保存

.azure/{Environment Name} 直下の config.json
- azd env 毎の 環境変数と、設定を保存

```powershell: 環境ファイル

.azure/
    {Environment Name}/
        .env
        config.json
    config.json

```

# あとがき

CD は可能になったものの、以下の問題が起きることが未だにある
同一 yaml でも起きるので、なにか対策を考えるかなぁ

https://qiita.com/baku2san/items/d04c731e08aa81cb0726
【Go】 スライスをコピーした時のメモリの共有

# スライスのメモリ共有
スライスからサブスライスを切り出す際はコピーを作成している訳ではなく、スライスとメモリを共有してサブスライスが作成される。
つまり、スライス・サブスライス共に要素を変更するとメモリを共有している箇所が影響を受ける。

```go:
	x := []int{1, 2, 3, 4} 
	y := x[:2]
	z := x[1:]
	x[1] = 20
	y[0] = 10
	z[1] = 30
	fmt.Println("x:", x)  // x: [10 20 30 4]
	fmt.Println("y:", y)  // y: [10 20]
	fmt.Println("z:", z)  // z: [20 30 4]
 ```

 ここでappendした場合の動きを確認してみる。
 ```go:
    x := []int{1, 2, 3, 4} 
	y := x[:2]
	z := x[1:]
	y = append(y, 10)
	z = append(z, 20)
	fmt.Println("x:", x)  // x: [1 2 10 4]
	fmt.Println("y:", y)  // y: [1 2 10]
	fmt.Println("z:", z)  // z: [2 10 4 20]
 ```
 yにappendした場合、xの3が10に変更されてしまった。これは何が起こっているのだろうか？
 それぞれのスライスのキャパシティは以下のようになる。
```go:
	x := []int{1, 2, 3, 4} 
	y := x[:2]
	z := x[1:]
	fmt.Println(cap(x), cap(y), cap(z)) //4 4 3
	y = append(y, 10)
	z = append(z, 20)
	fmt.Println("x:", x)  // x: [1 2 10 4]
	fmt.Println("y:", y)  // y: [1 2 10]
	fmt.Println("z:", z)  // z: [2 10 4 20]
 ```
 サブスライスを作成した際のキャパシティは元のスライスのキャパシティからオフセット分引いた値になる。
 そのためyは長さは2になるがキャパシティは4になり、yにappendで3つ目の要素を加えるとxの3つ目の要素を上書きしてしまう。

# 解決策1
 この解決策としてサブスライスを作成する際はフルスライス式を使用する。フルスライス式を使用するとサブスライスを作成する際にキャパシティを指定することができる。
サブスライスのキャパシティは**元のスライスから利用するキャパシティの最後の位置**を指定する。

 ```go:
    x := []int{1, 2, 3, 4} 
	y := x[:2:2]
	z := x[1:4:4]
	fmt.Println(cap(x), cap(y), cap(z)) //4 2 3
	y = append(y, 10)
	z = append(z, 20)
	fmt.Println("x:", x)  // x: [1 2 3 4]
	fmt.Println("y:", y)  // y: [1 2 10]
	fmt.Println("z:", z)  // z: [2 3 4 20]
 ```
 このようにすることで元のスライスに影響を与えることなくappendができるようになる。

 # 解決策2
 完全に元のスライスとメモリを共有しないオリジナルのサブスライスを作成する。
 copy関数を使うことで元の配列からスライスを必要な分コピーする。
 copy関数の戻り値はコピーできた要素数になる。
 ```go:
    x := []int{1, 2, 3, 4} 
	y := make([]int, 2)
	z := make([]int, 3)
	num_y := copy(y, x[:2]) // xをyにコピーする
// num_y := copy(y, x) // この書き方でもOK キャパシティ分コピーされる
	num_z := copy(z, x[1:])
	fmt.Println("num:", num_y)  // num: 2
	fmt.Println("num:", num_z)  // num: 3
	y = append(y, 10)
	z = append(z, 20)
	fmt.Println("x:", x)  // x: [1 2 3 4]
	fmt.Println("y:", y)  // y: [1 2 10]
	fmt.Println("z:", z)  // z: [2 3 4 20]
 ```

 # 参考
[Goのフルスライス式 a[x:y:z] は何のためにある？](https://qiita.com/ruiu/items/f3516b705e6a7f2efb05)
[初めてのGo言語 ―他言語プログラマーのためのイディオマティックGo実践ガイド](https://www.amazon.co.jp/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AEGo%E8%A8%80%E8%AA%9E-%E2%80%95%E4%BB%96%E8%A8%80%E8%AA%9E%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%A4%E3%83%87%E3%82%A3%E3%82%AA%E3%83%9E%E3%83%86%E3%82%A3%E3%83%83%E3%82%AFGo%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-Jon-Bodner/dp/4814400047)
WordPressのエラー対処「更新に失敗しました。現在オフラインのようです。」

WordPressで編集した記事を保存しようとすると、「更新に失敗しました。現在オフラインのようです。」というエラーが発生しました。

![wordpress-error.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902958/863c2529-de35-73a5-1e82-3552447676df.jpeg)

この厄介なエラーの原因と解決策を、体験談とともに詳しく解説します。
## 発生状況と試した対策
このエラーは、ブロックエディタの編集画面で、ある程度の量の情報を入力した際に発生しました。

解決方法をググって片っ端から、試してみましたが、いずれも解決には至りませんでした。

試したこと
 * Cookie削除
 * キャッシュ削除
 * 閲覧履歴削除
 * サイトURLをhttpからhttpsに変更
 * WAF（Web Application Firewall）の一時無効化
 * プラグインの削除
 * WordPress本体の手動インストール

## 原因と解決策
色々調べた結果、おそらく**レンタルサーバーのMySQLのバージョンが古い**ことが原因だと判明しました。

使用していたレンタルサーバーのMySQLバージョンは**5.6.14**でしたが、これは現在のWordPress推奨バージョンに満たしていません。

MySQLのバージョンアップができないか、レンタルサーバーを契約してる会社に問い合わせてみました。
しかし、残念ながら現契約だとMySQLのバージョンアップはできないとのことでした。

仕方ないので、Webページのみ別のレンタルサーバーに移行したところ、無事、エラーは解消されました。

## 教訓
古いバージョンのサーバーを使用していると、予期せぬエラーが発生する可能性があります。
今回、契約していたのは、新規契約の受付を停止している割と古めのプランだったので、このようなことが起こりました。

Web関係のサーバーやソフトウェアは日進月歩でアップデートされていて、定期的に確認しないとセキュリティが脆弱になったり、サ終になったりします。

今回の記事が、皆様のWordPressライフのお役に立てば幸いです。
【2024マラソン24】REALITYのアバターを使ってできること

# 何の記事？
REALITYのアバターを使ってできることについて、調べたことをまとめます。

# REALITYのいいところ
- スマホだけで手軽にかわいいアバターが作れる
- ガチャ衣服が可愛い
- フェイスシンクでアバターが手軽に動かせる
- スマホ1台で配信できる

# REALITYのアバターを使えるところ
- REALITYアプリ内の配信
- clusterでアバターとして使用

# REALITY外への発信は難しい
REALITYの配信は、その場のライブのみです。
基本的にはYouTubeのようにアーカイブを残し、後から誰かに見てもらうということができません。
なので、web検索で自分を検索してもらうと言うことが難しいのが現状です。

ただし、clusterで使うアバターとしてREALITYのアバターを使うことができます。
そのため、REALITY外に発信する場合は、REALITYのアバターでclusterのイベントを開催し、それをyoutubeに配信すると言うやり方があります。

clusterはもともとイベントをしやすく、またイベントにも参加しやすいメタバースなので、このclusterでイベントを開催するのはありかと思います。

# REALITYの配信の中でできること
実際のREALITYの配信画面でできることをここに書きます。

- 視聴者とコメントのやり取りを行う
- 視聴者から投げ銭をもらう
- YouTubeの配信などを視聴者と一緒に見る(動画再生位置が配信者と同期される)
- 配信中、自由にBGMを変更できる
- アバターにリアクションをさせる
- ミニアバターで小さなマップを探索する
- 視聴者も一緒に配信へ参加してもらう

# REALITYのアバターを外部で使う方法
既に聞いたりまとめてくれている人がいました。

## REALITYのアバターでビデオ会議に出る方法

https://www.freshvoice.net/knowledge/trouble/12326/

## REALITYのアバターでyoutube動画を作る方法

https://youtu.be/heUOFqFESVY?si=6EeW01cHODaV_gz0

これを使うとREALITYの可愛いアバターを使って、YouTubeにデビューしたり、ビデオ通話を行うことができます。
ただ、クロマキーの背景切り抜きを行う場合、REALITYで配信しながら、youtubeでもライブ配信をするのはあまり現実てきではないかも知れません。
youtubeへのライブ配信を行う場合は、clusterなどでイベント中の映像をyoutubeに流す方法をお勧めします。

▼REALITY運営がcluster内でイベントをやっているのをyoutubeで配信した図

https://youtu.be/Po_lhrdz5-8?si=QBM_eQADEqLgXmOO

REALITYのアプリ外でも工夫次第で色々な楽しみかたがあるので、興味を持った方は是非さわってみてください。
ECLiPSe で Welcome to AtCoder を解いてみた

[Qiita Engineer Festa 2024（キータ・エンジニア・フェスタ 2024） - Qiita](https://qiita.com/official-campaigns/engineer-festa/2024)
において、約1ヶ月で38記事という大量の記事の投稿を要求されることがわかった。
そこで、あまりコストをかけずに記事数を稼ぐ方法を考えた結果、「Welcome to AtCoder を様々な言語で解く」ことを思いついた。
単に解くだけでなく、使用する言語仕様の解説を入れれば、記事として一応成立するだろう。

# Welcome to AtCoder

[PracticeA - Welcome to AtCoder](https://atcoder.jp/contests/abs/tasks/practice_1)

Welcome to AtCoder では、以下の形式で整数 $a$, $b$, $c$ および文字列 $s$ が入力として与えられる。

```text
a
b c
s
```

この入力をもとに、与えられた整数の和 $sum = a + b + c$ および文字列 $s$ を、以下の形式で出力することが求められる。

```text
sum s
```

# ECLiPSe の情報の入手方法

「ECLiPSe」だけでググっても、統合開発環境 Eclipse やその他関係ないものばかり出てきて、ECLiPSe の情報にたどり着くのは難しそうであった。
「ECLiPSe 言語」でもダメそうだった。
そこで、AtCoder でわかるバージョンを入れた「ECLiPSe 7.1_13」でググると、以下のサイトが出てきた。

[Index of /Distribution/Builds/7.1_13](https://eclipseclp.org/Distribution/Builds/7.1_13/)

このサイトのURLのパスを `/` に置き換えてアクセスすることで、情報にたどり着くことができた。

[ECLiPSe Home](https://eclipseclp.org/)

さらに、[適当なサンプルコード](https://eclipseclp.org/examples/xkcd287.ecl.txt)を AtCoder のコードテストにコピペして実行を試みると、

> calling an undefined procedure main in module eclipse
> abort

と出てきたので、`main` の定義を要求されるらしいことがわかった。
そこで、`main site:https://eclipseclp.org/` でググると、以下のページなどが出てきた。

[Loop/Iterator Constructs](https://eclipseclp.org/doc/userman/umsroot023.html)

ここに載っている情報から、プログラムの書き方を推測できた。

# 今回用いた ECLiPSe の機能

[Input and Output](https://eclipseclp.org/doc/tutorial/tutorial028.html)
[Input/Output](https://eclipseclp.org/doc/applications/tutorial007.html#sec141)
[Programming Concepts](https://eclipseclp.org/doc/applications/tutorial006.html#sec97)

プログラムは

```
main :-
        処理内容.
```

の形で表現できるようである。
複数の処理を行う場合は、`,` で繋ぐといいようである。

```
read_token(値を受け取る変数, 種類を受け取る変数)
```

で、標準入力から数値 (など) を1個読み込めるようである。

```
get(結果を受け取る変数)
```

で、標準入力から1文字読み込み、数値として受け取れるようである。
(今回は、数値の後の改行文字を読み捨てるために使用した)

```
read_string(探す文字, 長さを受け取る変数, 文字列を受け取る変数)
```

で、標準入力から指定の文字の直前までを読み込み、文字列として受け取れるようである。

```
sum(数値のリスト, 結果を受け取る変数)
```

で、数値の和を求めることができるようである。

```
printf(書式文字列, データのリスト)
```

で、文字列で指定した書式にデータを埋め込み、標準出力に出力できるようである。

文字列は `""` で囲むことで表現できるようである。
リストは、`[]` で囲み、各要素を `,` で区切ることで表現できるようである。

# 提出コード

```
main :-
        read_token(A, T1),
        read_token(B, T2),
        read_token(C, T3),
        get(New_line),
        read_string("\n", L, S),
        sum([A, B, C], Sum),
        printf("%d %s\n", [Sum, S]).
```

[提出 #55484263 - AtCoder Beginners Selection](https://atcoder.jp/contests/abs/submissions/55484263)
Linuxコマンド：過去に打ち込んだコマンドの一覧を出して、再利用する方法 historyコマンド

## 読んで欲しい人
- Linuxを利用していて「あれ、さっきも同じコマンド打ったけど何だっけ？」となる人
- 矢印キーだと過去コマンド遡るのめんどい人
- 過去の自分

## やり方

1.下記を打ち込む

```
history
```

2.いっぱい過去のコマンドが出てくる

```
3488* bin/dev
3489* cdwor
3490* cd Workspace
3491* ls
3493* code .
3494* bin/dev
3495* code .
3496* rails routes | grep like
3497* rails routes | grep users
3498* exit
3499  code .
3500* bin/dev →　今回はこれ
```

3.使用したいコマンドの番号の前に`!`をつけて入力してEnter

```
!3500
```

4.コマンドが出てくる
```
bin/dev
```

### あれ、あのコマンドって cd…　なんて打ったっけ？ みたいなケースの時

```
history | grep cd
```

`| grep キーワード` をつけてEnter


```
3462* cd Workspace/github.com
3466* cd project
3468* cd Workspace/Miniblog
3489* cdwor
3490* cd Workspace
3492* cd MiniBlog2
```

みたいにcdが入ったコマンドがたくさん出てくる

以上
CLI版Postman!? ATACについて

## ATACとは

**Arguably a Terminal API Client(ターミナルAPIクライアント)**

- PostmanライクなCLI APIテストツール
- 基本的な機能は搭載済み
- オープンソース
- 無料
- アカウント登録不要
- Rust製

https://github.com/Julien-cpsn/ATAC

https://atac.julien-cpsn.com/

## インストール

### 環境

mac OS 14.5

Homebrew 4.3.9
他のOSでのインストール方法は公式ドキュメントを参考にインストールしてみてください！
```bash
brew tap julien-cpsn/atac
```

```bash
brew install atac
```

## 使い方

### 準備

APIリクエストなどを格納するディレクトリを作成する

```bash
mkdir collections
```

### 起動する

`-d` (`—directory`)オプションで対象ディレクトリを指定する

```bash
atac -d collections/
```

このようなCLIアプリケーションが立ち上がればOK

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686052/8fb4cbb3-d11b-d0d0-c22d-8cc3d43975a9.png)

### 使い方を調べる

`Ctrl` と`h` を同時押しで、コマンド一覧が表示される

`esc` でこの一覧を閉じることができる

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686052/e33bd9d5-0e5f-a9e0-648e-f823c4a92ec3.png)

### リクエストを作成する

`n` キーを押すとコレクション名を命名するテキストフィールドが現れるので入力し`Enter` 

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686052/2f9b79bc-d6d1-5e86-284a-239fc03b5fa5.png)


コレクションができたらもう一度`n` キーを押し、リクエスト名(ここでは`GET-test`)を入力し`Enter` 

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686052/29fef471-1a20-1423-0e82-bb5149937f54.png)

先ほど作成したHTTP-Methodsの中に先ほど作成した`GET-test` が格納されているため十字キーで選択し、`Enter` 

### APIをテストする

`u` を入力するとURLを編集できるため、テストとしてランダムにジョークを返してくれるAPIでテストしてみます。

API: https://api.chucknorris.io/jokes/random

そして、実行するにはスペースキーと`Enter` キーを同時押しする

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686052/38f04d3a-65e0-cc62-eab9-1c9fb1e01130.png)


右の方にレスポンスが表示され、APIの動作確認をすることができる

そのほか、色々な使い方があるので、ぜひ体験してみてください。
Azure Pipelines: デバッグする為の策

# 背景

Azure Pipelines を使うときに、役立った debug 用機能の備忘録

# 方法

## 環境変数で、debug 有効化

以下のようにして、system.debug を追加して、true/false で切替可能

1. Create variable
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/0288c880-1f50-9760-6a62-1c3d945a5102.png)

1. New Variable
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/8dde6913-d56d-0a13-9064-ed56c186280a.png)

1. system.debug = true を追加
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/aebaeeea-247e-2e8a-044a-7c2addffc8a3.png)

実際の差分は以下な感じで、#debug 行が大量に増えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/bbd3cb23-4211-ecc3-f6b8-5a0615e2b0f8.png)


詳細は以下

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/troubleshooting/review-logs?view=azure-devops&tabs=windows-agent

## 手動実行時の #debug 有効化

以下の 設定を 有効にして <code>Run</code> すればOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/51dc7121-3640-db3e-e0cb-1bb954291600.png)


## #debug のログ + α のファイルダウンロード

実行結果のとこからダウンロード可能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/8982dd1b-a565-0ece-5240-bdbcffe6dfe6.png)

内容としては
- [worker 診断ログ](https://learn.microsoft.com/ja-jp/azure/devops/pipelines/troubleshooting/review-logs?view=azure-devops&tabs=windows-agent#worker-diagnostic-logs)
- [エージェント診断ログ](https://learn.microsoft.com/ja-jp/azure/devops/pipelines/troubleshooting/review-logs?view=azure-devops&tabs=windows-agent#agent-diagnostic-logs)
- [その他のログ](https://learn.microsoft.com/ja-jp/azure/devops/pipelines/troubleshooting/review-logs?view=azure-devops&tabs=windows-agent#other-logs)

## azd の --debug オプション

以下のようにして、diagnostics logging を有効化出来る

> azd deploy --debug

https://learn.microsoft.com/ja-jp/azure/developer/azure-developer-cli/reference#azd

# あとがき

慣れてないと、ログを見ても勘所がさっぱりだなぁとは思う。
そう、人間もAIですよね、と
アメリカ地質研究所から過去の地震データを自動更新取得する【PowerBI】

今日は世界中で発生している地震のデータを自動取得する方法を説明いたします。

データ元はこちら。
https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%A1%E3%83%AA%E3%82%AB%E5%9C%B0%E8%B3%AA%E8%AA%BF%E6%9F%BB%E6%89%80

アメリカ地質研究所（USGS）のサイトの下記リンクからデータを取得できます。
https://earthquake.usgs.gov/earthquakes/search/

上記リンクからマグニチュードや期間などの条件を設定しまずはGeoJSONでデータを取得します。
正直に書きますと、実はGeoJSONの仕組み自体はわかっておりません。
ここで得られるクエリのURLを取得するのが狙いです。

https://earthquake.usgs.gov/fdsnws/event/1/query.geojson?starttime=2015-01-01%2000:00:00&endtime=2099-12-31%2000:00:00&minmagnitude=6&orderby=time

上のURLを見ると「2015年～2099年までのデータを」「最小マグニチュード6で」「GeoJSON形式で」データを取得するための物だと判別できます。上記「query.geojson?」を「query.csv?」に変えるとわかりやすいCSVでデータ取得できるわけです。

PowerBIを立ち上げ「データの変換」⇒「新しいソース」⇒「WEB」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832168/65d09bb0-67b2-415d-66cf-d8815e41b754.png)

アドレスに先ほど確認したURLをペーストします。下記は「2015年～2099年までのデータを」「最小マグニチュード6で」「CSV形式で」取得するための例です。

```https://earthquake.usgs.gov/fdsnws/event/1/query.csv?starttime=2015-01-01%2000:00:00&endtime=2099-12-31%2000:00:00&minmagnitude=6&orderby=time```

このダイアログが出たら「接続」を押して…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832168/6a2284e0-262f-5ca2-8fae-e77d6edef666.png)

そのまま「OK」を押してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832168/4bfa24ed-10c6-45fc-7037-43f48bb67dd8.png)

これで過去の地震データが緯度・経度・マグニチュード情報付きで利用可能となります。

今回のデータが今までの経済や都市座標と異なるのは、地震という人を巻き込む災害であること。
「数字の裏には様々な人の心が存在している」ということを心に刻んで正しく使うことが一番大事だと考えています。
データを扱う人こそアナログな心に重きを置くべきと、自重のためにも書き残しておこうと思います。
チェックボックスの状態でコンポーネントの表示を切り替える

# はじめに
備忘録として残しています．
もっと良い書き方があれば，指摘していただけると幸いです．

# コード
```page.tsx
"use client";

import { useState } from "react";
import { CheckBox, Panel } from "@/styles/CheckBox";

const Page = () => {
  const [isVisible, setVisible] = useState(false);

  return (
    <main>
      <div>
        <CheckBox onChange={() => setVisible(() => !isVisible)} />
        <label>テスト用チェックボックス</label>
      </div>
      <Panel $isVisible={isVisible}>チェックボックスの値によって表示を切り替えます</Panel>
    </main>
  );
};

export default Page;
```

```CheckBox.tsx
"use client";

import styled, { css } from "styled-components";

const CheckBox = styled.input.attrs({ type: "checkbox" })``;

const Panel = styled.div<{ $isVisible: boolean }>`
  background: #41a1fb;
  width: 100%;
  ${({ $isVisible }) =>
    !$isVisible &&
    css`
      visibility: hidden;
    `}
`;

export { CheckBox, Panel };
```

# 見た目
<div>
<img alt="チェックボックスOFF" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736836/411b8371-ab8a-9b96-91f7-018a7dd4c702.png" />
<img alt="チェックボックスON" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736836/4d1fafd2-4f9c-4407-b4d6-80bcaeb931dd.png" />
<div>

# コード説明
まずはuseStateを使って表示状態をbooleanで管理します．
CheckBoxコンポーネントの`onChange`でチェックの状態が変わるたびに`isVisible`を反転させています．

そして，表示状態を切り替えたいコンポーネント(今回はPanel)に`isVisible`を渡します．
ちなみに，`$`マークを付けておかないと`isVisible`がDOMに渡されてしまい，警告が出ます．
isVisibleがfalseの時に，`visibility: hidden`を有効にすることで，チェックボックスの状態によってコンポーネントの表示状態を切り替えています．
`visibility: hidden`の箇所をいじることで表示状態だけでなく，色や透明度や位置などを切り替えることが可能です．
親子関係を押さえよう！display: flex;でレイアウトを管理する方法

# はじめに
横並びに表示するCSSは主に`flex`と`float`の2種類あることを学びました。
使い勝手がいいのは`flex`だと思うのですが、深掘りすると親子関係が重要なのだとわかったので、それをまとめたいと思います。


# ?  `display: flex;`とは
レイアウトを簡単に管理するためにCSSで使うもの。

# 結論
複雑なレイアウトを簡単に作成でき、レスポンシブデザインにも対応しやすくなる。
最初のスタイルは**親要素**から書き始める！

 # 設定方法
【見た目】
![スクリーンショット 2024-07-12 20.48.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830302/7bfa0169-789d-07c7-f56f-14749ce28f22.png)

このように横並びで表示させたい時にまずHTMLから、

```html:index.html
<div class="container">
  <div class="item">アイテム1</div>
  <div class="item">アイテム2</div>
  <div class="item">アイテム3</div>
</div>
```

CSSでは、
〔１〕**親要素** に `display: flex;` を設定する。
〔 2 〕アイテムの配置やサイズの調整を効率的に行うための様々なプロパティを設定。
〔 3 〕指定した要素の**子要素**に反映される。
```css:style.css
.container {
  display: flex;
  justify-content: center; /* 主軸に沿って中央寄せ */
  align-items: center; /* 交差軸に沿って中央寄せ */
  height: 100vh; /* ビューポートの高さを占める */
}

.item {
  background-color: lightcoral;
  padding: 20px;
  margin: 10px;
}
```

## 親要素に使えるCSSプロパティ
・display: flex;: 親要素にフレックスプロパティを書いて、配置替えしますよ〜って宣言する感じ（デフォは横並び）。
・flex-direction: アイテムの配置方向を指定する。例えば、row（横並び）や column（縦並び）。
・justify-content: 主軸に沿ったアイテムの配置方法を指定する（左寄せ、中央寄せ、右寄せ、均等配置など）。
・align-items: 交差軸に沿ったアイテムの配置方法を指定する（上寄せ、中央寄せ、下寄せなど）。
・flex-wrap: アイテムがコンテナ内に収まりきらない場合の折り返し方法を指定する。

## 子要素に使えるプロパティ
・flex-grow: アイテムが利用可能なスペースをどの程度拡張できるかを指定する。
・flex-shrink: アイテムが利用可能なスペースをどの程度縮小できるかを指定する。
・flex-basis: アイテムの基本サイズを指定する。
・align-self: 特定のアイテムに対して交差軸に沿った配置方法を指定する（align-items の上書き）。

### （`float`のさわりだけ）
・要素を左または右に浮かせて配置する。
・浮かせた要素の親要素に clearfix を適用することで、レイアウトの崩れを防ぐ。
・FlexboxやGridの登場により、floatの使用頻度は減っていますが、特定のレイアウトにはまだ有用。


# おわりに
レスポンシブデザインに対応できる`flex`は使い勝手がよさそうだと思いました。
`float`の場合は他に設定の必要なプロパティがあるので、手間が増える。浮かせるってよく分からん、、。

今日覚えておきたいひとつは、**`display: flex;`は親要素につける**。
だから時々反映されなかったんだ、、。（子要素にあててた）

あのときは、こんな超初歩的なことでつまづいてたんだ、と早く言えるようになりたい。
そういえば`display`押さえといた方が良さそう、と今日もやっぱり思ったので、早くまとめます。
吹き出しコンポーネントの作り方

# はじめに
備忘録として残しています．
もっと良い書き方があれば指摘していただけると幸いです．

# コード

```page.tsx
import Button from "@/styles/Buttons";
import Explanation from "@/styles/Explanation";

const Page = () => (
  <main>
    <div>
      <Button>
        テストコンポーネント<Explanation>説明</Explanation>
      </Button>
    </div>
  </main>
);

export default Page;
```

```Button.tsx
"use client";

import styled from "styled-components";

const Button = styled.button`
  margin: 5px;
  border: solid 1px #ddd
  border-radius: 8px;
  cursor: pointer;

  &:hover {
    > span {
      visibility: visible;
    }
  }
`;

export default Button;
```

```Explanation.tsx
"use client";

import styled from "styled-components";

const Explanation = styled.span`
  position: absolute;
  right: auto;
  left: 8%;
  z-index: 10;
  display: block;
  visibility: hidden;
  width: 240px;
  padding: 10px;
  margin-top: 20px;
  text-align: center;
  color: #fff;
  background-color: rgb(12 110 183 / 100%);
  border-radius: 5px;

  &::after {
    position: absolute;
    top: -12px;
    right: auto;
    left: 5%;
    content: "";
    border-right: 10px solid transparent;
    border-bottom: 12px solid rgb(12 110 183 / 100%);
    border-left: 10px solid transparent;
  }
`;

export default Explanation;
```

# 見た目
![スクリーンショット 2024-07-12 212730.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736836/5ba7a050-736a-a5b0-6a34-f2a22423a2af.png)

# CSS説明
`position`は親コンポーネントを基準にするため，`absolute`にしています．
`visibility`は`hidden`を指定していますが，`Button.tsx`でホバーした際に子コンポーネントの`span`要素の`visibility`を`visible`に上書きするようにしています．

`&::after`内部は吹き出しのとんがり部分の位置を指定しています．
こちらも`position: absolute`とすることでspanの位置を基準にしています．
`border-right`や`border-left`をいじることでとんがり部分の角度を調整できます．