OmniAICreator/Qiita-1.07M huggingface dataset:
React typeScriptで勉強時間記録サイトを作成する初心者#1

初めまして!
私はここ最近エンジニア転職をするために日々プログラミング学習をしております。:writing_hand:


個人的にフロントエンドとバックエンドとで悩んだ結果、視覚的に自分の作成したものが分かりやすい(?)フロントエンドでの開発を主に学んでみようと考えました。


typeScriptを基礎的なところをYoutubeを見て手を動かしながらざっくり一周しReactの存在を知りモダンな技術、現在案件も多いという情報を目にしたのでReactとtypeScriptで開発してみようと思いました。。

何を作っていいかが今までずっと思い付かず悩んでいましたが、ふと自分が1日にどのくらいプログラミングに時間を費やしているか把握したいと思い、学習記録アプリ、サイトがないかと調べたところ、個人的に欲しい機能が無い、そもそも少ない(調べが足りない可能性も大💦💦)。

もうこの際自分で作ってみようと決心!!:triumph:

といったところで私が学習記録サイトを作成していく過程、学んだ技術、起こったエラーの解決方法を発信して思考を整理できればと思います!

めちゃくちゃ苦戦し、なかなか進まないことが多いと思いますが、エンジニア転職、プログラミング学習している方のモチベーションを少しでも自分も一緒に維持できればと思いますので頑張っていきます！！
【Python】sorted関数を利用して同じ組み合わせのクエリ実行（DBアクセス）を減らす方法

# 概要
`sorted`関数を利用することで、 DBアクセスする回数を減らすことができましたので紹介します。


## サンプルコード1
`sorted`関数とは、イテラブル（リスト、タプル、辞書など）をソートした新しいリストを返す関数。
以下、シンプルなサンプルコードです。

```py
def sort_and_tuple(input_list):
    sorted_tuple = tuple(sorted(input_list))
    return sorted_tuple

my_list = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
result = sort_and_tuple(my_list)
print(result)  # (1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9)
```

`sort_and_tuple`関数は、入力としてリストを受け取り、そのリストをソートした後、タプルに変換して返します。このように、`sorted`関数と`tuple`関数を組み合わせることで、リストの要素をソートし、その結果を変更不可能なタプルとして保存することができます。

公式ドキュメントはこちら。

https://docs.python.org/ja/3/howto/sorting.html


## サンプルコード２

次に、`fruit_list1`と`fruit_list2`という、異なる順序で同じ要素を持つリストで利用したコードです。
以下の通り、それぞれ別の順番ですが、ソートされたことで、これらのリストは関数内で「辞書のキー」として同じとみなされています。

```py
def add_to_dict(input_list, value, my_dict):
    sorted_tuple = tuple(sorted(input_list))
    my_dict[sorted_tuple] = value

my_dict = {}

fruit_list1 = ['apple', 'banana', 'cherry']
value1 = "Fruit Salad"

fruit_list2 = ['cherry', 'banana', 'apple']
value2 = "Smoothie"

add_to_dict(fruit_list1, value1, my_dict)
add_to_dict(fruit_list2, value2, my_dict)
print(my_dict)  # {('apple', 'banana', 'cherry'): 'Smoothie'}
```

最後に追加された値が`Smoothie`なので、`Smoothie`だけが保持されていることがわかりますね。
異なる順序で同じ要素を持つリストが同じキーとして扱われたことが確認できました。

## サンプルコード３
もう一つレベルアップして、冒頭で紹介した、DBアクセスを減らせる方法を紹介します。

もしも、順番が異なるだけの同じ組み合わせのクエリを（`for`ループとかで）大量にDBアクセスしている場合、少しパフォーマンスに影響が出てしまいますよね。その場合、以下のように、`sorted`でまずはソートし、一度同じ組み合わせで取得したものは辞書に保存（キャッシュ）してあげる形にします。

```py
class DataFetcher:
    def __init__(self):
        self.data_cache = {}

    def get_data(self, list1, list2, list3):
        key = (tuple(sorted(list1)), tuple(sorted(list2)), tuple(sorted(list3)))

        # キーが辞書に存在しない場合は、データを取得する
        if key not in self.data_cache:
            self.data_cache[key] = SampleModel.objects.filter(
                Q(field1__in=list1) & Q(field2__in=list2) & Q(field3__in=list3)
            ).distinct()

        return self.data_cache[key]
```

この例では、`get_data`メソッド内で`SampleModel`からデータを取得し、それをキャッシュに保存します。実際にこのようにすることで、同じ組み合わせのクエリ実行が大幅に減りました。

ちなみに、`Q`オブジェクトは、複数のフィールドに対する複雑なクエリを作成するためのもの。

上記では、
`field1`が`list1`のいずれかの値を持ち、
`field2`が`list2`のいずれかの値を持ち、
`field3`が`list3`のいずれかの値を持つ、
すべての`SampleModel`オブジェクトを取得するコードになっています。

## `sorted`メソッドもある
ちなみに、`sorted`関数とは別で`sorted`メソッドがあります。

```py
numbers = [5, 2, 3, 1, 4]
numbers.sort()
print(numbers)  # [1, 2, 3, 4, 5]
```

これはリスト自体をソートするリストオブジェクトのメソッド。
こちらの場合は、新しいリストを返さず、元のリストを直接変更します。
【生成AIアプリ100チャレンジ】（3）炎上防止！SNS文章校正アプリ

# 公開中サイト

https://ai.nuevo.jp/lyric_trans/

# 開発環境

|              |              |
|:------------:|:------------:|
| Server       | lightSail    |
| Language     | Python3.11   |
| Framework    | Django       |
| DB           | sqlite3      |

ローカル環境ではPythonのvenvを使用。エディタはvs codeです。

# 目的
 とにかくSNSには乱暴な言葉が多く飛び交っている。そういう言葉遣いを投稿する前に、綺麗な文章にしようというのが目的のアプリ。
 これで少しは地球も綺麗になるはずです。なにより自分がSNS弱者で乱暴な意見を言ってしまいがちなので、自分のために作りました。私同様にSNSやインターネットの中ではネット弁慶になりがちな人はぜひ、ChatGPTさんに校正してもらってから、POSTしましょう。

# 補足
 最初はXのAPIと接続してPOSTすることを考えたけど、それだと私のアカウントを閲覧者全員に使わせることが可能になるので、リンクボタンだけにしました。COPYボタンで生成後のテキストをクリップボードにコピーできます。リンクボタンでXを開いてPOSTするという流れです。会員制のサイトなどであれば、X連携などの仕様で個々人の校正アプリとして使うことも可能なのではないかなと思います。ジョークアプリの傾向が強いです。

# コード
```python:qiita.rb
            client = OpenAI(
                # This is the default and can be omitted
                api_key = OPENAI_API_KEY,
            )
            # ChatGPT
            response = client.chat.completions.create(
                model="gpt-3.5-turbo",
                messages=[
                    {
                        "role": "user",
                        "content": "ここに新しいユーザーの入力を置く"
                    },
                    {
                        "role": "system",
                        "content": """
                        下記規則に従って文章を書き直してください。
                        ・日本語で応答してください。
                        ・140文字以内に書き直してください。
                        ・差別的な表現があったら書き直してください。
                        ・不適切な表現があったら書き直してください。
                        ・暴力的な表現があれば削除してください。
                        ・性的な表現があれば削除してください。
                        ・できるだけ丁寧な言葉遣いに書き直してください。
                        そして書き直した文章だけ回答してください。説明などは一切しないでください。
                        なおした文章だけを返してください。
                        """
                    },
                    {
                        "role": "user",
                        "content": sentence
                    },
                ],
            )

            chat_results = response.choices[0].message.content
```

# アプリ画面
![スクリーンショット 2024-03-28 22.37.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398694/c386a362-e108-9495-b5b1-742ae8f40a8d.png)

# 感想
 プロンプトを仕込んでおけば、ある程度の構成をしてくれることは気づいた。チャットが過去の履歴を引き継いでしまうのでどうすればいいかと思っていたら、最初のユーザーに"ここに新しいユーザーの入力を置く"と記入することで履歴削除ができるらしい。（chatGPT4談）
 　強すぎる言葉を使うと、校正しないでその言葉に反応してしまうのは仕方ないか。あらかじめプロンプトを仕込むことでChatGPTに基盤となる人格？を埋め込むことは理解できた。
  まだ3作目のアプリだし、しばらくは簡単でシンプルなアプリが続くとは思う。
Pythonで「日付と時刻の情報を指定してインスタンスを生成する」の動作を確認してみた

# 概要

Pythonで「日付と時刻の情報を指定してインスタンスを生成する」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/python/date/index1.html

# 実装

以下のファイルを作成しました。
```sample.py
import datetime
dt1 = datetime.datetime(2020, 7, 21)
print(dt1)
dt2 = datetime.datetime(2020, 7, 21, 6, 12, 30, 551)
print(dt2)
tokyo_tz = datetime.timezone(datetime.timedelta(hours=9))
dt3 = datetime.datetime(2020, 7, 21, 6, 12, 30, 551, tokyo_tz)
print(dt3)

import datetime
d = datetime.date(2020, 7, 21)
print(d)

import datetime
t1 = datetime.time(6, 12, 30, 551)
print(t1)
tokyo_tz = datetime.timezone(datetime.timedelta(hours=9))
t2 = datetime.time(6, 12, 30, 551, tokyo_tz)
print(t2)

import datetime
print(datetime.datetime(2020, 7, 21, 6, 12, 30, 551))
print(datetime.date(2019, 12, 9))
print(datetime.time(23, 18, 45, 31112))
tokyo_tz = datetime.timezone(datetime.timedelta(hours=9))
print(datetime.datetime(2020, 7, 21, 6, 12, 30, 551, tokyo_tz))
ny_tz = datetime.timezone(datetime.timedelta(hours=-4))
print(datetime.datetime(2020, 7, 21, 6, 12, 30, 551, ny_tz))
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
2020-07-21 00:00:00
2020-07-21 06:12:30.000551
2020-07-21 06:12:30.000551+09:00
2020-07-21
06:12:30.000551
06:12:30.000551+09:00
2020-07-21 06:12:30.000551
2019-12-09
23:18:45.031112
2020-07-21 06:12:30.000551+09:00
2020-07-21 06:12:30.000551-04:00
```

# まとめ

何かの役に立てばと。
Windows 365を展開する ネットワークはどちらを選ぶ？

マイクロソフトの渡部です☺

本日はWindows 365をMicrosoft Intuneで展開する際の二種類のネットワークについて、どちらを選択したらいいかをご紹介します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/1890af3b-670d-8c2a-0ec3-9acdc33f890f.png)


ここでいうネットワークというのは、クラウドPCから出ていくネットワークのことを指します。
物理PC⇔クラウドPCの画面転送の通信のことではありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/574aa252-afc8-3301-b8d0-61157ac12c15.png)



# オプション1 Azure ネットワーク接続　を選んだほうがいい場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/8ff77227-b39a-84cf-926f-13c83d4df68a.png)

Windows 365 クラウドPC が使用するネットワークの選択肢として、AzureのvNet内のSubnetを指定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/78678b9f-e9b3-d998-fcbf-5f8b38138a71.png)

以下のコンディションのユーザーはAzure ネットワークが最適です。
- クラウドPCからのネットワークをカスタマイズしたいとき
    - トラフィックルートやポート、VPNやExpressRouteゲートウェイ接続
- クラウドPCからのネットワーク経路は自社ネットワークを経由させたいとき
- クラウドPCをActive Directoryで管理し、Hybrid Entra Join形式で認証させる場合
- クラウドPC展開時にクラウドPCに振られるローカルIPアドレスのレンジを固定したい場合
- Azure ExpressRouteを使用して専用線経由で自社ネットワークと接続をしたい場合

などなど

**総評：Azure上で仮想ネットワークを設計したものを、そのままクラウドPCのネットワークとして持ち込めるので、なんとでもカスタマイズ可能なのがうれしいところ。**
が、Azureのネットワーク利用料が、クラウドPC本体の費用とは別途発生します。

# オプション2 Microsoft でホストされるネットワークを選んだほうがいい場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/1492ede5-ab7e-5067-0ea8-0593beb16fe7.png)

Azure ネットワークを持ち込む以外にも、Windows 365の月額ライセンスに付帯したMicrosoftがパッケージ化してご提供するネットワークを選択いただけます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/9bd66f0d-a70f-1295-caa3-0312a8ab0d21.png)


以下のコンディションのユーザーはMicrosoftネットワークが最適です。
- **Azureネットワークでなければいけないユーザー以外**
- 自社のネットワークと接続する際、VPN Client配布型でもOKな場合（Intuneからクライアント配布できます）
- Azureのサブスクリプションがない場合
- ネットワーク構築の知識、Azureの知識があまりない場合

**総評：設計不要でプロビジョニング時にネットワーク選択するだけで、使えるのと、追加コストがかからないのがうれしいところ。Microsoftとしてもこちらの使用を推奨しております。**
が、カスタマイズ性には欠けるので、Azure ネットワークでなければいけない条件があるのであれば、Azureネットワーク一択になります。

# クラウドPCのネットワークスピードを検証してみた
ちなみに、Microsoft ネットワークも裏側はAzureのネットワークを使用しており、Microsoft の強力なネットワークインフラのバックボーンのメリットを享受できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/f416e647-296a-d247-e22a-28ed9dc8dc7e.png)

Microsoft ネットワークを使って東日本リージョンに展開したクラウドPCのネットワークスピード（ご参考まで。このスピードを確約するものではありません）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/123ee3b8-031f-62dd-6b7a-9f99d518c5e1.png)

私の物理PCのネットワークはというと・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529374/4f0a6795-0ff6-4c29-8a24-dfe25445e6eb.png)
(出先なので、モバイルのデザリングでの作業・・・)

# References
[Windows 365 ネットワーク展開オプション](https://learn.microsoft.com/ja-jp/windows-365/enterprise/deployment-options)
[Windows 365ネットワーク要件](https://learn.microsoft.com/ja-jp/windows-365/enterprise/requirements-network?tabs=enterprise%2Cent)
AtCoder Beginner Contest 150 B

# はじめに
こんにちは！　この記事で初投稿になる まさる です。
ATCoderめちゃくそ強い人になりたいけど、覚えたことを忘れることが多いので備忘録としてあげていく事にしました。

# 問題
しょうもないミスで２回ほどWAをぶちかましてしまいました…
https://atcoder.jp/contests/abc150/tasks/abc150_b

# どこでミスったの？

'''
#include <iostream>

using namespace std;

int main()
{
	int N = 0;
	string s;
	cin >> N >> s;

	int id = 0;
	int sum = 0;

	for(int i = 0; i < N; i++)
	{
		switch (id)
		{
		case 0:
			if (s[i] == 'A') id = 1;
			else id = 0;
			break;
		case 1:
			if (s[i] == 'B') id = 2;
			else if (s[i] == 'A') id = 1;   // ここ書き忘れた！！
			else id = 0;
			break;
		case 2:
			if (s[i] == 'C')
			{
				sum++;
				id = 0;
			}
			else if (s[i] == 'A') id = 1;
			else id = 0;   // ここ書き忘れた！！
			break;
		default:
			id = 0;
			break;
		}
	}

	cout << sum;
}
'''
( コードの汚さは許してください何でもします．．． )
ABCが連続で入力されているのを読み取るのに、idという変数を用いています。
switch文でidの動きを監視していたのですが、修正前のコードだと、ＢやＣの次にＡが来ると、Ａが来たのにカウントを始めていませんでした、、

これに気付かず愚かな私は２回もＷＡをかましました。

# さいごに
ATCoder初心者なため、テストケースが開示されていることを今日初めて知りました。
まだまだ解いた問題数が少ないので、まずは量こなしていこうと思います。
【Rails + Docker】Render.comでMulti Environment Credentialsに対応する

## はじめに
Render.comでなにも考えずデプロイしたら、development環境でデプロイされてしまいました。
production環境でデプロイしたくて試行錯誤したのでその方法と詰まった点を簡単にまとめてみました。
Render.comに環境変数を追加するために今までdashboardから追加していました。
`.env`で環境変数を管理することも考えましたが、チーム開発の際の障害が大きすぎるので`credentials.yml.enc`での管理を考えました。

## Multi Environment Credentialsとは
credentialsは`rails5.2`からサポートされ始めた機能です。
機密情報を暗号化し、安全に保護するためのものです。
Credentialsを使えば、復号化キーを紛失、もしくは盗難にあわない限り、機密情報を保護することができます。
`rails6`よりMulti Environment Credentials機能が追加され、環境毎に秘匿情報を設定できるようになりました。

## 実際に設定する
最終的な`credentials.yml.enc`周りのファイル構成はこのようになる予定です。
```
.
│
└─config
  │  credentials.yml.enc
  │  master.key
  │
  └─credentials
     production.key
     production.yml.enc
```
`rails new`を行ったときに`config/credentials.yml.enc`が作成されると思います。
今回はこちらを開発、test環境ように使用します。

### production環境用の`credentials.yml.enc`を作成する
```bash
EDITOR="vim" rails credentials:edit --environment production
```
これで以下のファイルが作成されます。
- `config/credentials/production.yml.enc`
- `config/credentials/production.key`

### `production.yml.enc`に`secret_key_base`を設定する
`rails new`で作成された`config/credentials.yml.enc`には`secret_key_base`の値が自動挿入されます。
Multi Environment Credentialsで作成されたファイルにはその値が記載されていません。

そのため、手動で設定する必要があります。
以下のコマンドで`secret_key_base`を生成します。
```bash
rails secret
```
上記のコマンドで生成されたキーを先ほど作成した`config/credentials/production.yml.enc`に記載します。
```bash
EDITOR="vim" rails credentials:edit --environment production
```
```
secret_key_base: <生成されたキー>
```

設定しなければ以下のエラーが出ます。
```
rails aborted!

PMArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `bin/rails credentials:edit`
```

### Render.comのDashBoardから環境変数を設定
production環境でデプロイするための環境変数を設定します。
設定する環境変数は以下です。
- RAILS_ENV: production
- RAILS_MASTER_KEY: *****
この時の`RAILS_MASTER_KEY`は`production.key`の値を設定します。

これで完了です。
正常にデプロイされれば成功です。


## 注意したいこと
- `config/credentials/production.yml.enc`は`config/credentials.yml.enc`の内容をマージするわけではない
- `config/credentials.yml.enc`のsecret_base_keyは`config/credentials/production.yml.enc`に追記する必要があること

「`config/credentials/production.yml.enc`は`config/credentials.yml.enc`の内容をマージするわけではない」については以下の例で説明します。
```config/credentials.yml.enc
setting_1: abcdefg12345
setting_2: hijklmn67890
```

```config/credentials/production.yml.enc
setting_1: hellohello
```
ファイルの中身がこのようになっている場合、production環境では
```console
Rails.application.credentials.setting_1
=>"hellohello"

Rails.application.credentials.setting_2
=>nil
```
となります。
読み込まれるのは`config/credentials/production.yml.enc`だけです。
この２点を知らずに`config/credentials.yml.enc`の`secret_base_key`が読まれると思い込み右往左往しました。
バッチファイルの文字化け'∩╗┐'の対応方法について

## 宣伝
Flutterに関する技術ブログを運営しています。
ご興味のある方は、よかったらご覧ください♪
https://flutterdevelop.blog/


## 本題
バッチファイルを実行すると、以下のようなエラーが発生しました。
```
'∩╗┐' is not recognized as an internal or external command,
operable program or batch file.
```
要約すると、「そんなコマンド知らん」です。
もちろん"∩╗┐"という文字はバッチファイルに入れいていません。
どうやら何かが文字化けし、正しいコマンドが実行されていないようです。


## 事象
このエラーが発生した状況は以下です。
 
ファイル文字コード：UTF-8
環境：Windows

バッチファイルをWindows既存アプリ「メモ帳」保存すると
１行目のコードに対し、該当の文字化けが発生します。

## 問題
バッチファイルの１行目のコードが正常に実施されません。
２行目以降は正常に実施されますが、意図した結果にならない可能性があります。
 
私の場合は「@echo off」を１行目に設定していたため、
処理自体は問題なく実施されましたが、「@echo off」が機能していないため、
全てのコメントが表示されてしまいました。

## 原因
全てのWindowsで起こる事象ではありませんが、
環境により「メモ帳」で保存すると、BOM付きのテキストデータに変換されます。
BOMとは、"Byte Order Mark"の略で、詳しくは以下サイトを参照ください。
[参考サイト：UTF-8のBOM付き・BOM無しの違いと確認方法](https://uxmilk.jp/48923)

BOM付きとなるとUTF-8データの場合、先頭3バイトに見えないデータが付与されています。
しかしバッチファイルはこれをコードと認識してしまうため、上記のエラーが発生します。
 
## 対策
検索すれば色々と方法はあったのですが、
個人的に以下の方法が最も簡単だった方法をご紹介します。
 
### 方法１
１．サクラエディタで対象のバッチファイルを開きます。

２．ファイルから「名前を付けて保存」をクリックし、
　　以下の「BOM」のチェックを外します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561397/804a2b8b-8693-704c-298d-54740ad7cb4d.png)
 
３．「保存」をクリックすると、BOMが除去された内容で保存されます。

### 方法２


この方法はエラーを取り除く方法ではありませんが、
状況により、サクラエディタが使用できない場面での対象に有効です。
 
方法としては単純で、１行目のコードがエラーとなるならば、１行目に何も書かなければ、解決できます。
```
-空白行-
@echo off
```
ただし、先頭３文字にBOMが付与されているため、
バッチ実行時、最初に挙げたエラーは発生しますがそれだけで済みます。
 

以上が対応方法になります。
参考になれば幸いです。
達人に学ぶDB設計徹底指南書を読んで

# はじめに

達人に学ぶDB設計 徹底指南書を読みましたので、感想をまとめました。

# 学んだこと
- 物理設計を行う前に論理設計を行う(エンティティの抽出)
- サイジング(格納するデータに合わせたハードウェアの選定など)ではパフォーマンスと整合性のバランスで検討する必要がある
- 物理設計について サイジング→ストレージの冗長構成→ファイルの配置について決める
- RAIDについて
- RAID0は冗長性(RAID)がないため冗長性の向上においては候補として検討に挙げられない
- 第一正規化：スカラ値の原則(一つのセルには一つの値しか持たない)
- 第二正規化：部分関数従属を解消(主キーに対する一意の値は別テーブルに分離する)→可逆的な操作なので無損失分解となる
- 第三正規化：推移的関数従属を解消する(主キーだけでない二段階以上で存在する一意の値は別テーブルに分離する)
- 代理キーの使い方
- 人工的なキーをシステムで付与することで不都合を解消する
- ただ積極的に使うものではない、論理モデルがわかりにくくなるため
- ID列とシーケンスだとシーケンスの方が柔軟に使える
- アプリ側で採番テーブル機能を用意するのはあまり良くない(移行時のバグ誘発や機能的にバグを生み出す可能性が高い)
- アドホック(場当たり的)な集計キーは使わない、テーブルを分けたりビューを使うことで使用を避ける
- ビューからビューを参照するような設計は避ける、仕様がわかりにくくなったりパフォーマンスに悪影響なため
- データクレンジング(DBに登録するために綺麗な状態にする)
- 木構造の隣接リストモデルは指摘されている問題があり、最近では入れ子集合モデルが採用されている

## 良かったところ

### 演習問題を通してより深く学ぶことができる
- 単純に学んだことを復習するだけの演習問題でなく、本書の中で紹介されていなかった部分については調べるような問題などがあり、演習問題を通してより学ぶことができると感じた。

### DBだけでなくハードウェアに関する部分についても掘り下げられていた
- RAIDやバックアップなど、ハードウェアに関する分野についても触れられており、単純なテーブルや設計の範囲だけでなく、パフォーマンスや冗長化などについても学べたと感じた。

## 難しかったところ
リレーショナルデータベースが木構造の取り扱いを苦手としていることに関連して、データモデルにも触れられていたが、データ構造の考え方についてはなかなかすぐにイメージしづらい部分だった。特に入れ子集合・入れ子区間モデルについてはなんとなく概念は理解できるが実際に頭の中で考えてみると意外と難しかった。理解しておくに越したことはないので何回か読み直して理解を深めていかなければと感じた。 

## 最後に
単純に設計といってもやはり幅広いところまで考えていかないとできないと改めて感じた。データの持ち方だけでなくパフォーマンスや長期運用に伴う劣化など、考えることはとても多いがこれらを網羅することでより良い設計ができると思うとやはり学ぶべき分野だと改めて思ったため、今後もより深く学んでいきたいと思う。
Zabbix LDAP連携

Zabbix6.0LTS AD連携

1.AD作業
    LDAP認証用ユーザー作成
    LDAPAUTH-ZABBIX

2.ZABBIX GUIでのLDAP設定
    認証タブ→LDAPをデフォルトの認証に変更
    LDAP認証の設定タブ→LDAP認証の有効化にチェック
    LDAPホスト→DCのIP
    ポート→デフォルト
    Base DN→DC=hogehoge,DC=local
    Bind password→LDAPAUTH-ZABBIXのPW（LDAP認証用ユーザーPW)
    ログイン→ログインテストで使用するユーザー
    ユーザーのパスワード→上記ユーザーのPW
    
※必ずテストを実行し、成功を確認すること(ここでのテストはあくまでLDAP認証でありzabbix GUIのログインユーザーのものではない
次工程のユーザー作成まではログアウトしないこと

ユーザー作成で先に作成したLDAP認証ユーザーを作成、権限・グループはSuper admin role、Zabbix administratorsとする
ここを忘れるとログイン可能なユーザーがいなくなるためログイン不能となった
ユーザー作成完了後、セッションを維持したまま、シークレットモード等で別ウインドウを起動してログイン確認を行うとよい
なにも考えずに Ubuntu にdocker, docker-composeを入れる方法

* docker
```bash
$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https software-properties-common ca-certificates curl
$ wget https://download.docker.com/linux/ubuntu/gpg 
$ sudo apt-key add gpg
$ echo "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee -a /etc/apt/sources.list.d/docker.list
$ sudo apt-get update
$ sudo apt-cache policy docker-ce
$ sudo apt-get -y install docker-ce
$ sudo systemctl start docker.service
$ sudo systemctl enable docker.service
```
* docker-compose
```bash
# https://docs.docker.com/compose/install/
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo  /usr/local/bin/docker-compose --version
docker-compose version 1.29.1, build c34c88b2
```

[補足]
docker-composeのversionが古くなっていたので修正。
HTML: DOM取得のなまくら術

対応できるかどうかはBrowser次第。いつの間にやら非推奨になってしまったり、廃れていったりする可能性もあります
<table>
<tr><th>関数<th>なまくら術
<tr><td>document.getElementById,<br>document.querySelector<td>id属性値を直指し
<tr><td>document.getElementsByTagName("*"),<br>document.querySelectorAll("*")<td>document.all
<tr><td>document.getElementsByTagName("form")<td>document.forms
<tr><td>document.querySelectorAll("a[href]")<td>document.links
<tr><td>document.querySelectorAll("a[name]")<td>document.anchors
<tr><td>document.getElementsByTagName("html")[0]<td>document.children[0], document.lastChild, document.documentElement
<tr><td>document.getElementsByTagName("head")[0]<td>document.head
<tr><td>document.getElementsByTagName("body")[0]<td>document.body
<tr><td>document.getElementsByTagName("script")<td>document.scripts
<tr><td>document.getElementsByTagName("img")<td>document.images
<tr><td>document.getElementsByTagName("embed")<td>document.embeds, document.plugins
<tr><td>document.getElementsByTagName("iframe")[0].contentWindow<td>frames[0]
</table>

## 例題
```html
<form id=f><input id=i></form>
```
上記のようなhtmlでform要素やinput要素を取得する場合、以下のようにできます
```js
//form
a=document.forms[0];
b=document.forms.f;
c=f;
//input
A=document.forms[0].i;
B=document.forms.f.i;
C=i;
```
`frames`は`for of`で参照できません。`for in`では参照可能ですが、`iframe`以外のobjectも参照しまくるので不便です。`frames.length`分だけ普通の`for loop`で巡回すると良いです。
```js
let a=document.getElementsByTagName("iframe");
console.log(a.length==frames.length);
console.log(a[0].contentWindow==frames[0]);

let c=0;
for(let b of a)console.log(c++);
for(;c;)console.log(frames[--c]);
for(let b in frames)console.log(b);// iframe以外も参照
for(let b of frames)console.log(c++);// error
```
## 後書き
まあ当たり前尽くしの事ではありますが、過剰なまでの関数連呼やjqueryの無駄遣いをちらほら見掛けるのもまた事実
静的ルーティング、動的ルーティング

今回も前回のL2スイッチに引き続いて、L3の勉強のためルータについてまとめた。前回の内容はこちら。https://qiita.com/daisei0311/items/1040703b8db0abc180ac

# 静的ルーティング
静的ルーティング→手動でルーティングの設定

宛先とネクストホップを設定する
ネクストホップは次のデータの転送先をきく「案内人」（ネットワークInterface）のこと。宛先は「10.1.3.0/24」のようにネットワークの指定をする。


# 動的ルーティング
静的ルーティング→自動でルーティングの設定

ルーター同士でルート情報の交換を行う。大規模ネットワークだと設定が便利。rt2,rt3の間でルーティングプロトコル「OSPF（Open Shortest Path Fast）」

# 再配送
静的ルーティングと動的ルーティングの互換性がない部分を補う方法。
利用例として、会社の合併や分割で機器が対応していない、複数の方式が重なるといったことがある。協調的に動作させるために<b>再配送</b>（変換）を行う。

# 設定の仕方(静的ルーティングの場合)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661566/c3799a43-0783-95a0-fb42-8009481000ed.png)
ping で家庭内LANからサーバーサイドにICMP Echoを送ることを考える。
そのとき、Requestを無事に送り、Replyが返ってくるには２か所ルーティングテーブルにdefault gatewayの設定をしなければならない。

家庭内LANから見たら、ネクストホップにあたるネットワークインターフェースは10.1.1.246。サーバーサイドから見たら、ネクストホップは10.1.1.254。それぞれ設定をする。

```
root@rt1:/# ping 10.1.1.253
PING 10.1.1.253 (10.1.1.253) 56(84) bytes of data.
64 bytes from 10.1.1.253: icmp_seq=1 ttl=63 time=0.034 ms
```
そうすると、応答が返ってくる。
メタデータ自動更新機能付きデータカタログのソースコードを公開しました！

# 前置き
こんにちは。データエンジニアの山口歩夢です！

先日、以下のイベントで登壇をしました！
こちらの記事では、登壇スライドとソースコードの共有させていただきます。

https://datatech-jp.connpass.com/event/310548/




# 登壇の内容
StreamlitとTerraformでメタデータの自動更新機能付きのデータカタログを自作したことについてお話をしました！



# 機能について
どんな機能のデータカタログなのかをご説明させて頂きます！

## データカタログの機能
### ドロップダウンで検索
データベース、スキーマ、テーブルをドロップダウンで検索すると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/bd351668-06bb-05d6-3289-a81069ca4ed0.png)
以下のように、テーブルの概要が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/dda8c477-c975-5dff-845a-90a2e188d4d4.png)
カラムの概要やプレビューも表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/cb3b744e-44dc-7fc7-3aeb-1cdb224f1506.png)

### テキストボックスで検索
テキストボックスに文字列を入力してエンターを押すと、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/696d013f-5dd2-fe03-e8f1-43f60292b391.png)
テーブルの概要に検索がかけられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/fce9f379-3698-4c0e-6aad-950039a5ee69.png)

ちなみにカラムやテーブルの概要は、SnowflakeのCOMMENTを表示させております！

## メタデータ自動更新の機能
TerraformとGitHub Actionsを使って、メタデータの管理や自動更新をする機能を実装しました！
詳細は別の記事に書いてありますので、こちらをご覧ください。

https://qiita.com/Ayumu-y/items/315b61c492bcc167d760

https://qiita.com/Ayumu-y/items/84c37f92ca9f26d20cfb

# スライドも公開！
上記に書いた内容ですが、詳細に記載したスライドを公開しております。
実装方法もスライドに書いてありますので、是非ご覧ください！

https://speakerdeck.com/gussan0223/streamlittoterraformdedetakataroguwozuo-tutahua


# サンプルコード
ソースコードの公開もさせていただいております🫡
`$ git clone`をして、環境構築をすることで簡単にご導入いただけるようにさせて頂きました！
環境構築の方法もREADMEに記載しております。


https://github.com/genda-tech/sample-data-catalog



# まとめ
まず、この度は登壇にお誘いいただき、誠にありがとうございました:bow: 


以前からデータカタログを自作していたのですが、メタデータの管理に課題がありました。
TerraformとGitHub Actionsを使って、メタデータ管理が効率化されたので非常に良かったと思っております。

# 採用
GENDAデータチームではプロダクトのデータ解析や機械学習プロジェクトを推進できるデータサイエンティストを募集しています。
興味を持っていただけましたら、是非ご連絡いただけると幸いです！

https://hrmos.co/pages/genda/jobs/1700006587045969926
GCP(Google Cloud Platform)のプロジェクトでOAuth クライアントIDを作成する

## はじめに

[GCP](https://console.cloud.google.com/)のプロジェクトでOAuthクライアントIDを作成して、認証に必要なClient Secretのjsonを取得する手順をまとめました。
プロジェクトの作成方法は[こちら](https://cloud.google.com/resource-manager/docs/creating-managing-projects?hl=ja)を参照してください。　

## 手順

[プロジェクト](https://console.cloud.google.com/)のナビゲーションメニューから「APIとサービス/認証情報」を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61849/a0aa9ddf-01b8-064b-c93e-712c6ceef081.png" width=500>

トップにある「+認証情報を作成」から「OAuthクライアントID」を選択して、　作成へ進みます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61849/9aa22d58-b17a-7073-39d7-cd05f32e96f4.png" width=500>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61849/454160d5-df97-ee46-aa67-d9a316b48fe4.png" width=500>

アプリケーションの種類は用途ごとに選択する必要がありますが、ここでは仮にデスクトップアプリとして作成します。
また名前もここでは仮に「my-google-api-tool-box-oauth2」としています。
作成を押すとOAuthクライアントIDが作成されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61849/0a67fc0b-a96e-0dcb-9392-09289b9c46aa.png" width=500>

ダイアログからダウンロードした　JSONを利用してGoogleAPIのOAuth認証を利用できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61849/f25ee584-8b49-ecae-c5d9-24b2075bfaaf.png" width=500>

以上となります。

## 関連
https://qiita.com/genta-mz/items/eeb5f3037e55486d9949
【論文紹介】60分でわかる!Transformer の近似・推論能力

# 概要
Transformerの理論解析をした論文を読んで研究室輪講で解説しました．そのスライドをTwitterに貼ったのですが，技術者向けのプラットフォームにしっかり置いておいた方が良いと思ったのでこっちにもリンクを貼っておきます．

https://x.com/trgkpc/status/1718265992130994608?s=20

# もう少し丁寧な導入
昨今，Transformerという機械学習アーキテクチャが自然言語処理，画像認識，音声認識・合成など幅広い分野で使われています．例えば，ChatGPTは今では知らない人が居ないと言っていいほど人工に膾炙したツールになりましたが，このChatGPTの"T"はTransformerから取られています（正確にはGPTがGenerative Pretrained Transformerの略）．
そんなTransformerがどうして上手く動くのか，気になりませんか？そんなモチベーションのもと，機械学習理論の研究が行われています．ここで紹介した論文はそんな潮流の中の一つとして，Transformerの近似誤差・汎化誤差を解析した論文になります．
フーリエ変換程度の数学的知識があれば読めるように解説したので，是非読んでください．
言語処理学会2024論文紹介/「RAGにおけるLLMの学習と評価：FAQタスクへの応用」

【一言で言うと】
FAQタスクのRAG運用において、LLMのfine-tuningの有用性を調査した

【タイトル/URL】
「RAGにおけるLLMの学習と評価：FAQタスクへの応用」
https://www.anlp.jp/proceedings/annual_meeting/2024/pdf_dir/P5-5.pdf

【まとめ】
この論文ではAmebaブログのヘルプページにあるFAQデータをQuestion Generationを用いて拡張し，手作業で回答を作成。さらに問題の難しさを関連文章の出現によってeasyとhardに分類という非常に大変な手作業でデータセットを作成している
このデータセットに対してGPT-4やELYZAなどの9個のモデルで評価を行った
評価指標はRagasのAnswer relevancyとBERT scoreを使用

【感想】
驚いたことに，表１ではほとんどのスコアでRAG＞LoRAとなっている。問題によってはfine tuningに匹敵する性能向上をRAGで達成できると言うことなので，計算資源のない組織にとってはありがたい結論

【画像】
![表１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2106750/8cfa0b44-3588-f416-34e2-80fbba4019be.png)
[ODC]Event Driven Architectureのリトライ・タイムアウトを確認する

[Event Driven Architectureが発表されたので触ってみる](https://qiita.com/jyunji_watanabe/items/d867db0723e5584039ff)で見た、Event Driven Architectureの、エラー処理とタイムアウトの動作を確認する。

# 環境情報
ODC Studio(Version 1.4.2)

# Event Handlerでハンドルされない例外⇒最大10回リトライ
## 動作確認用の実装
シンプルなEventを作り、そのHandlerを確実に失敗するように作る。
Event Handlerを失敗させ、リトライの動作確認をする。

### Event
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/c3c781b3-962c-a190-a79c-41d47f45b792.png)

### Event Handler
処理が流れると、自動的にRaise Exceptionにたどり着き、例外が発生する。
Exception Handlerを置いていないため、このActionは例外で終了する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/cbb1b5ca-1b37-b328-e445-b44882b38c7f.png)

Ifでは、Boolean型のSettingをチェックし、Trueになったら正常終了させる。これは、万が一に備えての予備的なロジック。無制限かつ短期間にリトライする仕組みであったら、ODC Portalから止めるために入れておいた。先頭のSleepも同じ理由で、共用の環境に過負荷をかけないようにおいてある。

## 動作確認
↑の実装を行ったEventをTriggerし、ODC PortalのTraceに表示された記録は以下の通り。計11回の実行が記録された。当初の1回の実行＋エラー時の最大10回のリトライ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/cd182507-9b0e-bd27-54f3-0f67c0ee566d.png)

リトライの間隔は、
最初の1回：数秒
2回目：2分
3回目：6分
4回目：14分
5回目以降：30分
と徐々に広がり、30分で打ち止めになる。

# Event Handlerのタイムアウト⇒2分
## 動作確認用の実装
Settingで指定した秒数分だけSleepするEvent Handlerを作成する。
Sleepする時間を変更しながらログを確認し、Event Handlerのタイムアウト時間を探る。
### Event
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/5d582df8-6ad7-50b3-0d5e-84251e2b281a.png)
### Event Handler
処理としては、Setting SecondsToSleepに設定した秒数分Sleepするだけ。動作していることをODC Portal > Logsから確認できるように、開始時と終了時にLogMessageでその時点の日時を出力している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/c91f01b7-4c39-8359-f3f8-c5f5fd71758d.png)

## 動作確認
### 110秒Sleep　⇒　正常に終了する
ODC Portal > Logsで開始ログ・終了ログともに出力されている。つまりEvent Handlerは実行に110秒かかってもタイムアウトしない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/1c1458c6-079b-bb6d-35f1-713f477936bf.png)

### 130秒Sleep　⇒　タイムアウトする
ODC Portal > Logsで開始ログが出力された2分後に再び開始ログが出力される。これはタイムアウトによってリトライされたことを示す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/7a3724e0-b4cb-e423-1225-38b3685bcb24.png)

以下のイベント実行のログ（「OS-BERT-61600 - Error while handling event.
The event execution exceeded the 120-second timeout.」）からも、2分でタイムアウトになったことが確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/3af9a4e7-907c-dc09-b276-fdfdd0e857ab.png)
FirbaseのNext.jsのAPI Routesを叩くときのホストをどうするか迷った

# はじめに

Next.jsでAPI Routesを作ってfetchするときに叩き方をローカルと本番でどのように変えるのかを迷ったのでまとめます

# 問題

以下のようにAPIを叩くとします

```ts
      const res = await fetch(`${API_URL}/articles?user=Sicut_study&count=20`);
      const data = await res.json();
```

ローカル : API_URL = http://localhost:3000/api
本番 : API_URL = https://hoge.web.app/api

このように環境変数で切り替えるように設定しました

しかし、ビルドの段階で本番のURLでは失敗してしまいました
Firebaseだからかはわかりませんが、決められたクライアントサイドからしか`fetch`ができないようで、本番のURLにするとビルドできません

# 問題


```ts
      const res = await fetch(`/articles?user=Sicut_study&count=20`);
      const data = await res.json();
```

このようにホスト部分を省略することで解決しました
ただこの方法をする場合は`use client`する必要が有ります

```ts
"use cleint";
(省略)
  useEffect(() => {
    const getArticles = async () => {
      const res = await fetch(`/api/articles?user=Sicut_study&count=20`);
      const data = await res.json();
      const articles = data.map((article) => {
        return ArticleCard.newArticleCard(
          article.title,
          article.date,
          article.url,
          article.thumbnail
        );
      });
      setArticles(articles);
    };

    getArticles();
  });
```

サーバーコンポーネントにするとホスト部分がないと動かなくなるので注意が必要です(省略できない)

# おわりに

Next.jsにだいぶ慣れてきたと思いましたが、まだまだわかっていないこともあるなと感じました

せいちょうできてよかったでｓ
プログラミングスクール卒業後のあれこれ⑤


前回の記事から約2か月空こうとしています。
前職で業務として取り組んでいたことはざっくりですが書き留めることが出来たかなと思っています。
じゃあ今はなにをしているか？について書いていきたいと思います。

# 社会復帰から約1年

記事を読んでいただいていた方は気づいていると思いますが、もうすでに退職をしており、別の仕事をしております。

退職理由は、
- 仕事と育児のバランスが取れなかった
- 会社のスピード感についていけなかった
- オンラインミーティング中の口論に耐えられなかった


など。
入社直後は社内のことを知ることやツールになれるために退勤後（子どもを寝かせたあと）もPC開いてなんとかついていこうと必死でした。
（データ整理業務を任されていたために夜仕事したりもしていた。）

子どもの体調不良が続いていたこともあり、子どもがそばにいながらも仕事をしていました。（会社的にはこれはOKだった）

しかし入社から2か月経とうとしたころ、今度は私自身の体調が悪くなり、発熱寒気などで仕事を休むことに。
そこから急に仕事も育児も家事も自信を無くし、先輩に相談→社長と面談→時短勤務（退職をして、6月終わり頃から業務委託契約を結び働く）とトントンと働き方の変更が決まっていきました。

時短で負荷がなく働けたことで、メンタル的にも落ち着いていきました。
しかし8月・・お盆中かお盆明け頃に契約終了のお知らせ。
特にわたしからも、「もう一度頑張りたいです！」といったことは言っていなかったので、
業務委託契約は長くはないんだろうなということは何となく感じていました。
でも、これで良かったんだと思っていました。

元々社長からは、負荷なく働きながら転職するかどうか考えたりする時間として使ってと言われていました。
急にまた転職活動というフェーズに戻るのは、子どももいる中で大変でしょう、とのこと。

2023年8月末には契約終了となり、9月から約1ヶ月転職活動をして、9月末ごろには新しい仕事の業務委託契約を交わし、それは今も続けて仕事をさせてもらっています。

今の仕事は開発に携わっているわけではないですが、2つ案件を契約しています。
セキュリティ対策としての業務と製品の動作テスト業務を主に行っています。
また、ここで学んでいることをQiitaにアップしていけたらいいなと思っています。

・・・と、2023年度はドタバタ、いろいろあった1年でした。
色々経験して感じたことは、今の自分の生活ではエンジニアとしてしっかり働けないなということ。
勉強する時間がない、といったら言い訳のように聞こえるかもしれませんが、本当に勉強する時間が無かった。
子ども寝かせたと思ったら末っ子の夜泣き、家事、食事の支度、荒れ果てた部屋、気づいたら朝・・本当苦笑いです。

2024年は今頂いている業務にしっかり取り組む。
無理をして働かない。
勉強は少しずつでも継続。
生活に合った働き方をして行く。

今の自分には大事で譲れないポイントだなと思っています。
挫折をしたと感じていましたが、今は前向きです。
仕事をしながら勉強もできているので、結果良かったと思っています。


5つの記事にまたがりこの2023年度のことをだらだらと書いてしまいましたが、読んでいただいた方がいらっしゃったら、大感謝です。
ありがとうございました。
引き続きQiitaを活用していきたいと思います。
Next.jsをFirebaseとGithubActionsでCDするとサーバー側で環境変数が読み込まれない

# はじめに

FirebaseでNext.jsをデプロイしたときに躓いたことをまとめます

# 問題


以下のようにデプロイを行いました

```yml
name: my-tech-blog-pipeline

on:
  push:
  workflow_dispatch:

env:
  NEXT_PUBLIC_SERVICE_DOMAIN: ${{ secrets.NEXT_PUBLIC_SERVICE_DOMAIN }}
  NEXT_PUBLIC_CMS_API_KEY: ${{ secrets.NEXT_PUBLIC_CMS_API_KEY }}
  NEXT_PUBLIC_API_URL: "https://my-tech-blog-417ef.web.app/api"
  QIITA_API_KEY: ${{ secrets.QIITA_API_KEY }}

  (省略)
  
  deploy:
    name: deploy
    runs-on: ubuntu-latest
    needs: test
    env:
      NEXT_PUBLIC_API_URL: "https://my-tech-blog-417ef.web.app/api"
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Setup Node.js and cache
        uses: actions/setup-node@v2
        with:
          node-version: "18"
          cache: "npm"
      - name: Install firebase-tools
        run: npm install --save-dev firebase-tools
      - name: Decode Firebase service account key
        run: |
          echo "${{ secrets.FIREBASE_KEY }}" | base64 -d > ./firebase-key.json
          echo "GOOGLE_APPLICATION_CREDENTIALS=${{ github.workspace }}/firebase-key.json" >> $GITHUB_ENV
      - name: change space
        run: ./node_modules/.bin/firebase use ${{ secrets.FIREBASE_PROJECT_ID }}
      - name: Deploy to Firebase Hosting
        run: |
          ./node_modules/.bin/firebase deploy
        env:
          FIREBASE_CLI_EXPERIMENTS: webframeworks
      - name: delete GOOGLE_APPLICATION_CREDENTIALS
        run: rm $GOOGLE_APPLICATION_CREDENTIALS
        if: ${{ always() }}
```

しかし、`NEXT_PUBLIC`がついていないものはすべて読み込まれていませんでした

# 解決方法

Firebaseの場合サーバーサイドが`CloudFunctions`にデプロイされます

CloudFunctionsは`.env`の内容をデプロイに利用しているためGithubActionsで環境変数が設定されていても利用されることがありませんでした

https://firebase.google.com/docs/functions/config-env?hl=ja#env-variables

そこでパイプラインの中で`.env`を作成することで解決しました

```yml
      - name: create env file
        run: |
          echo "QIITA_API_TOKEN=${{secrets.QIITA_API_TOKEN}}" >> .env
          echo "MICROCMS_API_KEY=${{secrets.MICROCMS_API_KEY}}" >> .env
          echo "URL_PREFIX=${{secrets.URL_PREFIX}}" >> .env
```

# 参考

https://blog.manaten.net/entry/runtime-env-for-client

https://firebase.google.com/docs/functions/config-env?hl=ja#env-variables
言語処理学会2024論文紹介/「言語の固有次元を測る」

【一言で言うと】
言語コーパスデータセットが持つ固有次元は数～数十と低い次元にあることを検証した

【タイトル/URL】
「言語の固有次元を測る」
https://www.anlp.jp/proceedings/annual_meeting/2024/pdf_dir/E6-1.pdf

【まとめ】
言語のような大規模な高次元データは、実際は小さな次元の多様体上に存在していると推測されている（多様体仮説）。
しかし、多様体はねじ曲がった曲面を形成していることが多く、多様体の次元を計測することは難しい。
この研究では、そのような問題をある程度回避するために、TownNNという新しい固有次元推定アルゴリズムを提案し、実際に7種類の英文データセットで計測を行っている。

【感想】
データセットがもつ概念的大きさの比較ができるので素晴らしいと思う。
データセット間の比較もできるのだろうか？
データセットAとBを測った後に、A+Bを計測すればいいのかな・・。。

【画像】
![fig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3347513/23d31fcf-7abd-aac8-7823-28d4a0d02502.png)
SQL Silver合格体験記 (Oracle Database SQL 1Z0-071)

## 受験の経緯
SES入社後1つ目にJavaSilverを取得し、2つ目の取得ではDB知識をつけたいと考えたため。
(JavaGoldに取り組むか考えましたが、難易度的にも知識の幅を広げるためにもDBをやっといた方が良い気がしたというのもあります。)

## 資格取得期間
おおよそ１ヶ月。

## 使用教材
-SilverSQL黒本
-Udemy【動画解説+模擬試験】1Z0-071-JPN : Oracle Database SQL 問題集
-ORACLE MASTERスキルチェック問題(https://blogs.oracle.com/oraclemaster/post/oracle-master-280k) ←2023年11月現在は使用できました。



## 学習概要

試験勉強前に軽くprogateで触ったことがあったので、progateのSQLの復習をしました。
delete from, insert into, などの基本的な動作、書き方を覚え、(黒本解き始めにDMLの書き順すら忘れていましたが)、繰り返し解くことで理解できました。
SQLの処理される順番、FROM,JOIN,WHERE,GROUP BY,HAVING,SELECT,ORDER BY,LIMITは最初の段階で暗記したのはよかったと思います。
(アルファベットの頭文字をとってサッカーっぽく
ふじがウィング、ハセはオフェンスリーダー、で覚えました。)

## ポイント

**黒本だけでなく他の教材を使うほうで合格率を上げられると思います**。
黒本の内容は充実していますが、Javaの黒本と比べ教材内の章末問題や最終模試に似通った問題は少なく、黒本で問題としては出題されていない各単元の知識が出題されることが多く感じました。
問題慣れするために、黒本だけに絞らず、他の教材にもやるのがいいと思います。
自分はUdemyの教材を使用しました(ping-tだと量が多くポイントが絞れないと思ったため)。

## 受験感想とその後思うこと
わりと満遍なく覚えないといけないので、合格は自信になりました。
やはり実務で使わないと忘れていくものの、資格勉強でスキーマなどの概念に初めて触れたことも直接DBを触らなくても現場で仕事をしていく中で生かされたと思います。
PHP ストリーム型のファイルの操作

# ストリーム型のファイルへの書き込み

参考: [fopen](https://www.php.net/manual/ja/function.fopen)  
参考: [fwrite](https://www.php.net/manual/ja/function.fwrite.php)  
参考: [fclose](https://www.php.net/manual/ja/function.fclose)  

- `fopen`, `fwrite`, `fclose` の3つセットで記述する

#### `.contact.dat`ファイルを作成しておく

#### `test.php`を作成及び編集

```php:test.php
<?php

$contactFile = '.contact.dat';

// ファイルを開く モード 'a+' は 読み込み／書き出し用でオープン 書き込みは常に追記
$contents = fopen($contactFile, 'a+');

// 追記したい文字を定義
$addText = 'テスト1' . "\n";

// 書き込み実行
fwrite($contents, $addText);

// ファイルを閉じる
fclose($contents);
```

`test.php`にアクセスして、`.contact.dat`ファイルを確認すると以下のようにテキストが書き込まれる。

```dat:.contact.dat
テスト1

```

# 書き込みの排他的ロックをかけてみる

参考: [flock](https://www.php.net/manual/ja/function.flock)

- `flock()`関数の第1引数にはファイルポインタ、第2引数にはロックの種類を指定する。
- `LOCK_EX` は排他的ロックで、他のプロセスによる読み書きを阻止する。

- ロックを解除するには、`flock($contents, LOCK_UN)` を呼び出します。

- ロック処理は必ず `fopen()` の後で行い、ロックの解除は必ず `fclose()` の前に行うようにする。

- ロックの種類には `LOCK_SH`(共有ロック)、`LOCK_UN`(ロック解除)などがあり、状況に応じて適切なロックを使用する。

`test.php`を編集

```php:test.php
<?php

$contactFile = '.contact.dat';

// ファイルを開く モード 'a+' は 読み込み／書き出し用でオープン 書き込みは常に追記
$contents = fopen($contactFile, 'a+');

// 排他的ロックをかける
if (flock($contents, LOCK_EX)) {
    // 追記したい文字を定義
    $addText = 'テスト1' . "\n";

    // 書き込み実行
    fwrite($contents, $addText);

    // ロックを解除する
    flock($contents, LOCK_UN);
}

// ファイルを閉じる
fclose($contents);
```

以上です。
【イベントレポート】「シフトレフトテストの推進と今後の展望」

## はじめに

◆この記事は何？
イベント[「伊藤 由貴さん、ブロッコリーさんに聞く！シフトレフトテストの推進と今後の展望」](https://findy.connpass.com/event/313168/)のレポートです。

◆対象は？
ソフトウェアテストやソフトウェア品質に興味がある方

◆この記事のねらい
シフトレフトの実践方法をお伝えできればと思います。

## イベント概要

◆イベント名
「伊藤 由貴さん、ブロッコリーさんに聞く！シフトレフトテストの推進と今後の展望」

◆日程
2024年3月28日

◆場所
オンライン

◆コンセプト
イベントページで次のように紹介されています。

> シフトレフトの重要性や開発生産性の向上、社内での進め方、実例など
様々な観点からQAのシフトレフトへの取り組みをご紹介いただきます。

イベントハッシュタグ
[#shiftleft_autify_findy](https://twitter.com/search?q=%23shiftleft_autify_findy)

## オープニング『シフトレフトとは』

オーティファイ株式会社 QAマネージャーの[末村拓也さん](https://twitter.com/tsueeemura)

「**1分でシフトレフトを紹介します**」という一言からスタート。

### シフトレフトとは？
シフトレフトとは、テストフェーズでのテストを前倒しすることです。

[「ソフトウェア品質を高める開発者テスト」](https://amzn.asia/d/eNZkzXI)では、「品質の向上活動を設計コーディングフェーズにもっていくという活動」と説明されています。

### 前倒ししたい理由
もし前倒ししないと、次のような影響があります。
- バグをキャッチするのが遅れる
- テストが難しい
- テストにしわ寄せが来る（十分なテスト期間が与えられない）

### シフトレフトの二つの軸
**①テストレベルのシフトレフト**
テストレベル：「単体テスト」「結合テスト」などの粒度のこと
例：これまでシステムテストでテストしていた内容を結合テストでテストする

**②プロセスのシフトレフト**
より早い段階からテスト活動を始める

## LT①『シフトレフトの１歩目として”テスト”を分解＆可視化した』

株式会社カカクコム QAエンジニア [伊藤由貴さん](https://twitter.com/yoshikiito)

↓資料はこちらで公開されています。

https://www.docswell.com/s/yoshikiito/5983J1-shiftleft_autify_findy#p1

まずはテストレベルのシフトレフトの話。

発表内容はまさにタイトル通りで、シフトレフトの1歩目のために、テストを小さく分解して、可視化した実践例をご紹介いただきました。

発表では、どういう風に声を掛けたか？など現場レベルの説明もありました。

◆印象に残ったポイント

> 「テスト」をおおきな塊として扱っているように見えた
実際は、「テスト」の中で様々なことを行っている
塊のままでは、シフトしづらい

「**塊のままではシフトしづらい**」は腑に落ちました。

自分の中でシフトレフトできていなかった要因が理解できました。
テストを分解/可視化する理由がよくわかりました。

分解方法や可視化の結果は[資料](https://www.docswell.com/s/yoshikiito/5983J1-shiftleft_autify_findy#p9)を見ていただければと思います。

シフトレフトしたいときに参考にしやすい発表でした。

## LT②『継続的テストモデルを実現するためにスリーアミーゴスを用いた10Xでのシフトレフトの事例』

株式会社10X 品質管理部 [風間裕也（ブロッコリー）さん](https://twitter.com/nihonbuson)

次に「プロセスのシフトレフト」の話になります。

↓資料はこちら

https://speakerdeck.com/nihonbuson/processshiftleft

### 継続的テストモデルとは

継続的テストモデルは、シフトレフトを整理した表現の一つです。

継続的テストモデル
- DevOpsの各段階でテストすること
- テストはフェーズではなく、アクティビティであるということ

スライドの図がわかりやすいです。

https://speakerdeck.com/nihonbuson/processshiftleft?slide=6

### 「スリーアミーゴス」とは

「スリーアミーゴス」とは3つの立場の人が集まり、協調的に要件を確認すること
三つの立場とは、QA、開発者、POです。

「スリーアミーゴスの結果、会話を通して気づいていく」とご紹介いただきました。

◆印象に残ったポイント

> スリーアミーゴスという取り組みを用いて、受け入れ基準作成時からテストを考える

私は設計時にテストを考えることはできていましたが、
受け入れ基準の作成時に、テストのことを考えることができていなかったです。

シフトレフトの余地がありそうです。

## おわりに

今回のイベントに参加して「シフトレフト」の解像度を上げることができました。

まずは、**受け入れ基準作成時のテスト活動**を取り入れます。

それでは。
VmmemとDocker

## Vmmemのメモリ、CPU使用率
Dockerを使用していると、たまにpcが極端に重くなるため、タスクマネージャーを見てみると、Vmmemという謎のプロセスがメモリやCPUを90%使用していることがあります。

## vmmemとは
Linux (WSL2) が動作している際に現れるプロセスで、仮想マシンのリソース使用状況を示すものです。

## Dockerを使用するとなぜvmmemに影響するのか
Dockerを使用するとWindowsでLinuxを動かすためにWSL2が使用されます。
WSL2は仮想マシン技術を用いるため、仮想マシンのリソース状況を示すVmmemのCPUやメモリ使用率が高くなります。

## 解決方法
以下サイトを参照してください。
・https://jp.minitool.com/news/vmmem-high-memory.html?amp
・https://www.drivereasy.jp/vmmem-high-memory-usage/
【Unity】VisualElement上でキーボード入力を取得する

# はじめに
みなさん、Editor拡張やっていますか?
今回はVisualElement上でキーボード入力を取得する方法を紹介します。

VisualElementには`RegisterCallback<T>()`というAPIが用意されており、特定のイベントに対してイベントを登録することができます。イベントには`KeyDownEvent`といったキーボードの入力を受け取るものがあります。
これを使用すればキーボード入力を取得できると思えますが、そううまくはいきません。

```csharp:RegisterCallbackの例
rootVisualElement.RegisterCallback<KeyDownEvent>(登録したい関数)
```

なぜかこれだけではできないので、取得するための解決方法を紹介します。

# 解決方法

解決方法は実に簡単で、
```
focusable = true;
```
これを行っておくだけです。
ただしこの方法では、VisualElementをフォーカスしているときにしか入力を取得できないので注意してください。

# 実践
実際に実践していきます。
文字をタイピングできるVisualElementを作成してみます。
コードは以下です。

```csharp
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public class TypingWindow : EditorWindow
{
    private string _text = "";
    private VisualElement _typingElement;

    public void CreateGUI()
    {
        _typingElement = new VisualElement
        {
            // キーボードイベントを受け取るためにフォーカス可能にする
            focusable = true,
            // 高さ幅を親の100%のサイズにする
            style =
            {
                height = Length.Percent(100f),
                width = Length.Percent(100f)
            }
        };
        // KeyDownEventを登録する
        _typingElement.RegisterCallback<KeyDownEvent>(OnKeyDown);
        // 再描画される際にGenerateVisualContentを呼び出す
        _typingElement.generateVisualContent += GenerateVisualContent;

        rootVisualElement.Add(_typingElement);
    }

    [MenuItem("Window/TypingWindow")]
    public static void ShowWindow()
    {
        GetWindow<TypingWindow>("TypingWindow");
    }

    private void GenerateVisualContent(MeshGenerationContext mgc)
    {
        // テキストを描画する
        mgc.DrawText(_text, new Vector2(10, 10), 14f, Color.white);
    }

    private void OnKeyDown(KeyDownEvent evt)
    {
        // キーボードイベントのキーコードによって処理を分岐する
        switch (evt.keyCode)
        {
            case KeyCode.None:
                return;
            case KeyCode.Backspace:
            {
                // テキストが空でない場合、最後の文字を削除する
                if (_text.Length > 0) _text = _text[..^1];
                break;
            }
            case >= (KeyCode)48 and < (KeyCode)90:
                break;
            default:
                // それ以外のキーコードの場合、テキストにキーコードを追加する
                _text += evt.keyCode.ToString();
                break;
        }

        // 再描画する
        _typingElement.MarkDirtyRepaint();
    }
}
```

`Window → TypingWindow`からウィンドウを開くことができます。

![b12994161157ba566c65a4e85f06a0f2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704747/a0935e39-cb20-50be-881a-194a8ed5a739.gif)

入力を取得できていますね！
以上です。

# 参考文献

https://forum.unity.com/threads/any-good-way-to-find-out-if-a-keyboard-key-is-pressed-with-the-mouse-over-a-visualelement.1063190/#post-6898823
node.jsのREPLで深いobjectを全部表示する

```
> repl.writer.options.depth = null
```

 例
```
> {1: {1: {1: {1: {1: 1}}}}}
{ '1': { '1': { '1': [Object] } } }
> repl.writer.options.depth = null
null
> {1: {1: {1: {1: {1: 1}}}}}
{
  '1': {
    '1': { '1': { '1': { '1': 1 } } }
  }
}
```

`repl.writer.options` に `util.inspect` の第二引数を設定できるようだ。

https://github.com/nodejs/help/issues/1490
PowerShellでSSL証明書作成

題名の通りです。

1.  PowerShellのプロンプトを管理者で開いて、以下コマンドラインを実行する。
```powershell:PowerShell(管理者)
PS> New-SelfSignedCertificate -subject <サブジェクト名>
```
　　
2. Windows キーを押しながら R キーを押し、[ファイル名を指定して実行] を開き、certlm.msc と入力して [OK] をクリックします。
　
3. 画面の左ペインより、[証明書 – ローカル コンピューター] – [個人] – [証明書] を選択し、作成された自己署名の証明書を確認します。


https://pkiwithadcs.com/new_selfsignedcertificate_cmdlet/

https://learn.microsoft.com/en-us/powershell/module/pki/new-selfsignedcertificate?view=windowsserver2016-ps
F9キーによる自動計算でカウンターをループ(Excel)

　こんにちは、初投稿です。今回はExcelにおける自動計算を利用したカウンターのループを作るための関数をお教えしたいと思います
　例えば数字を1〜5に設定した場合、F9を押している間は1、2、3、4、5、1、2、3、…とループが続く感じです
　検索しても出てこなかったので自分が第一発見者の可能性があるのですが、もし知ってるよって方がいらっしゃったらごめんなさい…

　作り方は簡単なのですが、まず初めに事前準備が必要です。 Excelのブックを開いたら「ファイル」→「オプション」→「数式」で「反復計算を行う」にチェックを入れ、最大反復回数を1にしてください。そうしないとエラーが出てしまうのでご注意
　準備ができたらセルA1に↓の写真の数式を入れてみてください

![image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758217/ff2ef5f2-54c8-0fa8-674f-4e44258adad7.jpeg)

　入れ終わったらF9を押しっぱなしにしてみてください。すると1から5までのカウンターがループします。わかりづらい場合はF9を連打してみるといいかもしれません

　これを利用し、条件付き書式と組み合わせてパラパラ漫画を作ることもできます。ただし、条件付き書式が多いと動きが鈍くなるのでご注意を…

　もし「こんな用途に使えるよ」的なものがあったらぜひ教えていただきたいです。ここまで読んでくださりどうもありがとうございました
RaspberryPiにルーティングを設定

### 複数インターフェースを持つ場合
https://qiita.com/BlueBlue/items/cf49e33cdc36a55b4082
https://tech.andhandworks.com/2018/09/raspberry-pi.html
https://zenn.dev/yutafujii/books/fcb457e798a3d5/viewer/bce757
https://y-naito.ddo.jp/index.php?id=1472284381
https://www.appliot.co.jp/blog/raspberry-pi%E3%82%92%E3%83%AB%E3%83%BC%E3%82%BF%E3%83%BC%E5%8C%96%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/
https://www.chobits.com/raspberry-pi-wifi-router/
https://tech-mmmm.blogspot.com/2018/03/raspbiandebianlinux.html
https://qiita.com/kooohei/items/b0931ae210911cc52adc
CodeGureのコードレビューでフルリポジトリ分析結果のダウンロード方法

# CodeGureのフルリポジトリ分析を試した結果

CodeGureのコードレビューの画面のどこ見ても、分析結果のダウンロードが無い！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284278/9a53de67-e8c9-b8e8-4ef3-7f1a56f7b9c7.png)

## とりあえずJSONダウンロードする方法

無ければ自分で作れば良い

ということで開発者ツールのコンソールで以下を貼ればダウンロードできます。
ダウンロードした後は、参考のリンクに貼ってるようなやり方でエクセルに取り込むなりしてもらえればと。

※記事を書いた時点でのHTML要素をベースにしています。HTML変わったら動かないです。
※ブラウザの日本語翻訳すると挙動が変になる場合があったけど諦めない心があれば大丈夫

```javascript
// データ抽出
const getData = () => {
  const data = []
  // カード単位
  const items = document.querySelectorAll('li[data-selection-item="item"] > div')
  for(let i = 0; i < items.length; i++){
    const item = items[i].children
    // リンク要素
    const link = item[0].querySelector('a').getAttribute('href')
    const title = item[0].textContent
    // 説明
    const text = item[1].textContent
    // 追加
    data.push({no: i, link, title, text})
  }
  return data
}

// 現在日付の文字列を作成
const getNow = () => {
  const date = new Date()
  const yyyy = date.getFullYear()
  const mm = ('0' + (date.getMonth() + 1)).slice(-2)
  const dd = ('0' + date.getDate()).slice(-2)
  const hh = ('0' + date.getHours()).slice(-2)
  const mi = ('0' + date.getMinutes()).slice(-2)
  const ss = ('0' + date.getSeconds()).slice(-2)
  const sss = date.getMilliseconds()
  return `${yyyy}${mm}${dd}-${hh}${mi}${ss}-${sss}`
}

// データ準備
const data = getData()
const now = getNow()

// ダウンロード
const blob = new Blob([JSON.stringify(data)], { type: 'application/json' })
const url = (window.URL || window.webkitURL).createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = `codegure-fullrepo-review-result-${now}.json`
a.click()
a.remove()
window.URL.revokeObjectURL(url)
```

## 参考

- [JSONファイルをExcelに変換](https://qiita.com/afukuma/items/65c6e96bd15b319e160f)
Reactアプリのテスト結果をCoverallsで表示

# 概要

下記Qiita記事の続きとなります。

https://qiita.com/ishi720/items/386a557313312fdec27d

前回は、Reactでカバレッジを計測できるようにしました。
今回は、GitHubActionsを用いて、pushするたびにカバレッジの計測を行い、Coveralls上で結果を表示できるようにします。



# 1. Coverallsのトークン取得

## 1.1 Coverallsのアカウントを作成

下記URLからアカウントを作成しgithubアカウントを紐づけます

https://coveralls.io/

## 1.2 リポジトリを紐づけ

`https://coveralls.io/repos/new`から、カバレッジの計測を行いたいプロジェクトをONにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473097/529db318-4b44-d9f4-89b4-e5cadb322d81.png)

## 1.3 トークンの取得

DETAILSのリンクを押下すると、トークンが表示されているのでコピーしておきます。

![スクリーンショット 2024-03-28 001152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473097/d1a7974a-db7c-f9a4-6b5c-00fd82d4c5d8.png)


# 2. githubにトークンの設定

GitHubActionsからCoverallsへ認証が通るようにします

## 2.1 トークンの設定

- githubプロジェクト内のSettingを押下
- 「Secrets and variables」を開き「Actions」を押下
- 「New repository secret」のボタンを押下
- トークン作成画面にて、Nameには、`COVERALLS_REPO_TOKEN`を入力。Secretには、先ほどコピーしたトークンを貼り付けます。（↓画面参考）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473097/386a2af1-e0dd-2db8-88f2-501896e3e65b.png)

# 3. GitHub Actionsの設定

GitHub Actionsの設定を行います。
下記のファイルをpushすると、自動でカバレッジの計測が行われます。

## 3.1 `.github/workflows/coveralls.yml`の作成

ブランチ名やコマンドなどは、状況に合わせて書き換えてください。

```yml
name: Coveralls

on:
  push:
    branches:
      - master

jobs:
  coveralls:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          node-version: 14.x

      - name: Install dependencies
        run: npm install

      - name: Run tests with coverage
        run: npm test -- --coverage

      - name: Upload coverage to Coveralls
        uses: coverallsapp/github-action@v2.0.0
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          path-to-lcov: ./coverage/lcov.info
```

## 3.2 GithubActionの実行

GithubActionが実行されて正常に終了すると緑のチェックマークが付きます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473097/d58696e0-2f34-30ce-454c-72632f1f89a3.png)



# 4. カバレッジの確認

`coveralls.io`上でカバレッジの内容が確認できるようになります。

https://coveralls.io/github/ishi720/levenshtein_distance_search


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473097/6efa36c2-3a77-56bc-7077-0e0de91b7171.png)


# おわりに

今回は、Coveralls上でカバレッジの結果が確認できるようになりました。とっても便利ですね。

ここまで読んでいただきありがとうございました。
VSCode のショートカットキー集

## はじめに
未だにVSCodeのショートカットキーを覚えられない自分の戒めのためと勉強のために記事を書いています。
また自分が忘れた時に確認する用のチートシートです。

## 対象者
・コーディングスピードを上げたい人
・作業効率を上げたい人
・ショートカットキーを覚えたい人

## 検索/置換系
- ```ctrl + f```　単語選択してから実行することでコピペがいらない
- ```ctrl + h```　同上
- ```ctrl + shift + f```　同上
- ```ctrl + shift + p```　ファイル名が分かっているものは便利
- ```alt + shift + f```　選択したフォルダ内で検索したい時に便利

## 編集系
- ```ctrl + c```　選択範囲をコピー
- ```alt + shift + ↑/↓```　カーソル行／選択行をまとめてコピー
- ```ctrl + x```　選択範囲を切り取り
- ```ctrl + bk```　カーソル位置より左側の単語を削除
- ```ctrl + del```　カーソル位置より右側の単語を削除

## 選択系
- ```ctrl + l```　```Ctrl```を押したまま```l```連打で複数行を選択
- ```shift +　ctrl + ↑/↓/←/→```　単語単位でカーソル移動しつつ選択
- ```ctrl + d```　単語選択(同単語を一気に編集することが可能)
- ```ctrl + shift + l```　一致するすべての出現箇所を選択

## 移動系
- ```ctrl  + home/end```　ファイルの先頭/末尾に移動
- ```home/end```　行の先頭/末尾にカーソル移動　
- ```alt + z```　折り返しする/しないの切り替え  
-```ctrl + ←/→```　単語の先頭に移動
- ```ctrl + ↑/↓```　カーソル位置はそのままに上下にスクロール
- ```ctrl + pgup/pgdn```　エディタのフォーカス左右移動
- ```ctrl + shift + pgup/pgdn```　エディタ全体を左右に移動
- ```ctrl + g ```　指定した行に移動
- ```alt + ←/→ ```　自分がいたカーソル位置の履歴に移動

## 開く/閉じる系
- ```ctrl + n ```　新規にエディタを開く
- ```ctrl + w ```　開いたエディタを閉じる
- ```ctrl + shift + t```　閉じたエディタを再び開く　
- ```ctrl + shift + n```　新規にウィンドウを開く
- ```ctrl + shift + w```　開いたウィンドウを閉じる　
- ```ctrl + k w```　エディタグループ内をすべて閉じる
- ```ctrl + shift + [``` 指定範囲の折りたたみ
- ```ctrl + shift + ]``` 指定範囲の展開
- ```ctrl + k + ctrl + 0``` すべて折りたたみ
- ```ctrl + k + ctrl + j``` すべて展開
- ```ctrl + @``` ターミナルを展開
- ```ctrl + shift + @``` 新しいターミナルを展開

## 終わりに
業務中に主に使うであろう基本的なショートカットキーを整理してみました。  
調べてみるとまだまだ自分が知らないショートカットキーが沢山あるだなという実感と  
作業スピード上げられるようにこれからも覚える作業をやっていきたいと思います。
また、見つけた便利なショートカットがあれば紹介していこうと思います。