OmniAICreator/Qiita-1.07M huggingface dataset:
widthとmax-widthの違いと使い分け

# はじめに
幅のスタイルの当て方はすこしずつ慣れてきたきがする。
だがしかし、、、
`width`プロパティには、`width`と`max-width`の２つあり使い分けがよく分からん。
という状況になったのでまとめます。
※超初学者です。間違いがありましたらご指摘いただけると、とても嬉しいです。


# ? : `width`と`max-width`って厳密には何が違うの？
ブロック要素には`px`指定。インライン要素には`％`指定をするというのが基本。
例）インライン要素のimgは`width: 100%;`と指定。（親要素に依存させる）

この`width`を`max-width`と指定しないのはなんで？

# 結論
厳密な決まりはないが、
・`width`は指定された幅を厳密に適用するため、**「 要素の幅は固定される 」**。
　→ だから`px`単位を使うことが多い。
 
・`max-width`は **「 要素の幅が特定の値を超えないように制約するだけ 」** で、
内容や親要素の幅に応じて変動する。
 

`width`と`max-width`はどちらも要素の幅を制御するためのCSSプロパティ。
それぞれの使い方と効果にはいくつかの重要な違いがある。

## width
機能: 要素の**幅を固定**する。
使用例: `width: 500px;` と指定する。→ その要素の幅は常に500pxになる。
適用例: **固定幅**のレイアウトを作成したい時に向いてる。

## max-width
機能: 要素の幅の最大値を指定する。
使用例: `max-width: 100%;` のように指定すると、その要素の幅は親要素の幅を超えない。
要素が特定の幅を超えないようにしつつ、画面サイズに応じて柔軟に縮小するようにできる。これにより、レスポンシブデザインを実現しつつ、読みやすさやデザインの一貫性を保つことができる。
適用例: レスポンシブデザインで使用されることが多く、要素の幅が特定の最大値を超えないようにしたい場合に使用します。



# 2つの違い
・**`max-width: n %;`の方が柔軟性が高い。**
`width`は指定された幅を厳密に適用するため、要素の幅は固定される。
`max-width`は要素の幅が特定の値を超えないように制約するだけで、内容や親要素の幅に応じて変動する。
・max-widthは10pxのコンテナに対して50pxの


## レスポンシブデザイン
`width`は固定レイアウトに。（レスポンシブデザインには適していないことがある。）
`max-width`はレイアウトが変わっても対応できることが多く、レスポンシブデザインでよく使用される。



# ポイント
親子関係がある時には、

**親要素に`max-width`子要素に`width:100%;`**

にする。
親要素の幅に合わせて子要素のサイズが調整される、柔軟なレイアウトを作成できる。
この方法はレスポンシブデザインや柔軟なレイアウトを実現するために非常に有効。

### 補足１：`width: 100%;`ってどんなとき指定する？

**『　子要素の幅を親要素の幅に完全に合わせたいとき　』**

```index.html
<div class="point">
  <img src="images◼︎◼︎◼︎◼︎◼︎◼︎◼︎◼︎" alt="">
</div>
```
```style.css
.point {
  max-width: 200px;/*親要素の固定幅を指定*/
}

img {
  width: 100%;/*親要素に100％になるように指定*/
}
```

→ imgに100％と指定しているので、親要素の200pxにピッタリの幅を持たせることができる。


# おわりに
`max-width`プロパティの癖にまだついていけない。。
使いこなせるようになりたいです。レスポンシブデザインをやるようになったらもう少しよくわかるようになるんだろうな、と思っています。
昨日から幅についてまとめてるけど、実際使っていってみてわかるようになりそうなので、練習していきます。
AtCoder 勉強記録[C++] その22

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)
# 本日解いた問題
## B - Light It Up
[B - Light It Up](https://atcoder.jp/contests/abc255/tasks/abc255_b)
解答
```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;
  cin >> n >> k;
  vec a(k), x(n), y(n);
  rep(i, k) cin >> a[i], a[i]--;
  rep(i, n) cin >> x[i] >> y[i];
  double res = 0;
  for(int i = 0; i < n; i++){
    double dismin = INT_MAX;
    for(int j = 0; j < k; j++){
      double tmp = sqrt((x[i]-x[a[j]])*(x[i]-x[a[j]]) + (y[i]-y[a[j]])*(y[i]-y[a[j]]));
      dismin = min(tmp, dismin);
    }
    res = max(res, dismin);
  }
  cout << fixed << setprecision(15) << res << endl;
}
```
### 解法
`N`人の人において、一番距離が近い明かりを求め、その中で一番大きいものが必要な明かりの最小値となる。
## C - Monotonically Increasing
[C - Monotonically Increasing](https://atcoder.jp/contests/abc263/tasks/abc263_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, m;
  cin >> n >> m;
  vec res;
  for(int i = 0; i < n; i++) res.push_back(0);
  for(int i = 0; i < m-n; i++) res.push_back(1);
  do{
    for(int i = 0; i < m; i++) {
      if(res[i] == 0) cout << i+1 << " ";
    }
    cout << endl;
  } while(next_permutation(res.begin(), res.end()));
}
```
### 解法
問題文の内容は、`mCn`の組み合わせを出力することと同義であるため、`next_permutation`関数を用いて組み合わせを出力する。
## C - Belt Conveyor
[C - Belt Conveyor](https://atcoder.jp/contests/abc265/tasks/abc265_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 h, w;
  cin >> h >> w;
  vector<vector<bool>> jud(h, vector<bool>(w, false));
  vector<string> g(h);
  for(int i = 0; i < h; i++) cin >> g[i];
  ll x = 0, y = 0;
  while(1){
    jud[x][y] = true;
    if(g[x][y] == 'U'&& x!=0) x--;
    else if(g[x][y] == 'D'&& x!=h-1) x++;
    else if(g[x][y] == 'L'&& y!=0) y--;
    else if(g[x][y] == 'R'&& y!=w-1) y++;
    else {
      cout << x+1 << " " << y+1 << endl;
      exit(0);
    }
    if(jud[x][y]) {
      cout << -1 << endl;
      exit(0);
    }
  }
}
```
### 解法
この問題では問題文の条件において場合分けして考え、動けなくなる場合、その座標を出力する。さらに無限に移動し続ける場合を考える必要がある。そのため、通った座標を記録しておく2次元配列を用意しておき、2度目に通る際に-1を出力する。
Google IMEがおバカになってしまったので

# はじめに
windowsの標準MS-IMEをに不満を抱いてGoogle IMEを利用している方は多いかと思います。
私もそうです。
Google IMEを愛用しています。

しかし、最近Google IMEに違和感を覚えることが増えてきました。
以前はスムーズに動作し、的確なｲｹｲｹ変換を提供してくれていたのに、最近どうも様子が変わってきたのです。

「自信がなく」を入力したいのに「地震が泣く」になる...みたいな、そういうことが多発するようになってしまいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3283241/193614ea-5811-f9c1-efc9-3478e26c29a3.png)


# 不満と文句と悲しみ
文書を作る中で頻繁に使用する単語が、全く異なる意味の言葉に変換されてしまうことがあります。
これにより、文章作成の効率が著しく低下し、非常にストレスです。

また、Google IMEの学習機能も以前ほど効果的ではなくなったように感じます。
何度も修正して登録しているにもかかわらず、同じ誤変換を繰り返すことがあるのです。
これは、私のような長年使い込んできたユーザーにとってとても不快で不便な状況です。


# 解決できなかった
私自身も、この問題に対処するためにいくつかの方法を試してみました。
IMEの設定をリセットしたり、辞書データを見直したり～といったよく言われている物たちを試行しましたが、残念ながら大きな改善は見られませんでした。

ちなみに、苦手だったMS-IMEもいつの間にかクラウド変換に対応してるみたいです。
これはもう乗り換え時なのかな...。


# さいごに
Google IMEの「おバカ化」は、多くのユーザーにとって悩ましい問題となっています。
Google側がいい感じに対応してくれるのを待つべきか、それとも他のIMEに移行すべきか、判断が難しいところです。

いい感じのIMEないかな。あったら教えて下さい。

それでは。


# 追記
そういうとこやぞGoogle IME

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3283241/ddb3c6f1-efd0-1e2a-855a-51f219b95c4b.png)
Webアプリケーション作成のための10ステップ　1. プログラミング言語

# この記事を書いたきっかけ

この記事では、Webアプリケーションエンジニアに必要なスキルを具体的に解説し、その学び方を示します。

Webアプリケーション作成に必要なスキルを10個にまとめ、一つずつ学ぶ目的と手段を整理したいと思います。今回は**プログラミング言語**について書きます。

### この記事を書いた目的
- webアプリケーションエンジニアになりたい
- そのために、自分に足りないものは何かを知りたい
- すぐに行動に移すために、学ぶ目的と手段を具体化したい
- webアプリケーションエンジニアに必要なスキルを全て把握したい
- 今、自分はなんのために、何を学んでいるのか、見失わないようにしたい


***
こちらの記事が大変参考になります。

https://qiita.com/Saku731/items/52a3bbacd002f26f408e

# Webアプリケーション作成のための10ステップ
1. プログラミング言語の習得
1. フロントエンド開発
1. バックエンド開発
1. バージョン管理
1. 開発ツールと環境
1. セキュリティ
1. デプロイメントとクラウド
1. テスト
1. アーキテクチャの知識
1. ソフトスキル

# 1. 基本的なプログラミングスキル
## 1.1 プログラミング言語
### プログラミング言語って何？（What）
プログラミング言語とは、コンピュータに対して特定の指示を与えるための文法とルールのセットです。Webアプリケーション開発においてよく使用されるプログラミング言語には、Python、JavaScript、Rubyなどがあります。
### なぜプログラミング言語を勉強する必要があるのか？（Why）
Webアプリケーション開発において、プログラミング言語を習得しなければ、コンピュータに対して特定の指示を与えることができないから。
その上で、プログラミング言語を習得するメリットは何か？
#### 1. 問題解決能力の向上
プログラミング言語を学ぶことで、コンピュータを使って効率的に問題を解決する方法を理解できる。具体的な課題を解決するためのロジックやアルゴリズムを組み立てるスキルが身につきます。
#### 2. アプリケーションの開発と運用
Webアプリケーションを開発するためには、サーバー側やクライアント側で動作するコードを書く必要があります。プログラミング言語を学ぶことで、ユーザーの要求に応じた機能を実装し、アプリケーションを運用することができます。
#### 3. 効率的な作業の自動化
プログラミング言語を使ってスクリプトを作成することで、手作業を自動化し、効率的にタスクをこなすことができます。

### どのようにプログラミング言語を習得していけばいいのか？（How）
- **基本文法**: 公式ドキュメントや入門書を使用して基本文法を学ぶ。
- **練習問題**: 競技プログラミングなどで問題を解いてみる。
- **プロジェクト**: 小さなプロジェクトを作成して、実際にコードを書いてみる。
- **Djangoチュートリアル**: [Django公式チュートリアル](https://www.djangoproject.com/)を実践し、Webアプリケーションを作成する。

### 実際に勉強したこと(Try)
- paizaで問題を解く（[paizaラーニング問題集](https://paiza.jp/works/mondai)）
- 基本文法：Progateに取り組む → paizaの新Python入門編 → Python入門書を参考にする
- Django開発入門を書籍通りに作成する → paizaのDjango入門編受講する → 実際にオリジナルのWebアプリケーションを作成してみる


## 1.2 アルゴリズムとデータ構造
### アルゴリズムって何？（What）
アルゴリズムとは、特定の問題を解決するための手順や計算方法のことです。データ構造は、データを整理・管理するための方法や形式です。

### なぜアルゴリズムを学ぶ必要があるのか？（Why）
効率的なアルゴリズムとデータ構造を理解することで、パフォーマンスの高いアプリケーションを開発できます。その結果、ユーザーが使いやすいサービスを作成できたり、リソースを節約できたりします。

### どのように勉強すればいいのか？（How）
**アルゴリズムで学ぶこと**
#### 基本的なアルゴリズム
- ソートアルゴリズム: バブルソート、クイックソート、マージソートなどの基本的なソートアルゴリズムを学ぶ。
- 探索アルゴリズム: 線形探索、二分探索、深さ優先探索、幅優先探索など。
#### 基本的なデータ構造
- 配列とリスト: 配列、連結リスト、スタック、キューなど。
- ツリーとグラフ: 二分探索木、ヒープ、グラフ、トライなど。
- ハッシュテーブル: ハッシュ関数とハッシュテーブルの使い方。

### 具体的にどうやって勉強するのか？
**オンラインコース**：Udemyなどのプラットフォームでアルゴリズムとデータ構造のコースを受講する。
**書籍**: アルゴリズムに関する書籍を読んでみる。
**練習問題**: アルゴリズムとデータ構造の問題を解く。

### 実際に勉強したこと(Try)
- paizaのアルゴリズムの問題を解いてみる（[paizaラーニング問題集](https://paiza.jp/works/mondai)）
- 放送大学の「データ構造の基礎」を受講する
- 書籍：[アルゴリズム図鑑](https://www.amazon.co.jp/%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E5%9B%B3%E9%91%91-%E7%B5%B5%E3%81%A7%E8%A6%8B%E3%81%A6%E3%82%8F%E3%81%8B%E3%82%8B26%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0-%E7%9F%B3%E7%94%B0-%E4%BF%9D%E8%BC%9D/dp/4798149772)を読む

# まとめ
Webアプリを作成するために、何を勉強しなければならないのかを考えました。ただ、初心者なので限界があります。自分が知らないことを、今後どうやって勉強していくかを考えるのは少し難しいです。

今回記事を書いたことで、今までやってきたことを振り返ることができたのはよかったと思います。

もし、Webアプリを作成する上で、オススメのプログラミングの勉強法があれば、是非教えていただけると嬉しいです。
【個人開発】最寄りの綺麗なトイレを見つけるアプリを一部改良しました【Next.js×Supabase】

# 名称
Quick Clean Restroom Map

# 概要
最寄りの綺麗なトイレの位置をリアルタイムで案内し、トイレの情報を提供します。

# URL
https://quickcleanrestrooms.com/

# 前回作成したアプリ(Next.js✖️Rails)の改良版です
https://qiita.com/JZ8xNeXY/items/b51ffd9f10986861c83b


# アプリを改良した背景
### 課題

この構成は柔軟性や拡張性が高い一方で、個人のアプリケーションにおいては運用コストが高くなるという課題がありました。

インフラ構成図
![インフラ構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917693/7ca31988-00b0-7686-0897-751716e6a5d1.png)

### 改良の方針
経費を抑えつつも柔軟性や拡張性を確保するため、インフラを見直しました。Supabaseを使用することでデータベースや認証機能を簡素化し、Vercelを使用してデプロイとホスティングを一元化することで、運用コストを削減しながらも拡張性を維持します。これにより、個人のアプリケーションでも経済的に運用できるようになりました。

インフラ構成図
![component_supabase.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/917693/9188d26c-cbd1-8517-483c-52fa603bd06d.png)







# 主な使用技術

| カテゴリー      | 使用技術                                      |
|-----------------|-----------------------------------------------|
| フロントエンド  | React 18.3.1<br>Next.js 14.2.3<br>TypeScript 5.4.5  |
| バックエンド DB   |Supabase |
| インフラ        | Vercel                                  |
| 認証            | Jwt                             |
| CI           | GitHub Actions<br>Jest<br>Cypress                                |
| 開発環境        | Docker                                        |
| API             | GoogleMapsAPI <br> OpenAPI                    |![インフラ構成.png]




# 技術選定理由
### フロントエンド（Next)
コンポーネント化により、コードの再利用と保守がしやすくなりました。各UI要素を独立した部品として分けることで、複数るファイルを同時に作業しやすくなり、新機能を追加する際の手間が減りました。また、Reactを使うことで、JavaScriptよりもシンプルにコードを書くことができ、開発がスムーズになりました。

### バックエンド（Supabase）
・コスト効率: オープンソースで基本機能が無料のため、運用コストを大幅に削減できます。
・リアルタイムデータベース: PostgreSQLベースのリアルタイムデータベースを提供し、即時性の高いアプリケーションが構築可能です。
・簡単なセットアップと統合: バックエンドのセットアップが簡単で、フロントエンドとの連携がシンプルです。

### テスト(Jest Cypress)
- Jest: 単体テストに使用しています。コンポーネントごとの挙動を細かくテストすることで、機能が意図した通りに動作することを確認しています。また、テスト駆動開発（TDD）を行うことで、バグの発見が早まり、効率的な開発が可能になりました
- Cypress: エンドツーエンド（E2E）テストを実施しています。ユーザーがアプリケーションを操作する一連の流れをテストし、各機能が期待通りに動作するか確認しています。特に、地図上のトイレ位置の案内やルート表示など、ユーザー体験に直結する部分のテストを重点的に行いました
 
# おわりに
この記事を読んでいただき、ありがとうございます。アプリのリニューアルにあたり、多くの新しい技術に挑戦し、ユーザー体験を向上させるための工夫を重ねてきました。今回のリニューアルが皆様にとってより快適なトイレ探しのサポートとなることを願っています。

また、これまで相談に乗ってくれた方々や、様々なアドバイスをくださった皆様に心から感謝申し上げます。皆様のご支援がなければ、このリニューアルは実現できませんでした。これからも「Quick Clean Restroom Map」をよろしくお願いいたします。
Terraformの環境をtfenvを使ってCloud9に構築する

# Terraformのバージョン管理について
TerraformはプロジェクトごとにTerraformのバージョンが異なるときに対応するため、それぞれバージョンを使い分けることができるように、tfenvを使ってterraformを管理する。
tfenvは、git cloneを使って設定していく。
[参考文献](https://github.com/tfutils/tfenv)

1.まずは、ソースコードをクローンする。
`git clone https://github.com/tfutils/tfenv.git ~/.tfenv`

2.リンクの設定をする。
`echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bash_profile`
`sudo ln -s ~/.tfenv/bin/* /usr/local/bin`


3.リンクの設定したところを確認する。
`ll /usr/local/bin/terraform`

`ll /usr/local/bin/tfenv`

4.tfenvでどのバージョンを追加したのか、確認する。
`tfenv --version`

5.tfenvで自分の好きなバージョンを入れる。
`tfenv install 1.5.0`

6.tfenvで利用するバージョンを指定する。
`tfenv use 1.5.0`

7.tfenvで設定したバージョンと同じterraformが起動するか確認する。
`terraform --version`

これにて完了。

あとは、自作したソースコードをgit cloneしてきて、`terraform init`、`terraform apply`するだけです。


## 【Terraformのバージョンについて】追記
Terraformのバージョンを確認するには、下記のURLを参考にすることで確認することができる。
[Terraformのリリースノート](https://github.com/hashicorp/terraform/releases)

## tfenvコマンドの使い方
下記のコマンドで、コマンドのオプションのリストを出すことができる。
```
tfenv --help 
Usage: tfenv <command> [<options>]

Commands:
   install       Install a specific version of Terraform
   use           Switch a version to use
   uninstall     Uninstall a specific version of Terraform
   list          List all installed versions
   list-remote   List all installable versions
   version-name  Print current version
   init          Update environment to use tfenv correctly.
   pin           Write the current active version to ./.terraform-version
```


- tfenv --versionでtfenvのバージョンを確認可能。
```
root@c9507ef71d2b:/# tfenv --version 
tfenv 3.0.0-49-g39d8c27
```

- tfenv listでインストールされているリストを確認
```
root@c9507ef71d2b:/# tfenv list 
  1.9.2
No default set. Set with 'tfenv use <version>'
```

- tfenv useコマンドで使うバージョンを指定することができる。
 ```

root@c9507ef71d2b:/# tfenv use 1.9.2
Switching default version to v1.9.2
Default version (when not overridden by .terraform-version or TFENV_TERRAFORM_VERSION) is now: 1.9.2
```
- tfenv use　コマンドで、設定したバージョンの左側に`*`マークが付与される。
```
root@c9507ef71d2b:/# tfenv list 
* 1.9.2 (set by /root/.tfenv/version)
 ```
MZK-W04Nのイメージ

RT1310が使われていてarmbm-mrubyが動くはずなので試してみます。

このモジュールのu-bootはtftpbootがサーバーでコンフィグレーションされています。なのでホスト側からtftpでputして焼きます。

mkimageで作ったファイルをflashのカーネル領域の0x1f020000から焼くと、エラーになり起動できません。

```
****************Kernel CheckSume**************
Check sume err: sum=0000f1d1

5VT9000-MPW1# 
```

u-bootのチェック以外の処理が入っているようです。しかしrun rombootすると起動できます。

試しに空のファイルを焼いてみます。

% dd if=/dev/zero of=main.uimg bs=1m count=1

```
****************Kernel CheckSume**************
Checksum ok!

## Booting image at 1f020014 ...
Bad Magic Number
5VT9000-MPW1# 
```

このu-bootはChecksum okの時には環境変数のkernel_addrを0x1f020014に書き換えてイメージを起動するようです。

先頭に20バイトの拡張情報があり、空でも大丈夫みたいなので、空のデータをつけてみます。

```
****************Kernel CheckSume**************
Checksum ok!

## Booting image at 1f020014 ...
   Image Name:   mruby on YABM
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    810676 Bytes = 791.7 kB
   Load Address: 40010000
   Entry Point:  40010000
   Verifying Checksum ... OK
OK

Starting kernel @40010000...

armbm-mruby f8a5646(master)-dirty Tue Jul 16 21:09:00 JST 2024
mruby 73337133f(master)
MRB SIZE 376
MRB SHA256 e45d678abb58875687ea2da6705301d14cf168747d15884ebde07a6649606602
Hello Bear Metal mruby on YABM.........................
```

ZRouterでも対応していました。

https://qiita.com/yamori813/items/3b14661f08a08aacbc33
Ideogramの無料プラン変更：利用者への影響と詳細解説

## はじめに

Ideogramは、クリエイティブデザインの分野でリーディングプラットフォームとして急速に成長を遂げています。この成長に伴い、無料ユーザーの数が劇的に増加し、サービスの待ち時間に大きな影響を与えています。そこでIdeogramは、すべてのユーザーに公平なアクセスと高品質なサービスを提供するため、無料プランの変更を決定しました。

本記事では、この変更の詳細、その影響、そして利用者の皆様にとって重要な情報をわかりやすく解説していきます。

## 変更の概要

### 日時
- **変更開始日時**: 2024年7月14日 午後8時（東部時間）/ 7月15日 午前0時（UTC）

### 主な変更点
- **1日あたりのプロンプト数**: 10プロンプトに制限

## 無料プランの新しい特徴

変更後も、無料プランでは以下の機能が引き続き利用可能です：

1. **Ideogram 1.0**
   - 最先端のプロンプト遵守性
   - 高品質なテキスト生成

2. **Magic Prompt**
   - 初期プロンプトの強化
   - プロンプトの翻訳機能

3. **Describe**
   - 画像から詳細な説明を生成

これらの機能は、クリエイティブな作業や日常的なタスクに大きな助けとなります。

## 変更の理由

### 1. ユーザー数の急増
Ideogramの人気が高まるにつれ、無料ユーザーの数が劇的に増加しました。これは、プラットフォームの成功を示す一方で、新たな課題をもたらしました。

### 2. 待ち時間の増加
ユーザー数の増加に伴い、サービスの待ち時間が長くなる問題が発生しました。これは、ユーザーエクスペリエンスに直接影響を与える重要な課題です。

### 3. 公平なアクセスの確保
すべてのユーザーに公平なサービスを提供するため、利用制限を設けることが必要となりました。これにより、リソースの公平な分配が可能になります。

### 4. サービス品質の維持
高品質なサービスを維持するためには、リソースの適切な管理が不可欠です。この変更により、Ideogramは一貫して高品質なサービスを提供し続けることができます。

## 有料プランの魅力

Ideogramは、より多くのプロンプトや高度な機能を必要とするユーザーのために、競争力のある有料プランを提供しています。有料プランの特徴は以下の通りです：

1. **増量されたプロンプト数**
   - 無料プランよりも多くのプロンプトが利用可能

2. **プライベート生成**
   - 個人的なプロジェクトや機密性の高い作業に最適

3. **画像アップロード機能**
   - 独自の画像を使用したプロンプト生成が可能

これらの機能は、プロフェッショナルなクリエイターや企業ユーザーにとって特に魅力的です。

## ユーザーへの影響

### 1. 無料ユーザーへの影響
- 1日あたりのプロンプト数が制限されます
- 基本機能は引き続き利用可能

### 2. 有料プラン検討者への影響
- より多くのプロンプトと高度な機能が利用可能になります
- ビジネスニーズに合わせたカスタマイズが可能になります

## まとめ

Ideogramの無料プラン変更は、サービスの持続可能性と品質維持を目的としています。この変更により、すべてのユーザーがより公平で効率的にサービスを利用できるようになります。

無料プランでも引き続き強力な機能が利用可能であり、より高度なニーズを持つユーザーには魅力的な有料プランが用意されています。Ideogramは、ユーザーコミュニティの一員である皆様に感謝し、今後もクリエイティブデザインの分野でリーディングプラットフォームとしての地位を強化していくことを約束します。

この変更に関するご質問や詳細については、Ideogramの公式サイトやサポートチームにお問い合わせください。皆様のクリエイティブな挑戦を、Ideogramは今後も全力でサポートしてまいります。

## 参考サイト

https://ideogram.ai/pricing
CSS: ぴょこぴょこhamburger

よく見掛けるお品書き一覧を小さいbuttonに格納する技。触れたら一気に全開丸出し、離れたら爆縮という動作。画面右上配置です。改造すれば配置はどうにでもなるでしょう。
```html
<style>
.menu{
	background-color:#424;
	background-color:rgba(64,32,64,.75);
	box-shadow:1px 1px 2px 2px rgba(0,0,0,.5);
	border-radius:0 0 0 10px;
	font-size:1.25em;
	color:#fff;
	margin:0;
	padding:0 8px 0 30px;
	width:0;
	height:24px;
	-moz-transition:all .25s;
	-webkit-transition:all .25s;
	-o-transition:all .25s;
	-ms-transition:all .25s;
	transition:all .25s;
	overflow:hidden;
	line-height:1.25em;
	position:fixed;
	top:0;
	right:-20px;
	z-index:1000
}
.menu:before{
	border-right:2px solid #212;
	color:#fff;
	content:"\2261";
	display:block;
	background-color:#a6a;
	background-color:rgba(160,96,160,.75);
	font-weight:700;
	position:absolute;
	left:0;
	width:18px;
	height:100%;
	text-align:center
}
.menu:hover{
	overflow:auto;right:0;height:auto;width:auto
}

/* 配色. 動作と無関係 */
a{color:#fff;text-decoration:none}
a:hover{color:#f88}
</style>
<body>
<dl class=menu>
<dt><a href=#>Information Theory</a>
<dt><a href=#>Godel's first incompleteness theorem</a>
<dt><a href=#>algorithmic probability</a>
<dt><a href=#>Chain rule</a>
<dt><a href=#>Kolmogorov complexity</a>
</dl>
</body>
```
modal boxとの合体技
<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="YzoyjOq" data-pen-title="CSS hamburger + modal box" data-user="xezz" style="height:300px;box-sizing:border-box;display:flex;align-items:center;justify-content:center;border:2px solid;margin:1em 0;padding:1em"> <span>See the Pen <a href="https://codepen.io/xezz/pen/YzoyjOq">CSS hamburger + modal box</a> by xezz (<a href="https://codepen.io/xezz">@xezz</a>) on <a href="https://codepen.io">CodePen</a>.</span></p><script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
GitHubのREADMEにGyazoショート動画を表示させる方法

# はじめに
この記事では、GitHubのREADMEにGyazoショート動画を載せる方法についてまとめています。

READMEにGyazoのショート動画を載せることで、アプリや機能の紹介がしやすくなります。

この記事が皆さんのお役に立てば嬉しいです！

https://gyazo.com/

# 前提
- Gyazoに登録済みであること

https://gyazo.com/

# 問題
READMEにGyazoから「マークダウン」でコピペしても動画が表示されず、リンクとして表示されてしまいます。

# 解決方法

Gyazoで撮影した動画のマークダウン横のGIFをクリックしてコピペすることで解決できます。

![スクリーンショット 2024-07-16 20.27.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3772961/a5cdaafb-0a76-5ac9-b878-ad5e92df89db.png)

### README

以下のような拡張子が```.gif```のコードをREADMEに貼り付けます。

```:README.md
[![Image from Gyazo](https://i.gyazo.com/313adb4e2f7aa50a63fa8367680b2e17.gif)](https://gyazo.com/313adb4e2f7aa50a63fa8367680b2e17)
```

これでGyazoのショート動画がGitHubのREADMEに表示されます。

[![Image from Gyazo](https://i.gyazo.com/8593708d03a9eeac05a97c4d2e4da939.gif)](https://gyazo.com/8593708d03a9eeac05a97c4d2e4da939)

# おまけ(アプリ機能紹介テーブル風)

次のように記述することで、アプリ紹介風のテーブルを作成することができます。

```:README.md
| アプリ機能1 | アプリ機能1 |
|:-----------:|:------------:|
| GyazoのマークダウンGIF | GyazoのマークダウンGIF |
| アプリ機能の説明が入ります。アプリ機能の説明が入ります。 | アプリ機能の説明が入ります。アプリ機能の説明が入ります。 |

</br>

| アプリ機能3 | アプリ機能4 |
|:-----------:|:------------:|
| GyazoのマークダウンGIF | GyazoのマークダウンGIF |
| アプリ機能の説明が入ります。アプリ機能の説明が入ります。 | アプリ機能の説明が入ります。アプリ機能の説明が入ります。 |
```

### READMEビュー

[![Image from Gyazo](https://i.gyazo.com/313adb4e2f7aa50a63fa8367680b2e17.gif)](https://gyazo.com/313adb4e2f7aa50a63fa8367680b2e17)

### テーブル説明

HTMLタグでもテーブルの記述は可能ですが、こちらの方が直感的な書き方でわかりやすいと思います。

### 空間を空ける

テーブルとテーブルの間に```</br>```を入れておりますが、間を空けるために入れております。デフォルトでも間はありますが、近すぎる気がしましたので。ここはお好みで入れてください。

# おわりに
ちょっとした記事ですが、お役に立てれば幸いです。

私自身、どうやって表示できるのかわからず数日調べていましたので、この記事をご覧になった方にはこんなところで時間をかけて欲しくないと思いました。

もし、この記事の内容に不備や改善点などがありましたら、ご指摘いただけると嬉しいです。

# 参考

https://qiita.com/Qiita/items/c686397e4a0f4f11683d#%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB
作業報告に「完了」という言葉をあまり使いたくない

## 前提
- 私：社会人2年目、まだ作業者レベル
- 報告相手：社内のチームリーダー(初鑑)→社外のプロジェクトリーダー(再鑑)（→ユーザー（ユーザーレビュー））

## どこから「完了」と言えるか
- 作業終了時点：
    - 初鑑で指摘がほぼ必ず出る
    - とても「完了」とは言えない

- 初鑑終了時点
    - 再鑑でも指摘は結構出る（あまり良くはないが）
    - まだ「完了」とは言えない

- 再鑑終了時点
    - ここまで終わると以降で指摘はほぼ出ない
    - 「完了」といっても差し支えなさそう

- ユーザーレビュー終了時点
    - 真の「完了」
    - これ以降で対応が必要になる場合はほぼユーザーが原因

## 結論
- ユーザーに出せる状況になった時（ユーザーレビュー前）に初めて「完了」したといえる

## けど
- 終了と完了の違いで怒られたことはないので厳密に気にする必要はないかもしれない
- それよりも指摘を減らすように努めるべき
SECCON Beginners CTF 2024 に参加してみた

# はじめに

今更ですが、2024/6/15(土) ～ 2024/6/16 (日) まで開催された、
SECCON Beginners CTF 2024 というオンラインイベントに参加しました。
初めてのCTF参加となります。（初心者の僕にとってはめちゃくちゃ難しかったです）

https://www.seccon.jp/13/seccon_beginners/content.html




# CTFとは
セキュリティに関する専門知識や技術を駆使して、隠されている答え（Flag）を見つけるイベントです。（専門知識が必要な謎解きゲームのようなもの）

様々な分野の問題を解いて得点を競う形式（Jeopardy形式）や、チーム間で攻撃と防御を行う形式（Attack & Defense形式）が存在します。

今回参加したSECCON Beginners CTF 2024 は、24時間以内に出題された問題を解く Jeopardy形式 のイベントです。




# 出題分野

SECCON Beginners 2024 は以下の分野が出題されました。
| 分野 | 説明|
|:-----------|:------------|
Crypto (暗号)|暗号技術に関する問題。暗号化されたメッセージの解読など
Reversing (リバースエンジニアリング)|与えられたプログラム等の解析など
Web|Webアプリの脆弱性を突く問題。SQLインジェクション・クロスサイトスクリプティング(XSS)など
Pwnable (バイナリ攻撃)|バイナリの脆弱性を利用する問題。バッファオーバーフローなど
Misc（その他）|ステガノグラフィ（画像や音声ファイルに隠されたメッセージの発見）など




# 実際はこんな問題が出ました

CTF 初参加ということもあり、ほとんどの問題を解くことができなかったのですが、
そんな私でもある程度解けた問題をいくつか紹介します。



## 1. 数字当てゲーム攻略
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/979767/b1d9d75b-5897-bcf2-5725-1d0ea2c59141.png">

上記に記載のURLにアクセスすると、ランダムに選ばれた1桁の数字を当てる、数字当てゲームで遊ぶことができます。
数字が当たると1ポイント加算され、ポイントに応じてランクが決定するようです。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/979767/2474a897-67f7-2c84-f99e-3ad09289099a.png">

getRank.tar.gz をダウンロードすると、Typescript で書かれたソースコードがダウンロードできました。ランクは以下の配列で定義されているようです。
```typescript:main.ts 抜粋
const RANKING = [10 ** 255, 1000, 100, 10, 1, 0];
```
初期ランクが6、1点以上でランク5、10点以上でランク4……とランクが上がっていき
ランクが1になれば、Flagをゲットできるようでした。

つまりランク1になるためには、10 ** 255（10 の 255乗…！）ポイント以上を取得する必要がありそうです。
ソースコードを確認してみると、変数 score が再代入可能なletで定義されていることがわかります。
```typescript:main.ts 抜粋
let score = parseInt(input);
```
そこで、Google Chrome の開発者ツールで score を変更する…という流れで解いていきます。
\# 実際はこの後、高得点過ぎるとチート対策としてスコアが減らされる仕組みがあったりします。




## 2. 暗号化された文章の復元
問題文の日本語訳は「safe prime を使えば RSA暗号は安全になるよね？」でしょうか。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/979767/65c590b6-6baf-74ce-34ab-ddffcbbea5af.png">

Safe_Prime.tar.gz をダウンロードすると、以下のようなテキストファイルがありました。
```js:output.txt
n = 2929273......
c = 4079147......
```

```python:chall.py
import os
from Crypto.Util.number import getPrime, isPrime
FLAG = os.getenv("FLAG", "ctf4b{*** REDACTED ***}").encode()
m = int.from_bytes(FLAG, 'big')
while True:
  p = getPrime(512)
  q = 2 * p + 1
  if isPrime(q):
    break
n = p * q
e = 65537
c = pow(m, e, n)
print(f"{n = }")
print(f"{c = }")
```



RSA暗号は詳しくなかったので、色々とWEBで調べました。
ソースコードと安全素数の定義より
今回 q は 2p + 1 で表されることがわかります。
そのうえで、素数の組み合わせ p q を求めて
C（暗号化済のフラグ）から、原文を復号することで
「ctf4b{*** REDACTED ***}"」となっている部分がわかるようでした。

https://zenn.dev/lilac/articles/bad1900aa8f0c0


# まとめ

今回参加したイベントは、初心者向け、といいつつ完全な初心者にはハードルが高かったです。
ただ、じっくり調べつつ、楽しみながら学ぶいい機会にはなりました。

一般的な謎解きゲームとは違い、知ってる人しか遊べない遊び、に参加できる優越感や、
合法的にハッキング？できる楽しさもあり、難しかったものの、来年も参加したいなと思えるイベントでした。


また今回のような年1回のものではなく、CTFができる常設のサイトがいくつもあるようなので、まずはこういったサイトで勉強してみようかなと思います。

https://tech.kusuwada.com/entry/2020/12/02/065100

---

https://naokichigyoza.com/
【Qiita Engineer Festa 2024】投稿マラソン完走したよ〜

## 完走しました 🎉🎉
なんだかんだ。完走しました。
ここ38日間、張り詰めた糸のように夜な夜な執筆してたので今回の記事はゆる〜く書かせてください。

## 当初は完走が目標ではありませんでした
はじめは、完走するなんて考えてませんでした。
正直、「仕事しながらで絶対に無理、完走できるやついんの？」と思ってたくらい。ハーフマラソン行ければいいかなって（19記事）

ほんとは取りたい資格あったからそっちを優先しようかな、と思ってたくらい。（資格を後回しにしました）

## 完走して変わったこと
### 自信がつきました！圧倒的に。
Qiitaの記事ってただのブログありません。技術ブログです。
技術記事ですので検証がマストです。からの執筆作業。

しかも、業務上で知ったことはほとんど書けないので記事にできることってかなり限られます。

そんな中、ネタを考えて、技術検証して、文章構成考えて、タイトル捻って（時には捻らず）...。

1日1本、38日間書き続けたので、自信くらい持たせてください 🍔

### 業務上で役立つことが多くありました。
- 記事を書く上で調査して知ったこと
- 検証を通して新しく身に着けた技術

業務に取り入れたことかなり多くあったなと。

## どのくらい時間かけた？
よくある質問ですよね。
**「この資格の学習に何時間かけましたか？」**

人によって個人差あるので、それ聞いてどうすんの？って思うんですが、一応計測しておきました。

![スクリーンショット 2024-07-15 21.37.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334980/74197163-b241-f614-3a76-15224fac5e6e.png)

Toggl Trackで時間計測してたんですが、**本キャンペーンにかけた時間は50時間** 🥱🥱 
（欠伸出ちゃいました）

実装の時間は別で時間入力してますので、**概算でも60時間**は行ってそう。（入力漏れも普通にある）

## 燃え尽き症候群には絶対になりません
時間も労力も正直かなりかけてました。
だから、「キャンペーンが終わったらどうなるか心配...。」

とは、正直ならないです。

**記事書くことを目標にはしてなかったので。**

やりたいことがあってそれを達成して、**せっかくだったら記事にしよう**、くらいです。
記事を書くことを第一目標にすると、自分の場合内容が薄くなっちゃうんですよね。

なので、記事投稿に対する思い入れからの燃え尽き症候群はありえません。

アプリ開発ももっとがんばりたいし取りたい資格もあるから、まだまだ燃え尽きません。

## 読んでほしい記事
3本だけ紹介させてください。
読んでいただけると幸いです。興味があればぜひ。

https://qiita.com/umekikazuya/items/a3260117bbc64e6673c3

https://qiita.com/umekikazuya/items/a8751e422bf198cde70f

https://qiita.com/umekikazuya/items/c5c4d73fa52c6b133a2a

## アナリティクスから学んだこと
がんばって書いた記事と実際に読まれている記事って、意外と一致しません。

## 今後も記事投稿はやめません
さすがに毎日は上げません。
書きたい記事はいくつかあるので、気が向いたらあげます。

## まとめ
最後まで読んでいただきありがとうございました。
ガード節とは何か、綺麗なコードを書くために。

## コードを綺麗にする
コードを綺麗にする(可読性を上げる)事によって、未来の自分を助けることになります。

## ガード節
ガード節とは、メソッド(関数)のはじめに例外などを処理することです。
+ **悪い例**
 ネストが3段もあり、ifとelseが多く、とても読みづらいです。
  ```python
  def is_hoge_check(age, state, time):
      if(age >= 20):
          if(state == "active"):
              if(time >= 10):
                  return True
              else:
                  return False
          else:
              return False
       else:
          return False
  ```
  <br>
+ **良い例**
 悪い例とは違い、ネストが1段でelseが無く見やすくなりました。
  ```python
  def is_hoge_check(age, state, time):
      if(age < 20):
          return False
      if(state != "active"):
          return False
      if(time < 10):
          return False

      return True
  ```
 <br>
 
+ **例外処理** 
 一番最初に例外をなくすことで、想定外の挙動が起こらない前提でメインの処理を書けるようになります。
  ```python
  def hoge(args):
      try:
          ~あらゆる例外~
      except Exception:
          print("error")

      ~メインとなる処理~
  ```


## まとめ
ガード節を使うことで、余計なことを考えずにメインとなる処理をかけるという利点に加えて、エラーを未然に防ぐ効果もあります。
意識するだけで使えるので積極的に使うようにしましょう。


## 参考
https://amzn.asia/d/0gCUUKCP
ITパスポート 通信サービス

・ブロードバンド
広帯域で高速・大容量が特徴の回線やサービス
・FTTH
光ファイバ回線を利用する
・CATV
ケーブルテレビの回線を利用する

・ふくそう
通信が急増することによって、ネットワークの許容量を超えて、つながりにくくなること

・データの伝送速度（bps）
１秒間に転送できるビット数（ビット/秒）で表す

・モバイル通信
・SIMカード
携帯電話や契約者IDなどが記録されたもの

・テザリング機能
スマートフォンなどをアクセスポイントのように用いて、PCやゲーム機などからインターネットを利用する

・MVNO
格安SIMの事業者
移動体通信事業者から回線網を借りて、サービスを提供する事業者

・キャリアアグリゲーション
複数の異なる周波数帯を束ねて、同時に使用することで無線通信の高速化や安定化を図る手法

・Qi（チー）
スマートフォンやワイヤレスイヤホンなどを、ケーブルなしにワイヤレスに充電できる規格

・伝送時間の計算
伝送時間＝データ量÷伝送速度

例
20Mバイトのデータを伝送速度80Mbpsの回線で転送する時間を求める
20Mバイトをビットに換算すると、20Mx8=160Mビット
よって、伝送時間＝160Mビット÷80Mbps＝2秒
Account Engagementのごみ箱のプロスペクト同期

# はじめに
Account Engagementのプロスペクトはデフォルトで10,000件までという上限があり、超過した状態ではメールを送信することができず、追加料金が必要となる。都合により、上限を変えられないが、10,000件以上のプロスペクトを対象にメールを送付する必要があり、プロスペクトの同期仕様、ごみ箱のプロスペクトの挙動について調査した際の備忘を記録する。2024年7月時点の仕様に基づく内容になります。

# Sales Cloudとの同期
プロスペクトはSales Cloudのリードまたは取引先責任者とデータを同期することができる。プロスペクトを作成し、Sales Cloud側に同期するレコードがない場合、デフォルトではリードが作成される。
リードでなく、取引先責任者を直接、作成したい場合は、リバース同期という設定で変更できる。リバース同期は自分で設定することができず、サポートに依頼して設定してもらう。

同期の仕様については、以下のサイトが非常に参考になった。
[【完全版】Account Engagement(旧 Pardot) とSalesforceのデータ連携仕様の徹底解説](https://www.strh.co.jp/knowledge/pardot-salesforce-data-integration)

## リバース同期した際の取引先責任者の取引先
リバース同期により作成した取引先責任者には、紐づく取引先が存在しない状態になる。取引先がなくても、取引先責任者は作成できるが、手動で編集した際に、取引先が存在しないというエラーになり、保存できない。フローなどで設定するのがいいだろう。

## リードを作成し、フローで取引先責任者を作成してもいい
プロスペクトと取引先責任者と同期したいので、リバース同期する以前は、リード作成を契機とするレコードトリガーフローでリードを削除して、取引先責任者を作成していた。しかし、このやり方は、プロスペクトとリードが同期状態になっているため、リードを削除した時点で、プロスペクトも削除されてしまっていた。その後、取引先責任者を作成した時点で、再度、新規で取引先責任者に同期するプロスペクトが作成されていたため、一見、やりたいことが実現できたように見えていたが、ごみ箱に最初に作成したプロスペクトが入っているので、よくないやり方である。リード作成時にフローで対応するのであれば、Apexトリガーでリードを取引開始にして、取引先責任者にするのがよい。

# カスタムオブジェクトの同期
Sales CloudのカスタムオブジェクトもAccount Engagementにデフォルト4コまで同期することができる。プロスペクトに紐づく情報として、ダイナミックリストの条件として参照することができる。Engagement Stuidoではプロスペクトに紐づく情報として参照できない。

# プロスペクトのごみ箱の仕様
プロスペクトを削除するとデータは完全削除されず、一旦、ごみ箱に移動する。ごみ箱の仕様について、以下を確認した。

- 完全削除は明示的に行う必要があり、自動で削除されることはない
- ごみ箱に入っているプロスペクトに対してメール配信を行うことはできない
- ごみ箱に格納できるプロスペクト数に上限値はない
- ごみ箱に格納したプロスペクト数は契約上のプロスペクトの上限数に計上されない

# プロスペクトがごみ箱にあるの状態でのメール、フォームアクションの挙動
プロスペクトがごみ箱に入っている場合に、メール、フォームによるアクションを実行し、同期対象の取引先責任者に情報が反映されるかを検証した。

## プロスペクトがごみ箱、取引先責任者が存在（更新により、コネクタ条件不一致のまま）
|  | プロスペクト（ごみ箱） | 取引先責任者 |
|:-----------|:------------:|:------------:|
| メール開封            | 更新しない | 更新 |
| メールURLクリック     | 更新しない | 更新 |
| フォーム入力          | ごみ箱から一時的に復元し、更新後、ごみ箱にもどる | 更新 |
| フォーム完了アクション | ごみ箱から一時的に復元し、更新後、ごみ箱にもどる | 更新 |

## プロスペクトがごみ箱、取引先責任者が存在（更新により、コネクタ条件が一致に変更）
|  | プロスペクト（ごみ箱） | 取引先責任者 |
|:-----------|:------------:|:------------:|
| メール開封            | 更新しない | 更新 |
| メールURLクリック     | 更新しない | 更新 |
| フォーム入力          | ごみ箱から復元し、更新 | 更新 |
| フォーム完了アクション | ごみ箱から復元し、更新 | 更新 |

# プロスペクトのコネクタ条件変更時のプロスペクト同期
プロスペクトのコネクタ条件をデフォルト（条件なし）に変更した場合、同期はトリガーされないので、注意。

| プロスペクト | 取引先責任者 | コネクタ条件 | コネクタ条件変更後のプロスペクト |
|:-----------|:------------:|:------------:|:------------:|
| 存在しない   | 存在 | 不一致 -> 一致に更新 | 新規作成される |
| 存在しない   | 存在 | 不一致 -> デフォルト（条件なし）に更新 | 更新しない |
| ごみ箱に存在 | 存在 | 不一致 -> 一致に更新 | ごみ箱から復元 |
| ごみ箱に存在 | 存在 | 不一致 -> デフォルト（条件なし）に更新 | 更新しない |

# まとめ
メールにプロスペクトの項目を更新するフォームURLを掲載しておき、プロスペクトに対して、メールを送信する。メール送信後、コネクタ条件を変更し、メール送信したプロスペクトがごみ箱に入っても、メールをみて、フォームを入力してもらうと、ごみ箱のプロスペクトに対して、項目の更新が行われ、取引先責任者にも反映される。プロスペクトがごみ箱に行ってしまうので、Account Engagement上でのリアルタイムな集計はできないが、取引先責任者に対して、項目を更新することは可能である。
Web開発プロジェクトの契約と納品の流れ

## Web開発プロジェクトの契約と納品の流れ

### はじめに
この記事では、Web開発プロジェクトでの企業（受託）がエンド企業と契約を結び、最終納品と支払いまでの一般的な流れについて解説します。契約の各ステップで必要な手続きや注意点についても触れています。

### 目次
1. [契約前の準備](#1-契約前の準備)
2. [契約交渉](#2-契約交渉)
3. [契約書の作成と確認](#3-契約書の作成と確認)
4. [契約締結](#4-契約締結)
5. [プロジェクトの開始](#5-プロジェクトの開始)
6. [プロジェクト管理と進捗報告](#6-プロジェクト管理と進捗報告)
7. [最終納品と検収](#7-最終納品と検収)
8. [支払いと契約完了](#8-支払いと契約完了)

### 1. 契約前の準備
#### 1.1 要件定義とヒアリング
- **初回打ち合わせ**: エンド企業からプロジェクトの概要と要件をヒアリングします。
- **要件定義書の作成**: 受託開発企業が要件定義書を作成し、エンド企業と共有・確認します。

#### 1.2 基本契約と秘密保持契約
- **基本契約**: 全体的なビジネス関係を規定する基本契約を締結します。
- **秘密保持契約 (NDA)**: 機密情報の保護に関する契約を締結します。

#### 1.3 見積もり
- **費用見積もり**: プロジェクトの規模や要件に基づき、開発費用の見積もりを行います。
- **スケジュール見積もり**: プロジェクトのスケジュールを見積もり、マイルストーンを設定します。

:::note info
Tips
私が経験した中には、工数出しの際に以下のような内容も含め提案することが多いです。
**工数**: プロジェクトに必要な作業時間。
例.機能一覧と人日の記載をしたもの
**スケジュール**: 各作業の予定と納期。
例.WBSやガントチャート
**納品物**: 提供するソフトウェアや関連資料。
例.ソースコード、基本設計書、詳細設計書、デザインなど
**体制**: プロジェクトに携わるチームの構成。
例.PM、PLや関係者、ベンダーや人数がわかる体制図

また、要件定義時に提案することも多いですが、工数出しやスケジュール作成時に弊社の強みとして、こういう風に開発しますのような差別化をして提案することも多いです。
例. プロトタイプ開発を行いお客様側でフローに問題がないかリリース前に確認をすることができます。とか、テストに関してはユニットテストやE2Eテスト含め自動テストを行い品質を管理しています。など
:::

### 2. 契約交渉
#### 2.1 価格交渉
- **価格調整**: エンド企業の予算に合わせた価格交渉を行います。
- **支払い条件**: 支払いのタイミングや方法について合意します。

#### 2.2 スコープ交渉
- **スコープの確定**: 開発の範囲を明確にし、プロジェクトのスコープを確定します。
- **変更管理**: スコープ変更時の対応方法を合意します。

### 3. 契約書の作成と確認
#### 3.1 契約書のドラフト作成
- **契約書の項目**: 開発内容、納期、支払い条件、知的財産権、機密保持などの項目を含めます。
- **法務チェック/リーガルチェック**: 法務部門や弁護士による契約書の確認を行います。

#### 3.2 契約書のレビュー
- **レビューと修正**: 契約書をエンド企業と共有し、必要に応じて修正を行います。
- **最終確認**: 双方の合意が得られたら、契約書を最終確認します。

### 4. 契約締結
#### 4.1 契約書の署名
- **署名と捺印**: 双方の代表者が契約書に署名し、捺印します。
- **契約書の保管**: 契約書を適切に保管します。

### 5. プロジェクトの開始
#### 5.1 キックオフミーティング
- **プロジェクトチームの編成**: プロジェクトに関わるメンバーを確定します。
- **初回ミーティング**: プロジェクトの目標や進め方について初回のミーティングを開催します。

### 6. プロジェクト管理と進捗報告
#### 6.1 進捗管理
- **定期報告**: プロジェクトの進捗状況をエンド企業に定期的に報告します。
- **問題解決**: 発生した問題に対して迅速に対応し、解決します。

#### 6.2 品質管理
- **コードレビュー**: 開発したコードをレビューし、品質を確保します。
- **テスト**: プロダクトの各フェーズでテストを実施し、バグを修正します。

### 7. 最終納品と検収
#### 7.1 納品
- **納品物の確認**: 合意された成果物をエンド企業に納品します。
- **動作確認 (ユーザー受け入れテスト - UAT)**: エンド企業が納品物の動作を確認し、検収テストを行います。

#### 7.2 検収
- **検収完了**: エンド企業から検収完了の確認を受け取ります。
- **修正対応**: 検収で発見された不具合を修正し、再度納品します。

### 8. 支払いと契約完了
#### 8.1 請求書発行
- **請求書の作成**: 契約に基づき、請求書を作成します。
- **請求書の送付**: エンド企業に請求書を送付します。

#### 8.2 支払い
- **支払い確認**: エンド企業からの支払いを確認します。
- **領収書発行**: 支払い完了後に領収書を発行します。

#### 8.3 契約完了
- **プロジェクト完了報告**: プロジェクト完了の報告を行い、契約を完了とします。
- **アフターフォロー**: 必要に応じてアフターフォローを行います。

### まとめ
以上、契約周りのフローをまとめました。企業によって異なる場合もありますが、基本的な流れはこのようになります。受託開発企業では、契約周りも含めてクライアントの方と話すこともあるかと思いますので、エンジニアの方やクライアントと話す機会がある方の参考になれば幸いです！
UbuntuでUbuntu 24.04のBootable USBを作成する

### 用意するもの

- Ubuntu（今回はUbuntu 22.04）
- 空っぽにしていい6GB以上のUSBメモリスティック（今回はSanDisk USB 3.0 32GB）

### isoファイルの入手

「[Ubuntuを入手する](https://jp.ubuntu.com/download)」から、Ubuntu Desktop 24.04 LTSのisoファイルをダウンロードします。6Gくらいあります。

### Startup Disk Creatorのインストール

Ubuntu Softwareで検索すると、HDDふうのアイコンとUSBふうのアイコンの2つが出てくることがあるが、HDDふうのアイコンのほうでいけました。

![appstore.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3721114/d538b432-e040-0baa-1780-865331772fe3.png "Ubuntu SoftwareでStartup Disk Creatorを検索したウィンドウのスクリーンショット。2つの検索結果が表示されている")

Startup Disk Creatorをインストールすると、「ブータブルUSBの作成」というアプリケーションが使えるようになります。

![installed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3721114/8e2914bc-2f9f-9fda-b3e8-d2af48abba2a.png "「ブータブルUSB...」と表示されたアイコン")

### ブータブルUSBの作成

「ブータブルUSBの作成」アプリケーションを起動すると、「書き込み元のディスクイメージ（.iso）」と「使用するディスク」を選択できるので、ここでそれぞれ選択し、「ブータブルUSBの作成」を実行するだけです。

なにかデータが入っていても、ブータブルUSBの作成の過程で全部消されます。

![create.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3721114/f8ba42c4-0960-754d-4b33-e9179b19d4e8.png "「ブータブルUSBの作成」のウィンドウ。「書き込み元のディスクイメージ（.iso）」と「使用するディスク」の入力欄と「ブータブルUSBの作成」のボタンがある。")

### 感想

昔はもっと苦労した記憶があったけど、あまりにかんたんで驚きました。
韓国に来てわかった日本とのITの違い

# はじめに
自分は現在韓国の大学で情報分野を専攻しているのですが、今回は韓国に来て2年ほど経ってわかったITの側面から見た日本と韓国の違いについてパッと思いつく部分を紹介しようと思います。

# 日本と韓国のITの違い7選
### ①電車でもwifiが使える
韓国着いた時に驚いたのですが韓国の空港周りの電車やソウルの地下鉄等では電車の中でもwifiが使えます。(日本でも使えたらすみません)
### ②みんなカード
最近は日本でもカードで支払いする人が増えていると思いますが、韓国では若い人から高齢の方までほとんどの人がカードで支払いをしています。韓国で現金はほどんど見ないです。韓国の方は割とせっかちな方が多いのでいちいち現金でやり取りするのが面倒なんでしょう(適当)。
### ③ITリテラシーが高い
大学で授業を受けていて思ったのが韓国の学生は男女問わず全員パソコンスキルが高いです。自分がまだ大学1年生でタッチタイピングも全然できない時に周りの韓国の学生はみんな当たり前のように高速タイピングでコードを書いていてよく絶望していました。話を聞くと高校の頃から授業でpythonやJavaを触る授業があったそうです。
### ④みんなwindows
韓国では教授も学生もみんなwindowsです。でもやっぱりMacのデザインが好きな方が多く、Macを使いながら中のosをwindowsで使う人もいるそうです(そんなことできるんか)。ちなみに日本でMacを使う人が多いというのは自分が勝手に思いこんでるだけです。
### ⑤店員がいない店がある
韓国のコンビニでは商品の仕入れの時以外は店員さんがいないとこも多いです。マクドナルドとかでは注文は背丈くらいあるパネル機器でやって受け取る時は番号を確認して店員から受け取るという感じで人との接触がかなり最小限に抑えられています。
### ⑥PCバンの存在
日本にも似たようなとこはあると思いますが、韓国では高性能のPCと高速の回線が配備されているPCがずらっと並んだネットカフェのようなものが多くあります。友達とゲームをするときはわざわざここにきて遊ぶ人も多いです(自分は行ったことない)。ちなみに韓国のPCバンと日本のセブンイレブンの店舗数はほとんど同じらしいです。
### ⑦学歴・実力主義採用が多い
韓国が幼い頃からの学歴競争が激しいということはご存じの方多いかと思いますが、同時に実力主義の風潮もかなり強く日本と比べコーディングテストやポートフォリオに求められるレベルが高いと感じます。
# おわりに
多分ちゃんと探せばもっとあると思うのですが、一旦パッと思いつくのはこれくらいでした。また何か見つけたら追加していこうと思います。
【Go言語】名前付き戻り値

# はじめに

Goでは名前付き戻り値(Named Return Value)はあまり使われない。
この記事では、名前付き戻り値の使い方を解説します。

# 名前付き戻り値とは？

名前付き戻り値を使うと、引数なしの空return文を呼び出せる。

```go
func f(a int) (b int) {
    b = a
    return
}
```

上記の場合だと、戻り値はbの値となる。

# 名前付き戻り値の使用例

非公開のインターフェイスの場合ドキュメントは必須ではない。以下の例は、住所から座標を取得するメソッドを持つインターフェイスである。

```go
type locator interface {
	getCoordinates(address string) (float32, float32, error)
}
```

ドキュメントがないと、`float32`の情報だけでは、緯度か経度かが不明瞭である。
そこで以下のように、名前付き戻り値を使用することで、シグニチャを明示する。

```go
type locator interface {
	getCoordinates(address string) (lat, lng float32, err error)
}

func (l loc) getCoordinates(address string) (lat, lng float32, err error) {
	return 0, 0, nil
}
```

# 無意味な名前付き戻り値

error型がerrorであることは自明なので、名前付き戻り値にはしてはいけない。

```go
func StoreCustomer(customer Customer)(err error) {}
```

# 可読性以外の名前付き戻り値

可読性を高める以外にも、名前付き戻り値が有効なことがある。
以下は、Effective Goで提案された例である。

```go
func ReadFull(r io.Reader, buf []byte) (n int, err error) {
	for len(buf) > 0 && err == nil {
		var nr int
		nr, err = r.Read(buf)
		n += nr
		buf = buf[nr:]
	}
	return
}
```

`n`と`err`は共にゼロ値に初期化sれるので、実装が短くなる。

# 空return

空returnは一般的に短い関数で用いられる。長い関数で使用すると、可読性が悪くなるので、使用すべきではない。1つの関数内で、空returnを使うか、引数のあるreturnを使用するか一貫性を保つことが大事。

# 名前付き戻り値の副作用

名前付き戻り値は、ゼロ値で初期化されるので、意図しないバグを招く可能性がある。

以下は、先ほどの`getCoordinates`を拡張し、住所を検証して、座標を取得する。また、途中で、コンテキストで、デッドラインが過ぎてないかやキャンセルされていないかを検査している。

```go
func (l loc) getCoordinates(ctx context.Context, address string) (
	lat, lng float32, err error) {
	isValid := l.validateAddress(address)
	if !isValid {
		return 0, 0, errors.New("invalid address")
	}
	if ctx.Err() != nil {
		return 0, 0, err
	}
	return 0, 0, nil
}
```

ここで、`if ctx.Err() != nil`で返されエラーは`err`ですが、`err`には何も代入しておらず、ゼロ値である`nil`しか返さない。

また、`err`は名前付き戻り値によって初期化しているので、名前付き戻り値がなければ、コンパイルエラーとなる。

この解決方法は2つある。

1つ目は以下のように`err`に`ctx.Err()`を代入する。

```go
if err := ctx.Err(); err != nil {
    return 0, 0, err
}
```

ただし、これはerrがシャドーイングしているので注意する。

2つ目の方法は、空returnを使用する。

```go
if err = ctx.Err(); err != nil {
    return
}
```

これは、[空return](#空return)の一貫性を保つことに反するので、使ってはいけない。

# 参考文献

1. [100 Go Mistakes and How to Avoid Them](https://100go.co/ja/#43)
Rails5.1以前と以降のデータ型の違いによるマイグレーションエラーの解決方法

## はじめに
Rails6.1で`references`を使って既存のテーブルを参照する新しいテーブルを作成しようとした際、エラーに遭遇しました。

エラーの内容とその原因・解決方法をまとめます。

## エラーの概要
### やりたいこと
既存の`User`テーブルを参照して新たに`SocialLink`（SNSなどの外部サービスのリンクを保持する）テーブルを作成したい。

### 使用したマイグレーションファイル
```ruby
class CreateSocialLinks < ActiveRecord::Migration[6.1]
  def change
    create_table :social_links do |t|
      t.references  :user, null: false, foreign_key: true
      t.string      :type, null: false
      t.string      :url,  null: false

      t.timestamps
    end
  end
end
```

### rails db:migrate実行時に発生したエラー
```bash
Mysql2::Error: Referencing column 'user_id' and referenced column 'id' in foreign key constraint 'fk_rails_a95eea6600' are incompatible.
```

## エラーの原因
Railsのバージョンによる主キーや外部キーのデータ型の違いが原因でした。

- Rails5.1 より前:　主キーと外部キーは`integer`型
- Rails5.1 以降:　主キーと外部キーは`bigint`型

今回のケースは
- `User`テーブル：Rails 4で作成（`id`が`integer`型）
- `SocialLink`テーブル：Rails 6.1で作成（`user_id`が`bigint`型）

そのため、`User`テーブルの`id`カラムと`SocialLink`テーブルの`user_id`カラムのデータ型が不一致となりエラーが生じていました。

## 解決策
以下の2つの解決策があります。
1. `SocialLink`テーブルの`user_id`カラムを`integer`型に変換する
2. `User`テーブルの`id`カラムを`bigint`型に変更する

### 1. `SocialLink`テーブルの`user_id`カラムを`integer`型に変換する
`references`を使って外部キー制約をつける場合、以下のように`type: :integer`を書けばOKです。
```ruby
class CreateSocialLinks < ActiveRecord::Migration[6.1]
  def change
    create_table :social_links do |t|
      # type: :integer を追加
      t.references  :user, null: false, foreign_key: true, type: :integer
      t.string      :type, null: false
      t.string      :url,  null: false

      t.timestamps
    end
  end
end
```
もしくは、`references`を使用せず、`user_id`を`integer`型で定義し、`add_foreign_key`で外部キーを別途つけても問題ありません。
```ruby
class CreateSocialLinks < ActiveRecord::Migration[6.1]
  def change
    create_table :social_links do |t|
      # user_id カラムを追加
      t.integer  :user_id, null: false
      t.string   :type,    null: false
      t.string   :url,     null: false

      t.timestamps
    end
    # 外部キー制約を別途付与
    add_foreign_key :social_links, :users
  end
end
```

### 2. `User`テーブルの`id`カラムを`bigint`型に変更する
この場合、まず`change_column`で`User`テーブルの`id`カラムのデータ型を変更するマイグレーションファイルを実行します。
```ruby
class ChangeUsersId < ActiveRecord::Migration[6.1]
  def up
    # int から bigint 型へ変更
    change_column :users, :id, :bigint, auto_increment: true
  end

  def down
    # rollback時に bigint から int 型へ戻す
    change_column :users, :id, :int, auto_increment: true
  end
end
```
あとは今まで通り`references`を使って`SocialLink`テーブルを追加すればOKです。
```ruby
class CreateSocialLinks < ActiveRecord::Migration[6.1]
  def change
    create_table :social_links do |t|
      t.references  :user, null: false, foreign_key: true
      t.string      :type, null: false
      t.string      :url,  null: false

      t.timestamps
    end
  end
end
```

## まとめ
- Rails5.1から主キーや外部キーのデータ型が`integer`から`bigint`に変更された
- そのためRails5.1以前に作成したテーブルを5.1以降で参照しようとすると型不整合によるエラーが生じる

### 参考文献
- [Ruby on Rails 5.1 リリースノート
](https://railsguides.jp/v5.1/5_1_release_notes.html#active-record-%E4%B8%BB%E3%81%AA%E5%A4%89%E6%9B%B4%E7%82%B9)
- https://github.com/rails/rails/pull/26266
2024年下半期の学習計画

## はじめに
IT業界参入3年目のインフラエンジニアによる、2024年下半期の学習計画です。
計画倒れ防止のために、下半期の学習計画を投稿することにしました。

## 投稿者のレベル
学歴：文系の四大卒
職歴：非IT→SES(2年)→クラウドインテグレーター(1年目)
業務内容：クラウド環境の運用構築

文系出身なので計算問題は苦手です(´；ω；`)

## 所持資格

**2021年**
| 資格名 | 取得年月 | 
|:-----------|------------:|
| CCNA       | 2021/10        | 

**2022年**
| 資格名 | 取得年月 | 
|:-----------|------------:|
| ITパスポート     | 2022/09      |

**2023年**
| 資格名 | 取得年月 | 
|:-----------|------------:|
| AWS CLF       | 2023/01        |
| AWS SAA         | 2023/02          | 
| LPIC101       | 2023/06       | 
| LPIC102    | 2023/08     | 
| AWS DVA    | 2023/10     |

**2024年**
| 資格名 | 取得年月 | 
|:-----------|------------:|
| AWS SAP       | 2024/01        | 
| AWS SOA     | 2024/04      | 
| AWS DBS     | 2024/04      | 
| AWS SCS         | 2024/06          | 
| AWS MLS         | 2024/07          | 

2021年の10月にIT業界へ参入しました。
入社前に会社から「できればCCNAの勉強しといて～」と言われ、必死のパッチで2か月ほど勉強して(入社までに間に合わず)10月に取得したことが、IT資格取得のスタートです！

AWS資格は合計8つです。
廃止前にDASとPASを受験しそびれてしまい、悔やんでいます(TдT)

## 下半期の受験計画

| 資格名 | 取得年月 | 
|:-----------|------------:|
| AWS DEA       | 2024/07                | 
| 応用情報技術者試験    | 2024/10      | 
| AWS DOP     | 2024/11      | 
| AWS ANS         | 2024/12          | 

これまでとにかく業務に直結する資格を～と思い、インフラ関係のベンダー資格を受験してきました。
しかし、IT業界人であれば知っていて当然の用語等が理解できず、話についていけないこともしばしば。
そのため、一度ベンダー資格の優先順位を落として、応用情報技術者試験に挑戦することを決めました！


## 使用予定教材
- AWS DEA
[要点整理から攻略する『AWS認定 データ分析-専門知識』](https://amzn.asia/d/0bhnjgRP "要点整理")
Cloudtech　資格問題集 
[Udemy問題集](https://www.udemy.com/course/dea-c01aws/learn/quiz/6225886 "Udemy")

- AWS DOP
(何か参考書を読む)
Cloudtech　問題集
- AWS ANS
[AWS認定 高度なネットワーキングー専門知識(ANS-C01)完全対応テキスト](https://amzn.asia/d/0inGZVJv "テキスト")
Cloudtech　問題集
CloudLicense 問題集
Udemy　問題集

- 応用情報技術者試験
過去問道場　
[ニュースペックテキスト 応用情報技術者](https://amzn.asia/d/0bhnjgRP "https://amzn.asia/d/017Lsl3R")　
[応用情報技術者　午後問題の重点対策](https://amzn.asia/d/0bhnjgRP "https://amzn.asia/d/09Gymnc0")　

DEA試験が終わり次第、応用情報技術者試験の勉強に全力を注ぐつもりです。
時間配分は朝に2時間ほど過去問道場をやって、夜の1~2時間でテキストを読む形になるのかなと思っています。
とか言いつつ色々と試行錯誤する形になるかと思います。いい勉強方法教えてください。
参考書は色々買ってみた中で、一番記載内容がシンプルなものを選びました。

AWS資格は8月に2つ増えるので、それらも含めた残り5つを来年の3月までに取得したいです。
ANSは今年中に受かれば大天才！くらいの気持ちでいます。

資格とは別ですが、余裕があればTerraformとAnsibleの勉強時間も確保したいです。

## まとめ
AWS全冠と応用情報技術者試験の合格に向けて精進いたします！
進捗が悪いぞ！と思った際には鞭打ちしてください！
よろしくお願いします。
【MariaDB（MySQL）】User名が空のユーザーを削除したい

## はじめに

MariaDBをインストールして初期設定作業をしていたら、何をどう誤ったのかわかりませんが、User名が空のユーザーが作成されてしまったので、削除します。

```sql
> select user,host,password from mysql.user;
+-------------+----------------+-------------------------------------------+
| User        | Host           | Password                                  |
+-------------+----------------+------------------------------------------ |
|             | localhost      |                                           |
（後略）
```


## 環境

- Rocky Linux 9.4
- MariaDB[^1] 11.4

## SQL

以下で上手くいきました。

```sql
drop user if exists ``@localhost;
```

### 失敗例

ちなみに、以下ではエラーになりました。。

```sql
> drop user if exists @localhost;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '@localhost' at line 1
```

## おわりに

単に「ユーザーを削除する」例はたくさん出てきたのですが、User名が空の場合の記事は見かけなかったので、一応記録しておきます。

## 参考

https://www.javadrive.jp/mariadb/user/index6.html

[^1]:試してないですが、おそらくMySQLでも上手くいくと思います。
数学2次試験 論文対策？2023 山梨大学推薦。ChatGPT先生へ

・出題者もChatGPT先生に聞いておられますか？
・**私の論文も採点してもらえるかも。それはそれで、ちょっと恐ろしい。**

# 例1.(過去問より)数学の内容でおもしろいと思ったもの，あまりおもしろいとは思えなかったものと比較
(再)回答が昨日と違う気がする。

User(以下私が改行しています。)
```
【１】　これまでにあなたが学習してきた数学の内容の中で，おもしろいと思ったも
のを具体的に示し，あまりおもしろいとは思えなかったものと比較しながら，その
おもしろさについて説明してください．
```

＞2023　山梨大学　推薦教育学部追試験MathJax【１】
＞https://mathexamtest.web.fc2.com/2023/202310401/2023104010500mj.html

ChatGPT
数学の中で特におもしろいと思ったのは、複素数とその幾何学的応用です。具体的には、複素数平面上での回転や拡大縮小の操作を、複素数の乗算や除算で表現できる点です。例えば、...
```
1000文字で
```
(省略)
```
何文字でしたか
```

この文章は1099文字です。1000文字に収めるために、少し削ってみます。
(省略)
これで1000文字以内に収まります。 ​​
```
300字以内で
```
(省略)

```
5字以内で
```

GPT-4o の制限に達しました。





# 例2　(過去問より)数学では，一見すると違うものを同じように見たり，...
User(以下私が改行しています。)
```
【１】　数学では，一見すると違うものを同じように見たり，異なる内容のものを
結びつけたりして考えることがあります．これまで学んだ数学の中で，そのような
具体例を挙げ，その良さについて述べてください．
```
＞2023　山梨大学　推薦教育学部本試験MathJax【１】
＞https://mathexamtest.web.fc2.com/2023/202310401/2023104010400mj.html

回答省略


# 過去問

https://qiita.com/mrrclb48z/items/89e3d0b8097a1c916344
Git で無限に rebase が終わらない時

`git rebase` をしていたら謎現象に当たったのでメモ書き

以下のようなコミット履歴があったとします。

```
aaaaaa: A
bbbbbb: B
cccccc: C
```

`git rebase -i aaaaaa^` で `aaaaaa` を `edit` にして保存します。その後 `aaaaaa` で作業を反映し `git rebase --continue` をすると当然 TODO は次の状態になります。

```
bbbbbb: B
cccccc: C
```

B, C は `pick` なので通常なら何事もなく commit されて終了なはずですが、なぜか `bbbbbb` がすでに反映されている状態で更に追加しようとしました (なぜ?)

```
error: could not lock '.git/MERGE_MSG': File exists
error: could not apply bbbbbb... B
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
hint: Could not execute the todo command
hint:
hint:     pick bbbbbb... B
hint:
hint: It has been rescheduled; To edit the command before continuing, please
hint: edit the todo list first:
hint:
hint:     git rebase --edit-todo
hint:     git rebase --continue
```

すでに反映されているので当然ファイル重複にはなっているのでこのコミットは必要ありません。なぜか `git rebase --skip` は使えなかったので `git rebase --edit-todo` で TODO を開き `bbbbbb` の行を削除します。`cccccc` でも同様の現象が起きたため同じ対処をします。

これにより意図通りに `aaaaaa` のみを編集できました。
React Testing Library 基本コマンド集

React Testing Libraryを使用する際の基本的な操作について、具体的な例と共にまとめていきます。

https://testing-library.com/docs/


## getByText

指定されたテキストコンテンツを持つ要素を取得します。任意の要素をテキストコンテンツによって見つけるために使用されます。


```jsx
render(<button>Submit</button>);

const button = screen.getByText("Submit");
expect(button).toBeInTheDocument();
```

## getByLabelText

指定されたラベルテキストに対応する要素（通常はフォーム要素）を取得します。

```jsx
render(
  <div>
    <label htmlFor="username">Username</label>
    <input id="username" />
  </div>
);

const input = screen.getByLabelText("Username");
expect(input).toBeInTheDocument();
```

## getByRole

指定されたロール（役割）を持つ要素を取得します。アクセシビリティ属性に基づいて要素を検索するために使用されます。


```jsx
render(<button>Submit</button>);

const button = screen.getByRole("button", { name: "Submit" });
expect(button).toBeInTheDocument();
```

## getByTestId

指定された `data-testid` 属性を持つ要素を取得します。特定のテスト対象要素を簡単に見つけるために使用されます。


```jsx
render(<button data-testid="submit-button">Submit</button>);

const button = screen.getByTestId("submit-button");
expect(button).toBeInTheDocument();
```
SA-IS法において各接尾辞のS-type, L-typeを線形時間で決められることの説明

SA-IS法が何か、とかそういう話は書かないです（詳しい記事が無限にあるので）。あくまで、S-TypeとL-Typeを線形時間で決める方法についてだけ書きます。

# 結論だけを簡潔に
## 前提
SA-IS法において、最初のステップとして長さ$N$の文字列$S$の全ての接尾辞を「1文字目からN+1文字目」[^1]、「2文字目からN+1文字目」……、「N文字目からN+1文字目」、「N+1文字目」と並べたときに、それぞれの接尾辞に対して S-Type か L-Typeかを判定するものがある[^2]。
普通に前から決めていくと、長さ$N+1$の文字列と長さ$N$の文字列の辞書順の比較、長さ$N$の文字列と長さ$N-1$の文字列の辞書順の比較……となり、トータルで$O(N^2)$の計算量がかかる。ところが実は、$S$を後ろから走査することにより、S-TypeかL-Typeかを全体で$O(N)$で判定できる。
…ということが、あちこちのサイトで説明されているが、その理由を詳細に書いてくれているところが見つからなかった。

# 実装の結論
$S$の$i$文字目の文字を$s_i$、$S$の$i$文字目から末尾までの接尾辞を$S_{i}$と表記するとき、$S_{i}$がS-TypeかL-Typeかは次の法則に従って決める。但し、後ろから走査するという前提があるので、$S_{i+1}$のTypeは既に決まっているとする。また、最後の接尾辞、つまり後ろから走査するとき一番最初に見ることとなる接尾辞のタイプはS-Typeとする。

* $s_i > s_{i+1}$のときは L-Type
* $s_i < s_{i+1}$のときは S-Type
* $s_i = s_{i+1}$のときは、$S_{i+1}$と同じType

$s_i \neq s_{i+1}$の場合は自明[^3]で、等しい場合について以下説明する。

辞書順の定義から、1文字目が等しければ、2文字目以降、2文字目の等しければ3文字目以降、と再帰的に辞書順を比較することになる。
そして、実はこの2文字目以降、3文字目以降の辞書順の比較は、 $S_{i+1}, S_{i+2}$のTypeを決めるときに行った比較そのものである。これは接尾辞配列の作り方から明らか。つまり、接尾辞の先頭$k$文字が等しくて$k+1$文字目で初めて異なるときには、$k+1$文字目の辞書順の比較結果がそのまま全体の比較結果になるわけだが、先頭の文字が同じなら直前のTypeを引き継ぐというルールによって、後ろから見ていったときにはじめて $k+1$ 文字目にあたる個所を比較したときの結果が、ずっと引き継がれていくということになる。
上記の理由から、このような実装をとることで、各接尾辞がS-TypeなのかL-Typeなのかは、トータル $O(N)$で決めることができる。

# 参考文献
* https://gist.github.com/tjkendev/99d7330fe5642004b68268b31ba38ad4
 このソースコードのコメント行を見て、ようやくTypeの決め方を理解した


# 注釈
[^1]: 接尾辞配列を考えるときは、$S$の$N+1$文字目に番兵として$S$に出現するどんな文字よりも辞書順が小さい文字を置くため、長さ$N$の文字列なのに$N+1$文字目という表現が出てくる。
[^2]: 本文のように接尾辞を並べたときに $i$番目の接尾辞を $S_i$と置いたとき、接尾辞$S_i$がS-Typeであることの定義は、辞書順で$S_i < S_{i+1}$ が成り立つことで、 L-Typeの定義は 辞書順で$S_i > S_{i+1}$ が成り立つことである。但し、番兵1文字からなる最後の接尾辞については次の接尾辞が存在しない。これについては常にS-Typeとする。
[^3]: 辞書順の定義そのものなので。例えば a***** と b***** (*は任意の文字列が適当に入ると思ってください) なら 1文字目を見るだけで a***** の方が b***** よりも辞書順で小さい。