OmniAICreator/Qiita-1.07M huggingface dataset:
サーバー移行後、GitLab接続が遅くなってwarningが出たときの対処法

先に結論を述べると`git config --global credential.https://(new hostname).provider gitlab`を実行して解決した。
当初の原因の考察では、サーバー側に設定漏れがあるのではないかと考えていた。
しかし実際は、Gitクライアント側の設定追加が必要だった。
# 事象
オンプレミス上でホスティングしているGitLabを、別の物理サーバーへ移行した。
クライアント側では、リモートのURLを新サーバーに変更する作業のみ行った。

この状態でリモートリポジトリに接続可能だったため、移行は成功したと思いきや
プルやプッシュの際、サーバーに接続するまでに数秒かかり(遅くなり)、下記の警告が出力されるようになった。
```powershell
warning: auto-detection of host provider took too long (>2000ms)
warning: see https://aka.ms/gcm/autodetect for more information.
warning: auto-detection of host provider took too long (>2000ms)
warning: see https://aka.ms/gcm/autodetect for more information.
```

# 調査
前出のwarningで[見ろと言われているページ](https://github.com/git-ecosystem/git-credential-manager/blob/main/docs/autodetect.md)を見に行くと
GCM(git credencial manager)のドキュメントに行き着いた。

GCMとは、gitの資格情報を管理するツールである。
GCMが働くことで、Gitクライアントからサーバへアクセス(pull,pushなど)する時に
username・password・MFAなどの認証を省略できている。
ドキュメントにはGCMのホストプロバイダを自動検出する機能について書かれていた。

ページを読み進めると[最後のほう](https://github.com/git-ecosystem/git-credential-manager/blob/main/docs/autodetect.md#manual-configuration)に、問題が起きている場合は
`git config --global`で手動設定するように書かれていた。
ページをひととおり読んで、いまの`git config`が間違っていそうなことが分かった。<br>現在の設定がどうなっているのかを確認してみた。
```console
$ git config --global --list
...
credential.https://(old hostname).provider=generic
...
```
現在のconfigを確認したところ、新しいホストに対する`provider`の設定が無かった。
ドキュメントにも書いてあったとおり`credential.https://(new hostname).provider`を設定すればよさそうだと判断した。

# 解決方法
`git config`で設定する値は`generic`でもよさそうだが、[ドキュメント](https://github.com/git-ecosystem/git-credential-manager/blob/main/docs/autodetect.md#manual-configuration)に倣って`gitlab`を指定した。
```console
$ git config --global credential.https://(new hostname).provider gitlab
```
この状態でプルを試して、冒頭のwarningが出現しないこと、それに伴いプルに時間がかからなくなったことを確認し、問題解決した。


また、調査中にGCMのdocs内に[GitLab supportのページ](https://github.com/git-ecosystem/git-credential-manager/blob/main/docs/gitlab.md)を発見した。
このページに載っているコマンドで、移行前のホストのcredencialに関する設定を削除した。
```console
$ git config --global --unset-all credential.https://(old hostname)
```
このページでは「Using on another instance」として別のインスタンスを使う時の手順が丁寧に説明されていた。
移行の際は、最初からこのページを参照することをお勧めする。
応用情報技術試験合格のために行ったこと

# はじめに
私が行った応用情報技術者試験についての勉強内容の共有です。
応用情報技術者試験を今後受ける方の参考になれば幸いです。

### 学習期間
- 7月上旬(試験申し込み)～10/8(テスト日)
### 学習時間
200時間弱くらいかと思います。主に通勤の電車（30分ほど)と平日の夜、土日の時間を利用していました。土日は大体１日3-4時間を目安にしていました。

### 午前の対策
- [情報処理教科書 応用情報技術者 テキスト＆問題集](https://www.amazon.co.jp/%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E6%95%99%E7%A7%91%E6%9B%B8-%E5%BF%9C%E7%94%A8%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85-%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%EF%BC%86%E5%95%8F%E9%A1%8C%E9%9B%86-2024%E5%B9%B4%E7%89%88-%E6%97%A5%E9%AB%98/dp/4798183520)
-  [応用情報技術者試験ドットコム](https://www.ap-siken.com/apkakomon.php)

午前問題の演習はほぼ過去問道場に頼っていました。
春季・冬季あわせて過去５年分やれば充分だと思います。
近年は問題の使いまわしが減り、時事問題が増えてきているようです。直近の年度の試験問題は直接再出題されることはないと思いますが傾向をつかむためにトライしておくことをおすすめします。

### 午後の対策
- [情報処理教科書 出るとこだけ！応用情報技術者［午後］ 単行本（ソフトカバー）](https://www.amazon.co.jp/%E6%83%85%E5%A0%B1%E5%87%A6%E7%90%86%E6%95%99%E7%A7%91%E6%9B%B8-%E5%87%BA%E3%82%8B%E3%81%A8%E3%81%93%E3%81%A0%E3%81%91%EF%BC%81%E5%BF%9C%E7%94%A8%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85%EF%BC%BB%E5%8D%88%E5%BE%8C%EF%BC%BD-%E6%A9%8B%E6%9C%AC-%E7%A5%90%E5%8F%B2/dp/4798156507/ref=sr_1_5?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=18QYZWM3VU9O5&keywords=%E5%BF%9C%E7%94%A8%E6%83%85%E5%A0%B1+%E5%8D%88%E5%BE%8C%E3%81%8B%E3%82%89&qid=1704536436&s=books&sprefix=%E5%BF%9C%E7%94%A8%E6%83%85%E5%A0%B1+%E5%8D%88%E5%BE%8C%E3%81%8B%E3%82%89%2Cstripbooks%2C174&sr=1-5)
-  [応用情報技術者試験ドットコム](https://www.ap-siken.com/apkakomon.php)

こちらは先に本を読み、読んだ分野ごとに過去問道場で演習していました。
午後は過去問道場だけではなく本を読んで体系的に理解することが重要かと思いますので半々くらいの比重で学習していました。

## 試験の戦略について考える
1	情報セキュリティ	必須	20点
2	ストラテジ（経営戦略、情報戦略、コンサルティング、情報戦略）	選択	20点
3	プログラミング	選択	20点
4	システムアーキテクチャ	選択	20点
5	ネットワーク	選択	20点
6	データベース	選択	20点
7	組込みシステム開発	選択	20点
8	情報システム開発	選択	20点
9	プロジェクトマネジメント	選択	20点
10	サービスマネジメント／ITサービスマネジメント	選択	20点
11	システム監査

私の場合は「情報セキュリティ／データベース／プロジェクトマネジメント／サービスマネジメント／システム監査」を選択していました。情報セキュリティは必須なので最初に手を付けることをお勧めします。残りの科目については自分の専門性や出題当日の内容をみて判断していただくしかないと思います。
ちなみに2023年秋季の場合はデータベースが難易度が低く選んでいる方が多かったです。
データベース（MySQL）を学んで大事だなと思ったこと

## はじめに
こんにちは、最近データベースを学んだ人です。今回は直近2週間でデータベースを学んでいて大事だなと思ったことを発信してきます。

## MySQLで大事なことはテーブル設計！！
はい。結局はここが一番大事になるんだなと思います。例えばテーブル設計で必要なエンティティを見逃していたら、それ以降の作成の段階でとってもめんどくさくなったからです。自分はそれを解決するためにテーブル作成のクエリを逐一メモしながら進めていたので最初から進めるのもそこまで時間はかからなかったですが、それでもめっちゃめんどくさかったので、これからデータベースを学ぶ人はテーブル設計だけはちゃんとできるようにしたほうがいいなと思いました。逆にそれ以外は調べれば答えが出てくるものが多いなと思うので、テーブル設計をちゃんとやっておけばそこまでデータベースは怖くないと思います！

## サンプルレコードについて
データベースを学んでいて一番悩んだところがサンプルレコードを生成するときです。書きたいクエリに合わせてサンプルデータを入れていく作業がすごく時間がかかるし難しい。ChatGPTがある時代にエンジニアを目指してよかったなと思う出来事でした。

## さいごに
データベースを学んで思ったことの総括はちゃんと一から順番にやっていけばそこまで難しくない分野だなと思いました。一番の難所テーブル設計をやってさえしまえばあとのやることは、ある程度決まっているので、これからデータベースを学ぶ人はあまり難しく考えすぎず、丁寧に順番にやっていってほしいです！ここまで記事を見てくれてありがとうございました。
アクセシビリティを意識した実装の意義について確認する

### この記事で分かること
- 身体に関わる障害を持つ方の雇用率
- それをデスクワークで改善させることにおいてはアクセシビリティは有効

# 1. 背景
アクセシビティにも色々定義がありますが、身体に関わる障害を持つ方のための実装をする意義を確認したいと思った為です。

# 2. 各身体に関わる障害と有効なアクセシビリティ

https://developer.mozilla.org/ja/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility

| 身体に関わる障害のカテゴリ | 有効なアクセシビリティ |
| ---- | ---- |
| 視覚 | スクリーンリーダーや拡大/ズームを使用してテキストにアクセス |
| 運動機能 | キーボード（または他のマウス以外の機能）を使用してウェブサイトの機能をアクティブ化 |
|聴覚|音声や動画のコンテンツのキャプション/字幕またはその他の代替テキストに依存

# 3. 令和4年度 国内雇用 身体に関わる障害を持つ方の人数とその割合
令和５年６月１日時点のデータです。

357,767.5人です。
実雇用率は1.31%です。

https://www.zenjukyo.or.jp/news/r05_koyou_joukyou_kekka.html#:~:text=%E4%BB%A4%E5%92%8C%EF%BC%95%E5%B9%B4%EF%BC%91%EF%BC%92,%E3%81%97%E3%81%9F%E3%81%A8%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%81%99%E3%80%82

ちなみに19年連続で障害を持つ方全体の雇用人数は過去最高を更新しています。

# 4. 令和4年度 就職件数 身体に関わる障害を持つ方のカテゴリ別の内訳

https://www.mhlw.go.jp/stf/newpage_33335.html

| 身体に関わる障害のカテゴリ | 身体に関わる障害を持つ方全体に占める割合 |
| ---- | ---- |
| 視覚 | 6.8% |
| 聴覚 | 14.4% |
|その他運動機能*| 78.8%

*肢体不自由+内部障害+その他

# 5. 不動産業界における障害を持つ方に向けた求人例
弊社は不動産業界向けにプロダクトを開発してますので不動産業界に焦点を当てます。

recommos

https://www.recommos.jp/postings/real-estate

indeed

https://jp.indeed.com/q-%E9%9A%9C%E5%AE%B3%E8%80%85%E6%8E%A1%E7%94%A8-%E4%B8%8D%E5%8B%95%E7%94%A3-%E6%B1%82%E4%BA%BA.html?vjk=89ffa8a10358177d

# 6. 最後に
- アクセシビリティを意識して実装することは身体に関わる障害を持つ方にとって以下のメリットがあると確認できました。
    - デスクワークでできる仕事の幅を広げられる。
    - 止むを得ず解雇になる機会を減らすことができる。
- 最初に対応するべきアクセシビリティは、ウェブサイトの機能をキーボード（または他のマウス以外の機能）によってアクティブ化させられるようにすることなのかなと思いました。
- アクセシビリティについてもっと勉強したいと改めて思いました。

# 7. 参考
- [視覚障害者へ企業が配慮すべきこと -雇用状況、職種、仕事内容-](https://persol-diverse.co.jp/lab/fundamental/work/work002/)
- [MarkdownでTable(表テーブル)を書く](https://help.notepm.jp/hc/ja/articles/17267262392473-Markdown%E3%81%A7Table-%E8%A1%A8%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB-%E3%82%92%E6%9B%B8%E3%81%8F)
- [令和４年度　ハローワークを通じた障害者の職業紹介状況などの取りまとめを公表します](https://www.mhlw.go.jp/stf/newpage_33335.html)
- [令和4年「障害者雇用状況の集計結果」から見る傾向と対策 令和5年度からの「障害者雇用率」の引き上げはどうなる？ | 人事のプロを支援するHRプロ](https://www.hrpro.co.jp/series_detail.php?t_no=3053#:~:text=%E3%81%AB%E5%BC%95%E3%81%8D%E4%B8%8A%E3%81%92%E3%81%B8-,%E4%BB%A4%E5%92%8C4%E5%B9%B4%E3%81%AE%E9%9A%9C%E5%AE%B3%E8%80%85%E9%9B%87%E7%94%A8%E7%8E%87%E3%81%AF,%E3%81%BE%E3%81%97%E3%81%9F%EF%BC%88%E5%9B%B3%E8%A1%A81%EF%BC%89%E3%80%82)
- [【社労士監修】法定雇用率とは障害者の雇用率。計算式や罰則、企業の対応は？ | d's JOURNAL（dsj）- 理想の人事へ、ショートカット](https://www.dodadsj.com/content/191209_statutory-employment-rate/#:~:text=%E5%AE%9F%E9%9B%87%E7%94%A8%E7%8E%87%E3%81%AF%E3%80%81%E5%AE%9F%E9%9A%9B,%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82&text=%E2%80%BB%E3%80%8C%E5%B8%B8%E7%94%A8%E9%9B%87%E7%94%A8%E3%81%A7%E5%83%8D%E3%81%84%E3%81%A6%E3%81%84%E3%82%8B%E9%9A%9C%E5%AE%B3%E8%80%85%E6%95%B0,%E8%80%85%E3%80%8D%E3%81%8C%E5%90%AB%E3%81%BE%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82)
お名前.comのDDNSクライアントをPythonで実装した【Linux対応】

## 前置き

お名前.comではダイナミックDNSクライアントが提供されていますが，サポートOSがWindowsのみとなっています．サーバ機でUbuntuを使用しているとDDNSを別のWindows機に頼ることになり，運用が面倒になってしまいます．

お名前.comのDDNSではテキストベースのプロトコルが使われているらしく，再現した実装が多々見つかりました．ただし，通信の実装が様々で，公式クライアントの通信を調べて再実装する必要を感じたため，新たに作成しました．

:::note warn
非公式な実装ですので，使用は自己責任でお願いします．
:::

## 要件

- Python 3.7 以上

## 導入方法

Ubuntuなど，systemdを採用するLinuxディストリビューションでの導入方法です．

1. リポジトリをクローンする

   ```bash
   git clone https://github.com/y-otn/onamae-ddns-client.git
   cd onamae-ddns-client
   ```

2. `onamae_ddns_client.py` の以下の項目を書き換える（8-12行目）
   - `INTERVAL`: 更新間隔（秒）
   - `USERID`: お名前ID
   - `PASSWORD`: パスワード
   - `HOSTNAME`: ホスト名（任意）
   - `DOMNAME`: ドメイン名

   :::note warn
   公式クライアントの更新間隔の初期値は1800秒です．
   公式の最低値，300秒未満では使用しないでください．
   :::

   :::note info
   日本語ドメインにも対応しています．
   :::

3. スクリプトを配置し，適切な権限を設定する

   ```bash
   sudo mv onamae_ddns_client.py /usr/local/bin/
   sudo chown root:root /usr/local/bin/onamae_ddns_client.py
   sudo chmod 600 /usr/local/bin/onamae_ddns_client.py
   ```

4. 自動起動するサービスとして設定，起動する

   ```bash
   sudo cp onamae_ddns_client.service /etc/systemd/system/
   sudo systemctl daemon-reload
   sudo systemctl enable --now onamae_ddns_client.service
   ```

   :::note warn
   必要に応じて `python3` のパスを修正してください．
   :::

5. サービスの状態を確認する

   ```bash
   sudo systemctl status onamae_ddns_client.service
   ```

   次のような出力があれば，正常に動作しています．

   - DNS records updated successfully. IPv4: \*\*\*.\*\*\*.\*\*\*.\*\*\*
   - No update necessary, DNS records are current.

   :::note info
   次のコマンドで長期的なログを確認できます．

   ```bash
   sudo journalctl -u onamae_ddns_client.service
   ```

   :::

:::note alert
`onamae_ddns_client.py` は常駐して動作する設計です．
cronなどで繰り返し実行する場合は適宜修正してください．
そのまま使用すると多重起動し，過剰なアクセスを生じます．
:::

## 参考文献

- [LinuxやMacで お名前.com ダイナミックDNS の IPアドレスを更新する #dns - Qiita](https://qiita.com/ats124/items/59ec0f444d00bbcea27d)
- [お名前.comのDDNSをスクリプトから行う | メモ帳](https://blog.sky-net.pw/post/%E3%81%8A%E5%90%8D%E5%89%8D.com%E3%81%AEddns%E3%82%92%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%81%8B%E3%82%89%E8%A1%8C%E3%81%86/)
- [お名前ドットコムのDDNSのIPをLinuxから更新する、onamae_ddns - THUNの遊戯室](https://www.thun-techblog.com/index.php/blog/onamae-ddns-linux/)
ルーティングを間違えるとコントローラにはアクセスできない

## はじめに
Laravelでテストコードを実装していた時、ルーティングを間違えたせいでコントローラにアクセスできず、しばらくブロックされていました。

基本的な所ではありますが、自戒も込めて対応法をまとめておきます。

## 環境
Laravel 9.52.16

## 問題
* 問題となったテストコード

```php: SalesOrdersControllerTest.php（一部略）
public function test_sales_destroy(): void
    {
        // テスト用のユーザを作成
        $user = User::factory()->create();

        $formData = [
            'category_id' => 1, 
            // 以下略
        ];

        // フォームデータを保存
        $response = $this->actingAs($user)->post('/my/sales/store', $formData);

        $sales_order = $user->sales_orders()->first();

        $response = $this->actingAs($user)->delete('/my/sales/destroy/' . $sales_order->id);

        $response->assertStatus(302);
        $this->assertDatabaseMissing('sales_orders', [
            'user_id' => $user->id,
        ]);
    }
```

* エラーの内容
```php
root:/var/www/html/niches # php artisan test --filter test_sales_destroy

   FAIL  Tests\Feature\SalesOrdersControllerTest
  ⨯ sales destroy

  ---

  Tests\Feature\SalesOrdersControllerTest > sales destroy
  Expected response status code [302] but received 404.
  Failed asserting that 302 is identical to 404.
```

「Httpステータスコードはお求めの302リダイレクトじゃなくて、404NotFoundを返してるぞ」と仰っています。

参考までに、web.php内のルーティングは次のようになっています。

```php: web.php（一部略）
Route::delete('sales/destroy/{saleId}', [SalesOrdersController::class, 'destroy'])->name('sales-destroy');
```


## 解決法
* テスト内のdeleteメソッドが存在しないルーティングにアクセスしようとしていました

```php: SalesOrdersControllerTest.php（失敗）
$response = $this->actingAs($user)->delete('/my/sales/destroy/' . $sales_order->id);
```

destroyアクションへのルーティングはweb.php内で「sales/destroy/{saleId}」となっているので…

```php: SalesOrdersControllerTest.php（解決）
$response = $this->actingAs($user)->delete('/sales/destroy/' . $sales_order->id);
```

こちらが正しいですね！


## まとめ
ググってみた感じ、404エラーの原因のほとんどがルーティングに関係してそうです。

今後404エラーが出た際には、ルーティングを正しく書いているかどうか、という所から確認したいと思います。
NetworkX入門 (3)

# NetworkXのグラフに矢印を付ける

矢印が付いていないグラフを無向グラフ、矢印が付いているグラフを有向グラフと言う。
グラフ理論とかネットワーク理論とかは難しすぎてわからないので、お詳しい方に教えていただきたいのだけれど、この無向・有向の定義は間違っていないはず。

NetworkXでの実装は、とても簡単。

```Python
import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph()
G.add_node(1)
G.add_edge(1, 2)

nx.draw_networkx(G, node_color='lightblue', edge_color='dimgray')
plt.savefig('file03.png')
```

４行目でこれまでは`G = nx.Graph()` だったところを、**G = nx.DiGraph()** にするだけだ。
これで有向グラフになる。ちなみに、DiGraphはDirected Graphのこと。

![file03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78475/43645e75-508e-04cd-73f0-2e87e7ba5514.png)
リモートデスクトップの資格情報を複数保存するためのhostsファイルの活用

RDPの資格情報は基本的に1つの接続先に対して1つの資格情報しか保存できない．
サーバー等，2つ以上の資格情報を使い分けたいケースでも，マシン名で登録するものとIP直打ちで登録するもの（ローカルホストであればさらに加えてlocalhost，127.0.0.1も使える）で分けることで大抵カバーできるが，ポートフォワードを併用しようとすると数が足りなくなってくる．

筆者は自宅サーバー上から複数個所（以下では拠点A，拠点Bと呼ぶ）にSSHポートフォワードを刺しているので，手元の端末に自宅サーバー自体（192.168.0.100），拠点Aのマシン（192.168.0.100:13389），拠点Bのマシン（192.168.0.100:23389)の資格情報をそれぞれ保存しようと思うと数が足りない．

これを解決するには，手元端末のhostsファイルを編集するのが手っ取り早い．
件のファイルは
`C:\windows\system32\drivers\etc\hosts`
にあり，これを管理者権限のメモ帳か何かで開く．

ここでファイルの末尾に
`192.168.0.100 hoge huga`
と追記する（区切りは半角スペース）と，
例えば`hoge:13389`に接続しようとしたとき，勝手に`192.168.0.100:13389`に読み替えてくれる．

その上で，RDPクライアント上では`hoge:13389`に拠点Aのマシンの資格情報，`huga:23389`に拠点Bのマシンの資格情報といったように別の資格情報を保存できるようになる．
＊＊＊Toolkit の最新バージョンはどれか【UWP/WinUI/Maui】

## 新しい （Windows）

https://github.com/CommunityToolkit/Windows

- CommunityToolkit.Uwp.*
- CommunityToolkit.WinUI.*

nugetで検索してもDL数が少ないためか下の方に出てくるかもしれません。 以下の特徴を持つパッケージが該当します。

- 作成者 Microsoft.Toolkit
- v8.0.x 以上
- 青いアイコン

## 新しい（.Net）

https://github.com/CommunityToolkit/dotnet

- CommunityToolkit.Common
- CommunityToolkit.Mvvm
- CommunityToolkit.Diagnostics
- CommunityToolkit.HighPerformance

プラットフォーム非依存な .Net 環境で共通して利用できる機能は CommunityToolkit 直下の名前空間に配置されています。nugetからは以下の特徴を含むパッケージを探してみてください。

- アイコンが紫色
- v8.2.x 以上
- 作成者 Microsoft 

> なお、CommunityToolkit.Maui は MAUI というクロスプラットフォームアプリ開発環境向けのため MAUIアプリの開発以外では利用しません。アイコンが紫色のため .Net系のCommunityToolkitパッケージと混同しないようご注意を。

## 古い

- Windows.Toolkit.*
- Microsoft.Toolkit.*

動作自体は安定しているため使用に問題なさそうですが、v7.1.3 で止まっているためサンプルアプリ（Windows Community Toolkit Gallary）と比べてみていくつか使えない機能、古いデザインのコントロールが含まれます。

## その他：MAUI 

https://github.com/CommunityToolkit/Maui

CommunityToolkit.Mauiは現状では複数バージョンは存在しません。
値をPOSTされた時のみ処理を行う PHP

## はじめに
値を受け取った時のみ処理を行うコードです、POSTのみに限りませんが備忘録として置いておきます。
POSTされた値は$_POSTに格納されています。

## 使ってみる
post.phpとFunc.phpがあります。
func.phpはPost.phpから送られたmessageをテキストに追加していきます。
```php
//post.php

<form action="result.php" method="post"> 
  <input type='text' name='message'>
  <button>Post</button>
</form>
```
```php
//func.php

$message = filter_input(INPUT_POST, 'message');
$message = $message ?? '値が空です';

$fp = fopen('messages.txt', 'a');
fwrite($fp, $message . "\n"); 
fclose($fp);
```
このコードだと手入力でlocalhost:8080/Func.phpとすると「値が空です」とテキストファイルに追記されてしまいます。
なので、$_SEVER関数を使いpostメソッドで送信された時のみテキストファイルに追記するようにします

```php
func.php

$message = trim(filter_input(INPUT_POST, 'message'));
$message = $message !== '' ? $message : '...';
    
if($_SERVER['REQUEST_METHOD'] === 'POST'){
    $filename = '../app/messages.txt';
    $fp = fopen($filename, 'a');
    fwrite($fp, $message . "\n"); 
    fclose($fp);
    }
```
これでpostだった時のみテキストファイルに追記されるようになりました。

## おわりに
便利ですね。
qiita記事をGithubリポジトリでMarkdownファイルで管理する

## 目的
qiitaの記事が増えていくにつれて、記事自体の内容を効率よく整理したり、
将来的にはqiitaに限らず投稿内容をファイルとしてGithubで管理します。

## 前提
下記のサイトでは、Githubから自動的にqiitaへの投稿を行うことは今回触れないので、Githubからの自動投稿に関する記事はこちらを参照頂ければと思います。

【設定簡単】GitHub Actions を使ってリポジトリ上の技術記事を Qiita に自動で投稿しよう

https://zenn.dev/noraworld/articles/github-to-qiita-by-github-actions

※注意点として、Github Actionsは、利用上限に達した場合は課金対象となります。

この記事では、qiitaで投稿をした投稿内容をmdファイルとしてエクスポートし、githubにアップロードするというのが内容となります。


## 内容

### qiita APIの実行
下記のURLで、アクセストークンを新規作成をします。
* アクセストークンの説明は、適当な文字を入れます。
* 「発行する」を選択します。

https://qiita.com/settings/tokens/new
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551020/aecfcf99-3322-46c9-e393-5ea9fd3045d4.png)

作成後、アクセストークンの値が表示されますので、メモします。
**（アクセストークンの値は一度しか表示されないので、ご注意ください）**

下記のcurlを実行すると、ファイルをエクスポートできます。

```
curl -OH 'Authorization: Bearer 【メモしたアクセストークン】' 'https://qiita.com/api/v2/authenticated_user/items?page=numbers&per_page=20' --insecure
※numbersは数字に変更してください。
```
bashが使える環境であれば実行可能です。
（※コマンドプロンプトやPowershellでは実行できませんでした…Windows端末を利用する場合はGit bashを利用すると可能）

page=numbers&per_page=20（※numbersは数字に変更が必要で、qiita投稿数によって変わるかと思います。）
というファイルが作成されるので、下記の処置をすることですべての記事のURLを一覧できます。
* 「,」⇒「\n」で正規表現置換後、
* 「https://qiita.com/【ユーザ名】/items/ 」でgrep検索

### qiita記事のエクスポート
下記のように、mdファイルとしてエクスポートします。

（エクスポートするコマンドはExcelを使って、下記のようにまとめておくといいと思います。）
```
curl -O https://qiita.com/himitsuuser/items/hogeeeeeeee1.md --ssl-no-revoke
curl -O https://qiita.com/himitsuuser/items/hogeeeeeeee2.md --ssl-no-revoke
...
curl -O https://qiita.com/himitsuuser/items/hogeeeeeeeen.md --ssl-no-revoke
```
あとは、ファイルをGithubにアップロードするだけでOKです。
（CLIからgit pushでもできると思います。）

## 参考
Qiitaの記事をGitHubリポジトリで管理する方法

https://qiita.com/Qiita/items/32c79014509987541130

GET /api/v2/authenticated_user/items

https://qiita.com/api/v2/docs#get-apiv2authenticated_useritems

GitHub Actions の課金について

https://docs.github.com/ja/billing/managing-billing-for-github-actions/about-billing-for-github-actions

よく使うcurlコマンドのオプション

https://qiita.com/ryuichi1208/items/e4e1b27ff7d54a66dcd9
ClickUpのAI機能を試してみた

# はじめに
- [以前の記事](https://qiita.com/matsumura-yzrh/items/dc884b6ec64368084aec)でも紹介したように、弊社ではタスク管理ツールにClickUpを使っています。
- ClickUpにAI機能が追加されたので、試してみました。

# Write with AI
- まずタスク作成のために、画面右上の「Add Task」ボタンをクリックします。
![スクリーンショット 2024-01-06 16.58.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627922/3fc18157-4056-2693-2822-ae51f3d1a8a9.png)
- タスクの内容を記載する箇所に、「Add description」と「Write with AI」が表示されます。
- 「Add description」は、自分でタスクの内容を記載する従来の方法になります。
- 今回はAI機能を使うので、「Write with AI」をクリックします。
![スクリーンショット 2024-01-06 16.30.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627922/74e87fa7-4f92-5a19-9fff-df0c50880c8e.png)

## Tone of voice: default, Creativity: High
- まずは「Tone of voice」は`default`、「Creativity」は`High`で生成してみます。
- タイトルとTalking pointsには、例として「Laravel9から10へのアップデート」を入力します。
![スクリーンショット 2024-01-06 16.44.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627922/d5940fa9-4985-33f5-6389-fb0a9294a118.png)
- そうすると、以下のようにアップデートの手順を生成してくれました。
![スクリーンショット 2024-01-06 17.15.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627922/5de4e0ff-e32b-acd3-82f4-834a10f763ff.png)

## Tone of voice: default, Creativity: Low
- 次に「Tone of voice」は`default`のままにして、「Creativity」は`Low`にしてみます。
![スクリーンショット 2024-01-06 17.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627922/01dfa29f-8375-e3e0-d290-f71cfe16dc7d.png)
- アップデートの手順を生成してくれるのは`High`の時と同じですが、具体的なバックアップのコマンドも記載してくれるようになりました。
![スクリーンショット 2024-01-06 17.20.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627922/6a64f3f3-f490-09ba-1bb2-0947a19f9c63.png)

## Tone of voice: Humorous, Creativity: High
- そして「Tone of voice」を`Humorous`に変更して、「Creativity」は`High`で生成してみます。
![スクリーンショット 2024-01-06 17.26.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627922/8c9c872e-111f-ec2a-c77f-bacc32bfe0ec.png)
- 口調がガラッと変わりました！笑
- 説明の内容自体は、`default`の時とそれほど変わらないですね。
![スクリーンショット 2024-01-06 17.28.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627922/d8982393-fd84-5d66-39d1-6748392d9982.png)

# Suggest Subtasks
- また、既存のタスクでもAIの機能を使うことができます。
- 「Suggest Subtasks」をクリックすると、タスクのタイトル・説明・コメントからサブタスクの候補を生成してくれます。
![スクリーンショット 2024-01-06 17.41.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627922/b2f566ef-8391-af1f-d016-b1ffa0d68917.png)

# プランごとの無料トライアル
- AI機能は有料ですが、全プランに無料トライアル枠が付いています。
- 枠の数はプランごとに異なるので、公式ドキュメントをご参照ください。
  - https://help.clickup.com/hc/en-us/articles/13826034537623-ClickUp-AI-pricing-FAQ#How-long-is-the-trial

# 最後に
- 今回紹介した「Write with AI」と「Suggest Subtasks」は、ClickUpのAI機能ほんの一部になります。
- 他のAI機能についても公式ドキュメントに詳しく記載されているので、興味のある方はご参照ください。
  - https://help.clickup.com/hc/en-us/articles/12578085238039-Intro-to-ClickUp-AI
- そしてClickUpに限らず、AIの導入は様々なシーンで目にする機会が増えて来ています。
- 「すぐに導入できるか」や「たちまち役立つか」は別として、一旦触れてみてどういうものかを把握しておくことが重要だなと個人的には思いますね。
[Redmine]APIを利用して、イシュー（チケット）の関連付け有無リストを取得する

# 背景・当時の状況
ルールを作るのは容易いが、形骸化や守られないことは多々ある。そして廃れていく。。。
以前チーム内で、Redmineのあるプロジェクト内では関連チケットを必須とするルールを設けました。しかしあまり守られていないと感じたため、関連チケットの有無を定期的に調べて催促したかったのです。
そのため、関連チケットのないイシュー（チケット）を一覧化する方法を調べました。

# Version
```
$ curl --version
curl 7.68.0
```



# 結論
未関連イシュー（チケット）のURL炙り出しワンライナー
```
curl -sk --header 'X-Redmine-API-Key:xxx' 'https://${Redmine Domain or IP}/redmine/projects/${projectname}/issues.json?limit=100' | jq '.issues[].id' | xargs -I{} bash -c 'curl -sk --header 'X-Redmine-API-Key:xxx' 'https://${Redmine Domain or IP}/redmine/issues/{}/relations.json';echo https://${Redmine Domain or IP}/redmine/issues/{}' | grep -v "relation_type" | cut -b 17-
```

# 解説
プロジェクト以下のすべてのイシューID取得して一覧化
```
curl -sk --header 'X-Redmine-API-Key:xxx' 'https://${Redmine Domain or IP}/redmine/projects/${projectname}/issues.json?limit=100' | jq '.issues[].id'
```

一覧化されたイシューIDを標準入力にして、以下コマンドで再度APIリクエストを行う。ここでは、関連付けの有無を一つずつ取得してechoで標準出力している。
(関連付けの有無を知るためにはイシューIDが必要なため2段階要している)
```
| xargs -I{} bash -c 'curl -sk --header 'X-Redmine-API-Key:xxx' 'https://${Redmine Domain or IP}/redmine/issues/{}/relations.json';echo https://${Redmine Domain or IP}/redmine/issues/{}'
```

関連付けがあるイシューに関しては標準出力に`relation_type`と表示されるため、以下コマンドで除外（今回は関連付けが***無い***一覧を作成するため）
```
| grep -v "relation_type" 
```

最後に見やすいように整形している
```
| cut -b 17-
```

# その他Point
### 1. ?limit
URLクエリパラメータのlimitをつけることで、漏れなく対応可能。
***デフォルトだと25件までしか取得できない***ので注意！

https://www.redmine.org/projects/redmine/wiki/rest_api#Collection-resources-and-pagination

### 2. curl -s
途中経過なくして、純粋な一覧を取得できる

https://nvnote.com/curl-disable-progress

### 3. curl -k
SSLエラー無視

### 4. bash -c
一覧出力にechoを利用しているために利用している。
無いと改行がうまくいかない。





# その他参考記事
:::note info
URL変えれば様々な一覧が取得できるので、bashでフィルターかけてからURL書き換えれば自由自在
:::
Redmine APIの基本

https://blog.serverworks.co.jp/tech/2020/02/07/redmine-api/

jqの分かりやすい記事

https://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af
linuxコマンド一覧

linuxコマンド一覧です！
見るだけでは覚えれないので
実際打ちこみ見ましょう！

| コマンド   | 説明 | 使用例 |
|:-------:|------------|------------|
|  cd     | ディレクトリ移動 |cd移動したいフォルダ名|
| ls      | フォルダの内容をリスト形式で表示 |中身を見たいフォルダに移動して、ls    |
| mv      | ファイルを移動 |mv(移動元ファイル名/フォルダ名)（移動した先ファイル名/フォルダ名）    |
| cp| ファイルやフォルダをコピー | cp(移動元ファイル名/フォルダ名)（移動した先ファイル名/フォルダ名）      |
| clear   | 消さずに画面を綺麗にする |        |
| mkdir   |フォルダを作成 | mkdir フォルダ名    |
| touch   |ファイルを作成   |touch ファイル名      |
| rmdir   |からのフォルダを削除する    | rmdir フォルダ名 |
| rm      | ファイルやフォルダを削除 |rmファイル名/フォルダ名 |
| pwd     | 現在いる位置を表示 |-       |
| find    | ファイルを検索     | find/-name ファイル名|
| cat     |ファイルの内容を表示　|cat ファイル名　|
| diff    | ファイルとファイルの内容の違いを表示する　|diff 旧ファイル名　新ファイル名 |
| grep    | 指定した文字列がテキスト内に存在した場合その行を抽出する     | grep"検索したい文字"*ファイル名      |
| chmod   | ファイルやフォルダのアクセス権限を変更     | chmod　権限ファイル名      |
| chown   | ファイルやfourだのオーナーやグループを変更する     | chown 変更したいユーザー名　変更したいファイル名      |
| history | コマンドの履歴を表示     | -      |
| ln      | ファイルやフォルダにリンクを設定     | ln リンク元ファイル名　リンク先ファイル名      |
| man     | コマンドのマニュアルを表示する     | man コマンド      |
| apropos | manページの内容を検索     | apropos キーワード      |
| less    | テキストファイルを閲覧     | less ファイル名      |
| more    | ファイルをページ単位で閲覧     | more ファイル名|
スプレッドシートにおけるArrayFormulaとQUERYの組み合わせ

# スプレッドシートにおけるArrayFormulaとQUERYの組み合わせ

## 目次

1. はじめに
2. 背景
3. やりたいことの概要
4. 問題の発生
5. 解決策の提案
   - 5.1 ArrayFormulaとQUERYの組み合わせ
   - 5.2 MATCHES関数の利用
6. まとめ

## 1. はじめに

本書は、スプレッドシートにおいてArrayFormula関数とQUERY関数を組み合わせてデータ処理を行う際に発生する問題に対する解決策を提供します。特に、配列中の条件に一致するすべてのデータを抽出する際にArrayFormulaを使用する際に発生する問題に焦点を当てています。

## 2. 背景

スプレッドシートを使用してデータ処理を行う際に、ArrayFormulaとQUERYを併用することで効率的な処理が可能です。しかし、特定の条件に一致するデータを抽出する際に、ArrayFormulaを使用すると期待通りの結果が得られない場合があります。

## 3. やりたいことの概要

配列が「フォームの回答 1」シートのA2:Jにあり、別のシートのD2以降の行に入力された値と同じものがC列に入力されているかを調べ、配列からA,D,E,F列を抽出したいと考えています。

## 4. 問題の発生

ArrayFormulaを使用して以下のクエリを実行した際に、期待通りの結果が得られないという問題が発生しています。

`=ArrayFormula(QUERY('フォームの回答 1'!$A$2:$J, "select A,D,E,F where C='"&D2:D&"'"))`

この式では、D2に該当するものしか抽出されず、配列全体から条件に一致するデータを取得できません。

## 5. 解決策の提案

### 5.1 ArrayFormulaとQUERYの組み合わせ

以下のように、ArrayFormula内でQUERYを使用し、MATCHES関数を利用することで問題を解決できます。

`=ArrayFormula(QUERY('フォームの回答 1'!$A$2:$J, "select A,D,E,F where C Matches '"&TEXTJOIN("|", TRUE, D2:D)&"'"))`

この式では、条件に一致するすべてのデータが抽出されます。

### 5.2 MATCHES関数の利用

MATCHES関数は正規表現を使用して一致するデータを抽出します。この関数をArrayFormulaと組み合わせて使用することで、条件に一致する複数のデータを効果的に取得できます。

## 6. まとめ

本書では、ArrayFormulaとQUERYの組み合わせにおいて発生する問題に対する解決策を提供しました。特に、MATCHES関数を利用することで、条件に一致する複数のデータを抽出する方法に焦点を当てました。これにより、スプレッドシート上で効率的なデータ処理が可能となります。

>メモ代わりにAI生成でまとめてます。未検証です
双方向から通信が同時に発生し、衝突を回避する仕組みCSMA/CD🔄


CSMA/CD (Carrier Sense Multiple Access with Collision Detection) は、イーサネットネットワークにおいて双方向からの通信が同時に発生した際に衝突を回避するための重要な仕組みです。この記事では、CSMA/CDのメカニズムとその実際のネットワークにおける役割について詳しく掘り下げます。

## CSMA/CDの基本プロセス🔍

CSMA/CDでは、以下のステップを通じてデータの送信と衝突の回避が行われます：

1. **キャリアセンス**🔎: 送信前に、ネットワーク上の伝送媒体が使用中かどうかを確認します。
2. **送信**📤: 媒体が空いていれば、データを送信します。
3. **衝突検出**💥: 送信中に他のノードからの送信が開始され、衝突が発生することがあります。
4. **ジャム信号**📡: 衝突が発生した際には、ジャム信号を送出し、他のノードに衝突を通知します。
5. **ランダムな待ち時間**⏲️: 衝突後、各ノードはランダムな時間だけ待機し、再送信のタイミングをずらします。
6. **再送信**🔄: 衝突回避後、データの送信を再試行します。

## CSMA/CDの衝突回避メカニズム🛡️

CSMA/CDの最大の特長は、複数のノードが同時にデータを送信しようとした際の衝突を効果的に回避する能力にあります。衝突が発生した場合、各ノードはランダムに選ばれた待ち時間を経て再度送信を試みることで、再衝突のリスクを減らします。

## CSMA/CDの現代ネットワークでの役割🌐

- **初期イーサネットでの重要性**: CSMA/CDは、特に初期のイーサネット技術で中心的な役割を果たしていました。
- **技術進歩による変化**: 現代のネットワーク技術、特にスイッチング技術やフルデュプレックス通信の進化により、CSMA/CDの必要性は減少しています。
- **歴史的な意義**: それでもなお、CSMA/CDはネットワーク通信の基本原則を理解する上で重要な概念です。
国際ロマンス詐欺や投資詐欺に遭ったら…相談ができるBot

# LINEチャットボットの使い方と特長

## はじめに

CHARMSというNPO法人では、国際ロマンス詐欺や投資詐欺の被害者を支援しています。2023年12月にChatGPTとLINEを活用したチャットアプリを立ち上げました。このアプリは、被害者の方々に寄り添うために設計されています。

## CHARMS相談ボットの概要
このボットは、詐欺被害者と共感できるように設計されています。実際のカウンセラーのデータを基にしており、相談員の話し方や性格を反映しています。特に、詐欺被害者の心理的サポートが重要な点として考慮されています。

**機能**

* 国際ロマンス詐欺や投資詐欺の被害の可能性を相談できます。
* 被害に気づいた時の対処法を相談できます。
* カウンセラーとして被害者の気持ちに寄り添い、様々な辛い気持ちにも対応します。

**技術**
現在はChatGPT3.5を使用していますが、GPT-4への移行を計画中です。バックエンドではGoogle Apps Scriptを使用しています。
GASのコードは下記のリンク先を参考にしました。

https://chatgpt-lab.com/n/n55257c082a9d

**注意点**
このボットは写真やスタンプには対応していません。AIの限界をご理解ください。

**使い方**
* こちらのリンクからLINEで友達登録してください。

https://line.me/R/ti/p/@743uluok

* LINEでボットに話しかけてみてください。相談内容をチャットで伝えてみてください。

**フィードバックのお願い**
使ってみた感想や改善点など、フィードバックをお待ちしています。スクリーンショットを添えて具体的なフィードバックをいただければ幸いです。フィードバックフォームはこちらです。

https://forms.gle/ApXnY52739JNBkVQ9


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">LINE用の相談ChatBotを作ってみました。性格設定をCHARMSの相談員の皆さんの言葉遣いや傾向を参考に作りました。皆さんタイプは様々、でも共通しているのが、ChatGPTの分析によるとフレンドリーで的確なアドバイスができて、相談者に寄り添い共感するということです。 <a href="https://t.co/SRwOoPGs9t">https://t.co/SRwOoPGs9t</a></p>&mdash; Rika (@meteoroid1701) <a href="https://twitter.com/meteoroid1701/status/1732948151659835594?ref_src=twsrc%5Etfw">December 8, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Rails lock! のメモ

ふとした時に lock! の挙動が気になるのでメモしておく。

## 前提

- Postgresql

## テスト1

以下のコードを console A, console B 両方に貼り付けて、A -> B の順に実行

```ruby
ActiveRecord::Base.transaction do
  User.first.lock!
  sleep 10
  puts 'foo'
end
```

### console A

```sql
  TRANSACTION (0.1ms)  BEGIN
  User Load (0.8ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1  [["LIMIT", 1]]
  User Load (0.8ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 FOR UPDATE  [["id", 4], ["LIMIT", 1]]
foo
  TRANSACTION (2.4ms)  COMMIT
=> nil
```

### console B

select for update が走るが、console A の終了を待ってから sleep 10 が走る

## テスト2

```ruby
# console A
ActiveRecord::Base.transaction do
  User.first.lock!
  sleep 10
  puts 'foo'
end
```

```ruby
# console B
User.first.update_confirmation_token!
```

### console A

テスト1と同じ

### console B

user の select は走るが、A を待ってから実行される

### テスト３

```ruby
# console A
ActiveRecord::Base.transaction do
  User.first.lock!
  sleep 10
  puts 'foo'
end
```

```ruby
# console B
User.first.clients.create!(
  name: 'foo',
)
```

### console A

テスト1と同じ

### console B

user の select は走るが、A を待ってから INSERT が実行される

### 補足

console B は以下にしても同じ

```ruby
Client.create!(
  user: User.first,
  name: 'foo',
)
```

## テスト4

```ruby
# console A
ActiveRecord::Base.transaction do
  User.first.lock!
  sleep 10
  puts 'foo'
end
```

```ruby
# console B
User.first.clients.last.update(
  name: 'bar',
)
```

### console A

テスト1と同じ

### console B

update まで即実行される

## テスト5

```ruby
# console A
ActiveRecord::Base.transaction do
  User.first.lock!
  sleep 10
  puts 'foo'
end
```

```ruby
User.first.clients.last.reports.create!(
  date: Date.current,
)
```

### console A

テスト1と同じ

### console B

insert が即実行される


## 参考

> 行レベルロックは、データの問い合わせには影響を与えません。 行レベルロックは、同じ行に対する書き込みとロックだけをブロックします。

https://www.postgresql.jp/document/9.4/html/explicit-locking.html#LOCKING-ROWS
Googleコードスキャナを使ってAndroidアプリにQRコード読み取り機能をお手軽導入

Androidアプリでワンショットのコードスキャン機能が滅茶苦茶簡単に実装できるようになっていました。というネタ

https://developers.google.com/ml-kit/vision/barcode-scanning/code-scanner?hl=ja

この記事に書かれている通りなので、蛇足も蛇足ですが...アプリのメイン機能ではなく、特定の手続きで１回だけなど、QRコードを読み取り機能が欲しくなることはよくあります。
この方法を使えば**カメラパーミッションも不要**で、簡単にQRコードを読み取ることができます。（世の中にはカメラを搭載していない端末もあるので、プロダクトで利用する場合、その考慮は必要かと思いますが）
Google開発者サービスがスキャン機能を提供しており、アプリはスキャン結果のみを受けとるというものです。アプリがカメラ画像に一切アクセスしないため、プライバシーポリシーのケアなども（規約上は）不要です。

|||
|--|--|
|![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/85817371-a6ba-bcbe-717a-09e865096549.png)|![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/0ef152bb-c037-dd46-3899-28046bd9a2c6.png)|

# 使い方

`com.google.android.gms:play-services-code-scanner` をdependenciesに追加

```build.gradle.kts
dependencies {
...
    implementation("com.google.android.gms:play-services-code-scanner:16.1.0")
}
```

AndroidManifestの`application`タグ内に`meta-data`タグを追加

```xml
<manifest>
...
    <application>
    ...
        <meta-data
            android:name="com.google.mlkit.vision.DEPENDENCIES"
            android:value="barcode_ui"/>
    </application>
</manifest>
```

`GmsBarcodeScanning`を呼び出し、結果を受けとる

```kotlin
findViewById<View>(R.id.button).setOnClickListener {
    GmsBarcodeScanning.getClient(this)
        .startScan()
        .addOnSuccessListener {
            Toast.makeText(this, "${it.rawValue}", Toast.LENGTH_LONG).show()
        }
}
```

以上！超簡単

# 読み取りの指定

この機能はQRコードだけではなく、バーコードを始め様々なコードを読み取ることが可能です。
実際のユースケースでは何か特定のフォーマットを読み取らせたいでしょうから、それを指定して利用するのが通常でしょう。その場合は`GmsBarcodeScannerOptions`を使います。

```kotlin
val options = GmsBarcodeScannerOptions.Builder()
    .setBarcodeFormats(Barcode.FORMAT_QR_CODE)
    .build()
GmsBarcodeScanning.getClient(this, options)
...
```

とすれば、QRコードだけを読み取ってくれます。

また、16.1.0以降は、自動ズーム機能を指定することができます。

```kotlin
val options = GmsBarcodeScannerOptions.Builder()
    .setBarcodeFormats(Barcode.FORMAT_QR_CODE)
    .enableAutoZoom()
    .build()
GmsBarcodeScanning.getClient(this, options)
...
```

私が使った範囲では、どういう条件でズームされるのかなどがいまいち分からず、便利なのかはよく分かりませんでした。

# コールバック

`startScan()`の戻り値は`Task`ですので、success以外のコールバックも登録可能です。

```kotlin
GmsBarcodeScanning.getClient(this, options)
    .startScan()
    .addOnSuccessListener {
    }
    .addOnCanceledListener {
    }
    .addOnFailureListener {
    }
    .addOnCompleteListener {
    }
```

失敗したりキャンセルされた場合にユーザーにメッセージを表示したりも簡単に実装できます。

以上です。
TypeScript×Firebase(Step2:CRUD処理)

## はじめに
[前回記事](https://qiita.com/koji0705/items/7321004ed6542e5df5be)の続きです。
FirestoreのCRUD処理を記載します。

▪️シリーズ
[TypeScript×Firebase(Step1:プロジェクト作成~データ取得まで)](https://qiita.com/koji0705/items/7321004ed6542e5df5be)
[TypeScript×Firebase(Step2:CRUD処理)](https://qiita.com/koji0705/items/3d6ec00cad126effc930)←いまここ
[TypeScript×Firebase(Step3:ディレクトリ修正、リファクタリング)](https://qiita.com/koji0705/items/d330911cbcc9fa44b63b)

https://github.com/kouji0705/firebase_typescript

## ソースコード
```shell:ディレクトリ構成
~/develop/firebase_typescript$ tree src   
src
├── firestore.ts
└── users
    ├── create.ts
    ├── delete.ts
    ├── read.ts
    └── update.ts

2 directories, 5 files
```

```ts:src/users/create.ts
import { addDoc, collection, doc, writeBatch } from 'firebase/firestore';
import { app, db } from '../firestore';
import { deleteApp } from 'firebase/app';

// 新しいユーザーを作成する
async function createNewUser() {
  try {
    // `users` コレクションに新しいドキュメントを追加
    const docRef = await addDoc(collection(db, 'users'), {
      name: 'New User',
      email: 'newuser@example.com',
    });

    console.log('ドキュメント作成成功！ドキュメントID: ', docRef.id);
  } catch (e) {
    console.error('ドキュメント作成エラー: ', e);
  } finally {
    // 処理が完了したらFirebaseの接続を閉じる
    await deleteApp(app);
  }
}
```

```ts:src/users/read.ts
import { deleteApp } from 'firebase/app';
import { collection, doc, getDoc, getDocs } from 'firebase/firestore';
import { db, app } from '../firestore';

// コレクションの全ドキュメントを取得する
async function getUsers() {
  const querySnapshot = await getDocs(collection(db, 'users'));
  querySnapshot.forEach((doc) => {
    console.log(`${doc.id} => ${JSON.stringify(doc.data())}`);
  });

  // 処理が完了したらFirebaseの接続を閉じる
  await deleteApp(app);
}

// コレクション内の対象ドキュメントを取得する
async function getUser(docId: string) {
  const docRef = doc(db, 'users', docId);
  const docSnap = await getDoc(docRef);

  if (docSnap.exists()) {
    console.log('Document data:', docSnap.data());
  } else {
    console.log('No such document!');
  }
  // 処理が完了したらFirebaseの接続を閉じる
  await deleteApp(app);
}

```

```ts:src/users/update.ts
import { doc, updateDoc } from 'firebase/firestore';
import { app, db } from '../firestore';
import { deleteApp } from 'firebase/app';

async function updateUser(docId: string) {
  const docRef = doc(db, 'users', docId);

  try {
    await updateDoc(docRef, {
      name: '更新されたユーザー名',
    });

    console.log('ドキュメント更新成功！');
  } catch (e) {
    console.error('ドキュメント更新エラー: ', e);
  } finally {
    // 処理が完了したらFirebaseの接続を閉じる
    await deleteApp(app);
  }
}

const docId = 'KZc9Ko0wSGVUHOqOO3Dx'; // 更新したいドキュメントのID
updateUser(docId);

```

```ts:src/users/delete.ts
import { doc, deleteDoc } from 'firebase/firestore';
import { app, db } from '../firestore';
import { deleteApp } from 'firebase/app';

async function deleteUser(docId: string) {
  const docRef = doc(db, 'users', docId);

  try {
    await deleteDoc(docRef);
    console.log('ドキュメント削除成功！');
  } catch (e) {
    console.error('ドキュメント削除エラー: ', e);
  } finally {
    // 処理が完了したらFirebaseの接続を閉じる
    await deleteApp(app);
  }
}
```
【チーズはどこへ消えた？】ざっくりアウトプット

# 初めに

スペンサー・ジョンソン著 【チーズはどこへ消えた？】
を読んできたのでざっくりアウトプットです。

# 対象読者

- 変化したい・しなければいけない人
- 変化に対する対応力・適応力を身に付けたい人
- 変化を恐れている・そもそも嫌いな人

# 前提

**チーズ**=**自分自身の人生における幸せ**
例えば、仕事、家族や恋人、財産など私たちが人生に求めるものです。
  
私たちは自分にとってのチーズを心に抱いていて、それが手に入れば幸せになれると信じ、チーズを追い求めています。
手に入るとそれに執着してしまい、なくしたり奪われたりすると大きなショックを受けかねないものです。

# まとめ

## 本書が伝えたいこと

かなりまとめると本書は以下のメッセージを伝えていると思います。

「**自分の幸せ**(チーズ)を見つける為には、変化に対応する適応力が重要である」

## 格言

- **変化は起きる**
チーズは常に持って行かれ、消え失せる
　　
- **変化を予期せよ**
チーズが消えることに備える
　　
- **変化を探知せよ**
常にチーズの匂いを嗅ぎ、古くなったことに早急に気付けるようにする
　　
- **変化に素早く適用せよ**
古いチーズを諦めれば、その分だけ新しいチーズを楽しむことができる
　　
- **変わろう**
チーズと一緒に前進しよう
　　
- **変化を楽しもう**
新しいチーズの味を楽しもう
　　
- **進んで素早く変わり再びそれを楽しもう**
チーズは常に持って行かれ、消え失せる
Windows10 初期セットアップのメモ書き

2024年1月に新しいWindows10マシンをセットアップした際のメモ。

# Windows10 環境設定・アプリケーション等

## まずやること

* マシンのホスト名を「システム」から変更する
* Google Chrome インストール、Googleアカウントログインと同期
* Dropbox インストールと、Googleアカウント経由のログイン
* Google IMEをインストール

## 日本語入力の変換、無変換キーによるトグル

Windowsのデフォルトの日本語入力切替は半角/全角キーだが、Macのようにスペースキーの両隣の変換、無変換キーで日本語入力のON/OFFを操作できるようにしたい。

> [Windowsの変換・無変換キーでIMEの有効無効をMac風に操作する](http://www.karakaram.com/mac-ime) 

上記を参考に、Google IME 用の[キーマップファイル](https://gist.github.com/hayamiz/eaa46150356e6d66d2fcd4628808e157)を作成した。

Ctrl-F12でプロパティを起動するショートカットも追加している。

* Google IME プロパティ　→　「キー設定の選択」を「カスタム」にして「編集」をクリック→「編集」→「インポート」で上記ファイルをインポートする

## インストールするもの (Boxstarter経由)

[Boxstarter](http://boxstarter.org/) をインストール

[run-boxstarter.ps1](https://gist.githubusercontent.com/hayamiz/7cc8a033f7d3b9417b1914deff369d25/raw/run-boxstarter.ps1) を C:\ などに保存して，boxstarter shell から実行する．

下記の内容を始めとする設定が自動で実行される。
* [Ctrl2cap](https://technet.microsoft.com/ja-jp/sysinternals/bb897578.aspx) ... まず最初にやるやつ
* [Bitvise SSH client](https://www.bitvise.com/ssh-client) ... SSHクライアント。SSHトンネルを切れるたびに自動で張りなおしてくれるので便利
* [Listary](http://www.listary.com/) ... エクスプローラで文字入力をすることでインクリメンタルにファイル選択を行うことができるようになる。その他便利機能多数
* [Java](https://www.java.com/ja/download/help/download_options.xml) ... サーバのiDRAC等リモートコンソール起動に必要
* VSCode
* 

## WSL

PowerShellを管理者として開いて下記のコマンドを実行する。

```
wsl --install
```

完了したら再起動する。

参考： https://learn.microsoft.com/ja-jp/windows/wsl/install

## 手動でインストール・設定するもの

* Windows Subsystem for Linux の有効化
* MS Store から Ubuntu、Windows Terminal インストール
* [OpenVPN GUI](https://openvpn.net/index.php/open-source/downloads.html)
* [Adobe Creative Cloud](https://creative.adobe.com/ja/products/download/creative-cloud?promoid=KSPDX)
* [Explzh](http://www.ponsoftware.com/) ... 多数の形式に対応した圧縮解凍ソフト
* [Slack](https://slack.com/)
* [PicPick](http://ngwin.com/picpick) ... 高機能なスクリーンキャプチャソフト
* [Typora](https://typora.io/) ... シンプルなMarkdownエディタ

## Visual Studio Code

Githubアカウントでログインして設定を同期する。

https://code.visualstudio.com/docs/remote/ssh を参考にSSHの設定をする。

Ubuntu WSLでキーを作成

```
$ ssh-keygen -t ed25519
```

`.ssh/config` と鍵ファイルを `C:\Users\<username>\.ssh` に配置する。

OpenSSH client をインストールする ( https://learn.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_install_firstuse?tabs=gui )
- 設定→アプリと機能→オプション機能を開く
- 「OpenSSHクライアント」があることを確認する
- なければ機能の追加でインストールする

VSCodeで Remote-SSH の extensionをインストールする。

ssh-agentを設定する（ https://code.visualstudio.com/docs/remote/troubleshooting#_setting-up-the-ssh-agent ）
- 下記のコマンドを管理者として実行しているPowerShellで実行する

```
# Make sure you're running as an Administrator
Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent
Get-Service ssh-agent
```

下記の内容で .bat ファイルを作成して鍵を登録できるようにする。

```
ssh-add C:\Users\<username>\.ssh\id_ed25519
```
Google スプレッドシート ＆ GAS インデックス値←→A1表記 切替関数



```javascript:GAS
/**
 * インデックス値からA1表記への変換を行います。
 * 特定セルの指定または範囲の指定が可能です。
 * @param {number} x1 - 開始列のインデックス
 * @param {number} y1 - 開始行のインデックス
 * @param {number} [x2] - 終了列のインデックス (範囲を指定する場合)
 * @param {number} [y2] - 終了行のインデックス (範囲を指定する場合)
 * @returns {string} - A1表記のセルまたは範囲
 */
function indexToA1Notation(x1, y1, x2, y2) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

  if (x2 === undefined && y2 === undefined) {
    // 特定セルの指定
    var range = sheet.getRange(y1, x1);
  } else {
    // 範囲の指定
    var range = sheet.getRange(y1, x1, y2, x2);
  }

  // A1表記を返す
  return range.getA1Notation();
}

/**
 * A1表記からインデックス値への変換を行います。
 * セルまたは範囲の左上の座標と右下の座標を取得します。
 * @param {string} a1Notation - A1表記のセルまたは範囲
 * @returns {number[]} - [x1, y1, x2, y2] 形式の座標配列
 */
function A1ToIndexNotation(a1Notation) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

  // A1表記からセルまたは範囲を取得
  var range = sheet.getRange(a1Notation);
  
  // セルまたは範囲の左上の座標を取得
  var x1 = range.getColumn();
  var y1 = range.getRow();
  
  var x2, y2;
  if (range.getNumRows() === 1 && range.getNumColumns() === 1) {
    // セルの場合はx2およびy2を未定義に設定
    x2 = undefined;
    y2 = undefined;
  } else {
    // 範囲の場合はx2およびy2を計算
    x2 = x1 + range.getNumColumns() - 1;
    y2 = y1 + range.getNumRows() - 1;
  }
  
  // インデックス値を配列で返す
  return [x1, y1, x2, y2];
}
```
ネットワーク内のあるデバイスと通信したい時に実際に起こっていること 🌐


ネットワーク内でのデバイス間通信は、表面上はシンプルに見えますが、その裏では複雑なプロセスが行われています。特に、スイッチングハブが果たす役割は非常に重要です。ここでは、スイッチングハブを使用した通信プロセスを、MACアドレステーブルの観点から詳しく見ていきましょう。

## ステップ1: ARPリクエストの送信 📤

**アクション:** IPアドレス「1」のデバイスがスイッチングハブを介してARPリクエストをブロードキャストします。

**スイッチングハブのMACアドレステーブル:**
- MACアドレス: `AA:BB:CC:11:22:33` (IPアドレス「1」のデバイス)
- ポート番号: 1

##### (ところで)ポート番号のアサインのプロセス 🔗
- **物理的接続時のアサイン:** デバイスがスイッチングハブに物理的に接続されると、その接続されたポートに自動的にポート番号が割り当てられます。
- **MACアドレスとの紐付け:** スイッチングハブは、接続されたデバイスのMACアドレスを識別し、そのMACアドレスを割り当てられたポート番号と関連付けます。

## ステップ2: ARPリクエストの受信と応答 📥

**アクション:** スイッチングハブはARPリクエストをネットワーク上の全デバイスに転送します。IPアドレス「2」のデバイスがリクエストを受信し、ARPレスポンスをスイッチングハブ経由で送信します。

**スイッチングハブのMACアドレステーブル:**
- MACアドレス: `AA:BB:CC:11:22:33` (IPアドレス「1」のデバイス)
- ポート番号: 1
- MACアドレス: `DD:EE:FF:44:55:66` (IPアドレス「2」のデバイス)
- ポート番号: 2

## ステップ3: データの送信 📡

**アクション:** IPアドレス「1」のデバイスがARPレスポンスを受け取り、スイッチングハブを経由してIPアドレス「2」のデバイスにデータを送信します。

**スイッチングハブのMACアドレステーブル:**
- MACアドレス: `AA:BB:CC:11:22:33` (IPアドレス「1」のデバイス)
- ポート番号: 1
- MACアドレス: `DD:EE:FF:44:55:66` (IPアドレス「2」のデバイス)
- ポート番号: 2

このようにスイッチングハブは、ネットワーク内のデバイス間の通信を効率的にルーティングするために、MACアドレステーブルを使用してデバイスとポートの対応関係を管理します。これにより、データパケットは正確に目的のデバイスに送信されます。

---

### MacアドレステーブルとARPテーブルについて 📚

#### MACアドレステ

ーブル
- **定義:** スイッチングハブ内部に保持されるテーブルで、接続されたデバイスのMACアドレスとポート番号を対応させたものです。
- **役割:** データパケットを効率的に正しいデバイスに転送するために使用されます。

#### ARPテーブル
- **定義:** ネットワーク内のデバイスが、IPアドレスをMACアドレスに変換するために使用するテーブルです。
- **役割:** IPアドレスからMACアドレスを特定することで、ネットワーク内でのデータ送信を効率化します。

---

ネットワーク通信は、これらのテーブルを活用することでスムーズかつ正確に行われ、ネットワークの安定性と効率性が保たれます。この背後にあるメカニズムを理解することで、ネットワークのトラブルシューティングや最適化に役立てることができます。
Linuxとは？

linuxのことがよくわかっていなかったのですごく簡単にまとめている動画があったので、
そちらを参考にしました！

### Linuxとは？
macOSやWindowsと同じ、OSの一つです
OSはアプリ開発に必要なWebサーバーに作る際に必須です。

### Linuxの概要
#### OS(Operating System)
コンピューターを管理しているソフトウェアのこと
1991年に最初のバージョンが公開
Webアプリの公開するときに必要となる「Webサーバー」を設定する際にも使用される

### Linuxでできること
- WindowsやmacOSのように「パソコンの操作ができる」
- 操作が早くなるCUI操作を基本としている

#### WindowsやmacOSのように「パソコンの操作ができる」
- ファイルやフォルダの操作
- インターネット検索
#### CUI操作とは？
マウスを使わずにキーボードだけで操作する方法
例）「cpコピー元コピー先」といったコマンドを打つだけ

### Linuxのメリット
1.多くの種類がある
2.無料で使える
3スペックの低いパソコンでも使える
#### Linux ディストリビューション
Linuxを使うために必要なアプリや機能を１つのパッケージとしてまとめているもののことです。
例）有料でもいいから、動作の安定したLinux環境を使いたい！
→「Red Hat Enterprise Linux」
マウスでの操作もできる「Ubuntu」

WindowsやまcOSがインストールされているパソコンにインストールすることも可能

### Linuxの代表的なディストリビューション
1.Red Hat Enterprise Linux(RHEL)
2.Ubuntu
3.CentOS

#### Red Hat Enterprise Linux(RHEL)
- 有償のLinuxディストリビューションで最も有名
- 商用サポートがある

#### Ubuntu
- CUI操作だけでなく「GUI操作」もできる
- macOSやWindowsに似せた画面にできる
- 「Ubuntuソフトウェアセンター」で豊富なフリーソフトが使える

#### CentOS
Red Hat Enterprise Linux(RHEL)の無料版というイメージ
制限がある

### Linuxを導入する方法
1.パソコンにインストールする
2.仮想環境にインストールする
#### パソコンにインストールする
Macの場合
Linuxのイメージファイルが格納されたディスクを使用することで、インストールできる
MacとLinuxは同時起動できない

#### 仮想環境にインストールする
##### 仮想環境とは？
パソコン上で動くパソコン環境を作ること
これを作ると、Macを起動しながら「アプリを開くような感覚でLinuxを動かすこと」ができる
「VirtualBox」などのツールを使えば、簡単に仮想環境を作ることも可能
良いコード悪いコードで学ぶ設計入門を読んで(その①)

# 前置き
今年の目標に小規模～中規模のリファクタリングができるようになることを設定しました。まずコードの良し悪しの判断基準が明確に分からなかったので名著である『良いコード悪いコードで学ぶ設計入門』の内容を纏めることで今後のphp,Laravelのアプリケーションの開発に生かしたいと思いました。

## 1章 悪しき構造の弊害を知覚する
- 技術駆動命名や連番命名をしない

```sample.php
class MemoryStateManager{
    void changeIntValue01(int $changeValue){
        $intValue01-=$changeValue;
        //以下略
    }
}
```
MemoryStateManagerみたいな関数の技術駆動命名結構してたかもしれない
他者から見ると意図がわかりにくいのか、知らなかった。注意する。
- 条件文の巨大なネスト

ネストが深くなると仕様変更などに時間がかかるという話

- 様々な悪魔を招きやすいデータクラス

```DataClass.php
public class ContractAmount{
    public int $amountIncludeingTax;//税込金額
    public float $salesTaxRate;//消費税率
}
```
データクラスとは自由にデータの出し入れ可能な構造を持つクラス
(上だとContractAmountは税込金額と消費税率をpublicなインスタンス変数で持っている)
このデータクラスを用いて計算ロジックを別のプログラムに組んだ場合が以下

```ContactManager.php
//契約を管理するクラス
public class ContractManager{
    public ContractAmount $contactAmount;
    //税込金額の計算
    public calculateAmountIncludingTax(int $amountExcludingTax,float $salesTaxRate):int{
        //計算
        float $multiplier = $salesTaxRate+float(1.0);
        float $amountIncludingTax *= $amountExcludingTax
        return intval($amountIncludingTax)
    }
    //契約締結
    public conclude():void{
        int $amountIncludingTax=calculateAmountIncludingTax($amountExcludingTax,$salesTaxRate);
        $contractAmount = new ContractAmount();
        $contractAmouont.amountIncludingTax = $amountIncludingTax;
        $contractAmount.salesTaxRate = $salesTaxRate;
    }
}
```
データを作成するクラスであるContractAmount、データを計算するクラスのContactManagerが離れている(低凝集)ため、開発生産性が下がる以下の問題を引き起こす。

- 重複コード
同じロジックを別のメソッドに実装してしまう
- 修正漏れ
重複コードが生まれるため、修正漏れが発生しやすくなる
- 可読性低下
コードの意図が読みずらくなる
- 未初期化状態(生焼けオブジェクト)の発生
ContractAmountは初期化の必要なクラスのため、代入する値によっては例外が発生する
- 不正な値の混入
バリデーションロジックを実装する際、漏れが生じ無効な値が入りやすくなる

# 感想
エンジニアになって低凝集のコードを見たり、修正に苦慮することが最近増えてきたように感じる。私も結構そういうコードを書いてしまっているかもしれない。型付きに慣れていきたい。今後意識していく。

時間はかかるかもしれないが、この書籍の内容を全17章分一通りアウトプットしつつ良いコードの定義を理解することを今年中にやる。

# 参考書籍
良いコード悪いコードで学ぶ設計入門　著:仙塲大也
Python学習でよかった教材 まとめ

## Pythonを非情報系学生が0から学ぶ際に役だった教材まとめ

ざっと箇条書きにすると以下（思いつき次第更新予定）

1. [Paiza 「Python3 入門編」](https://paiza.jp/works/python3/primer)
1. [ゼロからのPython入門講座](https://www.python.jp/train/index.html)
1. [Progate 「Python学習レッスン IV」](https://prog-8.com/lessons/python/study/4)


### 1. Paiza 「Python3 入門編」
自分はプロゲートより、ドットインストールより、この教材が一番わかりやすかったです。解説が細かすぎない。かつわかりやすい印象。でもあっさりしていて細かいところは解説を省いている気もするので、最初に学ぶときにおすすめ。

### 2. ゼロからのPython入門講座
最後まで通るとPythonで何かを作る体験できます。また順番に進める過程で、Pythonの学習漏れを減らすのにも良い。初学者あるあるの、プログラミング学んだけど、何も作れない。を解決し得る良教材。しかも無料。

### 3. Progate 「Python学習レッスン IV」
1のPaiza 「Python3 入門編」ではクラスの概要を掴んだ感じで、クラス内のメソッドになぜselfを書くのか十分理解してなかった。（「まあ決まりごとみたいなもんだろ」と思っていた）
ですが、Progateの「Python学習レッスン IV」を通ることでなぜselfを書くのかが理解できました。Pythonの「クラス」がわかるようでわからない人におすすめ。
（Paizaで一度クラスの概要を掴んでいる状態だったのでより理解しやすかった説もあるが、それでもわかりやすい解説だったと思います。）
【初心者】ローカルで作成したプロジェクトをリモートリポジトリへ反映するまでの流れ

# はじめに
ローカルで作成したプロジェクトファイルを、初めてリモートリポジトリに反映させる時に、リモートリポジトリへの反映までの流れを理解するのに苦戦しましたので備忘録として残しておきます。なるべくイメージで覚えられるように書いて見ました。

# 前提条件
+ gitインストール済み
+ プロジェクト作成済み　
+ gitlabで以下の作業が完了済みであること
　- 初期登録
　- プロジェクト作成
　- ブランチ作成

# 手順0 プロジェクトを作成した時の状態
gitを何もいじらずにプロジェクトを作成した時のローカルリポジトリ、リモートリポジトリはどちらもプロジェクトの内容が反映されていない空っぽの状態です。

![各リポジトリの初期状態](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664957/370841f2-99f2-cc5b-8bad-cb9829de9474.png)

# 手順1 プロジェクトをステージに追加
以下のコマンドをターミナルで実行し、プロジェクトの内容をステージに追加する。
```
git add .
```
このコマンドを実行することでプロジェクトの内容全てがステージに追加される。

![プロジェクト内容をステージに追加するイメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664957/c877e0ba-7cd6-8038-b51b-c5c2da134d8f.png)

今回は初めてローカルリポジトリにプロジェクトの内容を反映させるため、上記のコマンドでプロジェクトの内容全てをステージに追加している。
特定のファイルのみをステージに追加するためには以下のコマンドを使用する。
```
git add [ファイル名]
```

# 手順2 ステージの内容をローカルリポジトリに反映させる
手順1によりプロジェクトの内容を全てステージに追加したが、まだローカルリポジトリには反映されていない状態である。
そこで以下のコマンドを実行し、ステージに追加されたプロジェクト内容をローカルリポジトリに追加する。

```
git commit -m "メッセージ"
```
>-mオプションを使用することで、コミットにメッセージを追加することができる。

手順1、手順2によりプロジェクトの内容がローカルリポジトリに反映される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664957/d68bfb6e-0ea1-28c3-b6d6-67c4a86919d6.png)

あとはローカルリポジトリをリモートリポジトリに反映するだけだ！とプッシュしようとすると問題発生。
この時点では、ローカルリポジトリから見てpush先がわからない状況である。

![宛先がわからない](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664957/d3b303aa-9583-2400-777a-b88b4c13dece.png)

# 手順3 gitlab上のプロジェクトにリモートリポジトリを作成
gitlab上のプロジェクトにリモートリポジトリを作成する前準備として、gitlab上のプロジェクトのpathを取得する必要がある。(住所のようなもの)
以下の画像中のSSHでクローン欄内のpathを取得する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664957/0cc521cf-cfc1-6bf9-c74f-601abf75c53a.png)

取得後以下のコマンドを入力し、gitlab上のプロジェクト内にリモートリポジトリを作成する
```
git remote add [リモートリポジトリ名] [取得したpath]
```
以上のコマンドより、ローカルリポジトリとリモートリポジトリが接続できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664957/6a9f20c8-fc6e-ac48-eb1d-c8948f39a746.png)

>厳密にいうと接続ではないが、イメージとしては接続に近いと個人的に思う。

# ローカルリポジトリの内容をリモートリポジトリに反映
ここまできたら、お馴染みのpushをするだけである。
pushは以下のコマンドで行う。
```
git push [リモートリポジトリ名] [ローカルブランチ名 : リモートブランチ名]
```
>ローカルブランチ名の内容をリモートブランチ名に反映する。

これまでの手順を踏むことでローカルリポジトリの内容をリモートリポジトリに反映することができた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664957/5bb6d2b9-d96d-c2a8-de1b-9e35e4fdec95.png)