OmniAICreator/Qiita-1.07M huggingface dataset:
自分用 通知の設定方法(taipii)

通知の設定方法
Androidアプリ内で通知を送信する方法を詳しく説明します。通知を送信するためには、通知チャンネルの設定などいくつかのステップが必要です。

1. **通知チャンネルの作成（オプション）**:
   Android 8.0（API レベル 26）以降では、通知を送信する前に通知チャンネルを作成することが推奨されています。通知チャンネルは通知をカテゴリ別に管理し、ユーザーに通知の重要度を示します。

   ```kotlin
   // 通知チャンネルを作成する
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
       val channelId = "my_channel_id"
       val channelName = "My Channel"
       val importance = NotificationManager.IMPORTANCE_DEFAULT
       val channelDescription = "My Notification Channel"
       val channel = NotificationChannel(channelId, channelName, importance).apply {
           description = channelDescription
       }
       val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
       notificationManager.createNotificationChannel(channel)
   }
   ```

2. **通知の作成**:
   通知を作成し、通知のタイトル、メッセージ、アイコン、通知チャンネルなどを設定します。

   ```kotlin
   val notificationBuilder = NotificationCompat.Builder(this, "my_channel_id")
       .setSmallIcon(R.drawable.notification_icon)
       .setContentTitle("新しいメッセージ")
       .setContentText("新しいメッセージが届きました")
       .setPriority(NotificationCompat.PRIORITY_DEFAULT)
   ```

3. **通知の送信**:
   作成した通知を通知マネージャーを使用して送信します。

   ```kotlin
   val notificationId = 1 // 通知の一意なID
   with(NotificationManagerCompat.from(this)) {
       notify(notificationId, notificationBuilder.build())
   }
   ```

これにより、通知がステータスバーに表示されます。ユーザーが通知をタップすると、通知を選択したアクションがトリガーされたり、詳細情報が表示されたりします。

4. **通知アイコンの設定**:
   通知アイコンは `setSmallIcon()` メソッドを使用して指定します。通知アイコンはアプリのリソース内に存在する必要があります。

以上の手順に従うことで、Androidアプリ内で通知を送信できます。通知の詳細な設定やユーザーインタラクションのサポートも可能です。通知はアプリのユーザーエクスペリエンスを向上させ、ユーザーに重要な情報を提供するのに役立ちます。
JavaScriptの非同期処理の変遷 ①  コールバック関数の登場とその課題

▼参考文献

https://gihyo.jp/magazine/SD/archive/2023/202309

Software Design 2023年9月号の中で非同期処理について詳しく解説されていて大変参考になったので、本記事を通じて学んだことを整理しています。


## 非同期処理はなぜ重要？
:::note
現代のWebページにおいて、処理を効率的に行い、良いユーザー体験を作るには非同期処理が重要。

特にWebAPIからのデータ取得といった時間のかかるタスクを同期処理で行うと、ユーザー体験に悪影響を与える。
:::

非同期処理が重要になった背景には、Webページの進化が関係しています。
### 90年代のWebページ
当時のWebページは静的で、ブラウザの仕事はHTMLを表示するだけで、ユーザーとの相互作用はサーバサイドが担っていた。

### JavaScriptの登場
1995年のJavaScriptの登場により大きく変化。JavaScriptはブラウザ向けに開発された言語で、ユーザーがWebページと動的に相互作用できる強力な特徴を持っている。

### クライアントサイドアプリケーションの複雑化
JavaScriptを用いたWebページは、入力のバリデーションを行うような単純なものから始まり、GmailやGoogle Mapsに代表される複雑なWebアプリケーションというジャンルに反転した。
最近はWebAPIからのデータ取得、ユーザー入力の処理、画面描画などありとあらゆる処理をクライアントサイドで行うことを前提としたアプリケーションも一般的になっている。


ここで効率的なタスク処理が重要になってくる。特にWebAPIからのデータ取得といった時間のかかるタスクを同期処理で行ってしまうと、ユーザーインターフェースのタスクが停止することもあり、ユーザー体験に悪影響を与える。

そこで非同期処理が重要になってくる。

## そもそも同期処理と非同期処理の違いは？
:::note
同期処理と非同期処理は、タスクがどのように実行されるかを指す言葉
:::

|同期処理|非同期処理|
|:-|:-|
|タスクを直列に実行|タスクを並行に実行|
|タスクを一つ一つ順番に実行する|複数のタスクを同時に実行する|


### 同期処理の問題点
待ち時間（ブロッキング）を有効活用できないこと。待ちの間は、コンピュータの計算資源が有効活用できないため、パフォーマンスの問題に繋がる。待ちの間に実行できない処理の中にはユーザーと相互作用するUIの処理も含まれるためユーザー体験の悪化にも繋がる。

### 非同期処理が解決してくれること
非同期処理はノンブロッキングであるため、待ち時間に計算資源を有効活用でき、UIの処理も並行して実行できるため、ユーザー体験を損なわずに済む。

## 非同期処理を実現するために用いられたコールバック関数
:::note
コールバック関数とは、他の関数に引数として渡される関数で、特定のイベントで実行される。特定のイベントで実行したいタスクを関数に書いておき、その関数をコールバック関数として渡すことで、非同期処理を実現できる。
:::

登場人物が多いので整理、、、
`コールバック関数`：他の関数に引数として渡される関数。特定のイベントの際に実行したいタスクを書く。
`コールバック関数が渡される関数`:何らかのタイミングで非同期的にタスクを実行するためのトリガー。


これにより、コールバック関数が設定されれば、、、
* コールバック関数の完了を待つことなく他の処理を進めることができ、
* 特定のタイミングにコールバック関数が実行されるという流れになる。

以上の流れにより、待ち時間を有効活用することで全体的なプログラムのパフォーマンスを向上させることができる。

## コールバック関数の問題


### コールバック地獄 callback hell
:::note
コールバック関数により、非同期処理が実現できるようになったが、新たな問題も発生。
多くの非同期処理を連続して行う場合、コールバック関数が入れ子状になり、可読性が低下する。この問題をコールバック地獄という。
:::

以下がコールバック関数の具体例です。

処理内容：特定の投稿、その投稿者、その投稿者が属する組織を順に取得する非同期処理

1. まず`getPost`関数が非同期で投稿を取得する
1. その投稿は`post`としてコールバック関数にわたる
1. そのコールバック関数内で、`post`から`userId`を取り出し`getUser`関数に渡す
1. `getUser`関数も非同期的に投稿者を取得し、それが次のコールバック関数に渡る
1. 同様に`getOrganization`関数も非同期に組織を取得する
```javascript
getPost(postId, (post) => {
    getUser(post.userId, (user) => {
        getOrganization(user.orgId, (org) => {
            // さらにコードがネストされて読みにくくなる
        });
    });
});
```
上記のように、非同期関数の処理結果を連鎖して扱う必要が出てくるとネストが深くなり、コールバック関数が生じる。現実はさらにさまざまなロジックや条件分岐が入ってくるため可読性はますます悪くなる。

### 不統一なコールバックAPI
:::note
どのようなAPIであれ、一貫したパターンの方が開発者が各APIを個別に理解する必要がないため利便性が高くなる。

しかし当初コールバック関数APIには標準的なパターンがなく、各APIは独自のパターンを持っていた.
:::

コールバックAPIが不統一なことから、
「開発者は各APIごとにコールバックパターンを正しく理解する」必要があり、
実装の障壁となったり、コールバック地獄をさらに複雑化させたりする要因になっていた。


:::note
コールバック地獄や不統一なコールバックAPIなどの問題を解消する方法の1つとして、Promieやasync/awaitが登場する。
これらを利用することで、非同期処理のコードがより読みやすく理解しやすくなっていく。
:::


---

https://qiita.com/yusuke2310/items/134b8484d3e0cb0b8d14

https://qiita.com/yusuke2310/items/b2dbe85c966bb14268eb
MacBook環境でOpenStreetMapを動かすだけの備忘録

# 環境
Mac(OS Monterey ver.12.5.1), Apple M1, memory32GB

# OpenStreetMapとは

https://www.openstreetmap.org/
https://openstreetmap.jp/
> OpenStreetMap(OSM)は、誰でも自由に地図を使えるよう、みんなでオープンデータの地理情報を作るプロジェクトです。
> プロジェクトには、誰でも自由に参加して、誰でも自由に地図を編集して、誰でも自由に地図を利用することが出来ます

# 準備

こちらの記事を参考にローカルPCで動かさせて頂くだけの記事です
anacondaではなく、アプリケーション-->ユーティリティ-->ターミナルから開きます

> https://qiita.com/nujust/items/63387a51d3f2379d3433

事前にインストール

```
pip3 install cartopy
pip3 install contextily
```

# 実行

以下記事を参考に実行する
以下記事では東京駅（の緯度経度）に、赤い丸をプロットしている。

> https://qiita.com/nujust/items/63387a51d3f2379d3433

(以下を参考に日本語をMeiryoで表示したかったが今回は実行優先した）

> https://www.kimoton.com/entry/20201115/1605426414

```
python3 test.py
```

>```py:test.py
>import cartopy.crs as ccrs
>import contextily as cx
>import matplotlib.pyplot as plt
>import pyproj
>from matplotlib.offsetbox import AnchoredText
>
>
>def main():
>    # 日本語フォントの設定
>#    plt.rcParams["font.family"] = "ボールド・イタリック" #"Meiryo"
>
>    # 対象地域の適当な座標系を設定
>    crs = ccrs.epsg(6677)  # 平面直角座標系 9系(JGD2011)
>
>    # 座標系に対応したオブジェクト
>    fig = plt.figure(figsize=(8, 8))  # 実際の出力サイズは描画領域で決まるため、ここでは最大サイズとして指定。
>    ax = fig.add_subplot(1, 1, 1, projection=crs)  # projectionへのcrsの指定により地理空間に投影
>
>    # 描画領域の設定（東京駅周辺の座標を確認して入力）
>    ax.set_xlim(-8000.0, -4000.0)
>    ax.set_ylim(-37000.0, -34000.0)
>
>    # ベースマップ(OpenStreetMap)の追加
>    cx.add_basemap(ax, crs=crs, zoom=16, source="http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png")
>
>    # 図形(ポイント)の描画
>    lat, lon = 35.6810912, 139.7671861  # 東京駅の緯度経度
>    transformer = pyproj.Transformer.from_crs("EPSG:4326", crs)
>    y, x = transformer.transform(lat, lon)
>    plt.scatter(x, y, s=200, c="red", alpha=0.5, label="Tokyo Station")
>
>    # 凡例の描画
>    ax.legend(loc="upper right", prop={"size": 20})
>
>    # OpenStreetMapのクレジットを右下隅に表示
>    text_box = AnchoredText("© OpenStreetMap contributors", loc="lower right", borderpad=0, frameon=True)
>    plt.setp(text_box.patch, facecolor="white", alpha=0.6, linewidth=0)
>    ax.add_artist(text_box)
>
>    # プロットエリアの枠を非表示
>    ax.set_axis_off()
>
>    # プロットエリア以外の部分をなくし、地図部分のみをファイルに出力
>    fig.tight_layout(pad=0)
>    fig.savefig("output.png", bbox_inches="tight", pad_inches=0)
>if __name__ == "__main__":
>    main()
>```

実行結果(output.png)
![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/dc2deb78-a3f7-d08e-9547-ec394cc25e3e.png)


# 参考

https://www.kimoton.com/entry/20201115/1605426414

https://www.openstreetmap.org/

https://openstreetmap.jp/
Phoenixにおけるページレンダリング順についてのメモ

- [Phoenixにおけるページレンダリング順について](#phoenixにおけるページレンダリング順について)
  - [レイアウトの設定](#レイアウトの設定)
  - [アプリレイアウトの変更](#アプリレイアウトの変更)
  - [どんなときに新たなアプリレイアウトを作成するか](#どんなときに新たなアプリレイアウトを作成するか)

# Phoenixにおけるページレンダリング順について

ページを表示する際、以下の順序に関連するファイルが読み込まれる。

1. `root.html.heex`を読み込む
2. `app.html.heex`を読み込む
3. テンプレートが読み込まれる。

読み込まれるファイルの種類には次のようなものである。

* **ルートレイアウト** - <font color="red">すべてのテンプレート</font>でレンダリングされるレイアウトのこと。`root.html.heex`を指す。
* **アプリレイアウト** - ルートレイアウト内でレンダリングされるレイアウトのこと。デフォルトでは`app.html.heex`を指す。
* テンプレート - コントローラのアクションやLiveViewモジュールで読み込むheexファイル

## レイアウトの設定

Phoenixプロジェクトを生成すると、`/components/layouts.ex`というファイルが生成されている。

この**モジュール**と**同名のディレクトリ**はルートレイアウトとアプリレイアウトの構成を設定している。

## アプリレイアウトの変更

デフォルトではlayouts/のapp.htmlが呼び出される。

また表示するアプリレイアウトを指定することで、<font color="red">**別のheexを読み込むように指定する**</font>こともできる。

Controllerのアクションに以下のように記述して、アプリレイアウトを変更することができる。

```elixir
render(conn, :テンプレート, layout: {省略Web.Layouts, :アプリレイアウト})
```

LiveViewでは`mount()`に以下の例のように記述して、アプリレイアウトを変更することができる。

```elixir
def mount(_params, _session, socket) do
  ...
  # アプリレイアウトにtuto.html.heexが読み込まれる
  {:ok, socket, layout: {TutoWeb.Layouts, :tuto}}
end
```

なお`layout: false`と記述するとアプリレイアウトを**無効化**することができる。

この場合、`root.html.heex`の`@inner_content`内にテンプレートが読み込まれる。

## どんなときに新たなアプリレイアウトを作成するか

`app.html.heex`はControllerのアクション読み込む場合、LiveViewから読み込まれる場合があるとする。
`app.html.heex`でLiveComponentの呼び出しを記述すると、**ViewモジュールではLiveComponentを呼び出せないため**読み込むことができなくなる。

そのためLiveView用のアプリレイアウトを作成し、LiveComponentを呼び出す。
それから、`mount()`にアプリレイアウト指定すると良いと思う。
組み合わせの数とパターンの列挙

## 組み合わせ nCi　 の列挙

gtools にはあるが，パッケージをインストールしなくても，Base には combn() がある。行と列が転置されている関係があるが，　combn() は得られる組み合わせにおいて関数を適用することができる。

```R
> library(gtools)
> committees = gtools::combinations(n=5,r=3)
> committees
      [,1] [,2] [,3]
 [1,]    1    2    3
 [2,]    1    2    4
 [3,]    1    2    5
 [4,]    1    3    4
 [5,]    1    3    5
 [6,]    1    4    5
 [7,]    2    3    4
 [8,]    2    3    5
 [9,]    2    4    5
[10,]    3    4    5

> combn(5, 3)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    1    1    1    1    1    1    2    2    2     3
[2,]    2    2    2    3    3    4    3    3    4     4
[3,]    3    4    5    4    5    5    4    5    5     5
> # combn(x, m, FUN = NULL, simplify = TRUE, ...) 
```

## 組み合わせの数

定義により計算する必要はなく，Base には choose() がある（速い）。

```R
> factorial(5)/(factorial(3)*factorial(2))
[1] 10
> choose(5, 3)
[1] 10
```
【Ruby】初心者のためのattr_reader、attr_writer、attr_accessor


# はじめに
この記事では`attr_reader`、`attr_writer`、`attr_accessor`を使用してインスタンス変数へのアクセス方法を説明し、コードを簡潔にする方法を紹介します。

# attr_reader, attr_writer
Rubyのオブジェクト指向プログラミングでは、インスタンス変数へのアクセス方法が重要です。Rubyのオブジェクトメソッドは基本的に公開されていますが、データ（インスタンス変数）はプライベートです。つまり、インスタンス変数には直接アクセスできず、メソッドを通してのみアクセスできます。

例えば、次のRubyクラスを考えてみましょう：

```ruby
class Person
  def initialize(name)
    @name = name
  end
end

person = Person.new("John")
puts person.@name # エラー！
```

インスタンス変数`@name`に直接アクセスしようとすると、エラーが発生します。そのため、外部からインスタンス変数にアクセスできるようにするには、ゲッターメソッド（getter）とセッターメソッド（setter）を定義する必要があります。ゲッターメソッドはインスタンス変数の値を読み取るためのメソッドであり、セッターメソッドは新しい値を割り当てるためのメソッドです。

```ruby
class Person
  def initialize(name)
    @name = name
  end

  # ゲッター(getter)メソッド
  def name
    @name
  end

  # セッター(setter)メソッド
  def name=(name)
    @name = name
  end
end

person = Person.new("John")
puts person.name # "John"
person.name = "Brian"
puts person.name # "Brian"
```

これで、`name`インスタンス変数の値を読み取り、変更できるようになります。しかし、各インスタンス変数に対してこれらのメソッドを定義することは冗長になることがあります。これを簡略化するために、Rubyでは`attr_reader`と`attr_writer`が提供されています。

```ruby
class Person
  # attr_readerを使用してnameのゲッターメソッドを生成
  attr_reader :name

  # attr_writerを使用してnameのセッターメソッドを生成
  attr_writer :name

  def initialize(name)
    @name = name
  end
end

person = Person.new("John")
puts person.name # "John"
person.name = "Brian"
puts person.name # "Brian"
```

これにより、`attr_reader`は`name`のゲッターメソッドを生成し、`attr_writer`は`name`のセッターメソッドを生成します。これらのメソッドを使用してインスタンス変数の値を読み取り、設定できます。

# attr_accessor
`attr_accessor`メソッドはゲッターを生成する`attr_reader`メソッドとセッターを生成する`attr_writer`メソッドを1つのメソッドに結合したメソッドです。 このメソッドを使用する場合には、あえて`attr_reader`、`attr_writer`をそれぞれ定義する必要はありません。`attr_accessor`を使用すると、コードがより簡潔になります。

```ruby
class Person
  # attr_accessorを使用してnameのゲッターとセッターメソッドを生成
  attr_accessor :name

  def initialize(name)
    @name = name
  end
end

person = Person.new("John")
puts person.name # "John"
person.name = "Brian"
puts person.name # "Brian"
```

# 参考
https://www.rubyguides.com/2018/11/attr_accessor/
Qiitaをオススメする記事をQiitaで書いてみる

# Qiitaをオススメする理由

## 実はエンジニアだけでなく、デザイナも使っているQiita
自社でQiitaをオススメしたくてまとめていたが、簡単に１ページでまとまった記事がないなーとググってましたが、前置きが長かったりして、サクッとまとまった記事がなかったので、作ってみました。QiitaにQiitaをおすすめする内容です。


### 1.技術情報の共有とアウトプットの場所

Qiitaは開発者が技術的な知識や経験をシェアし、アウトプットするための理想的な場所。
プログラミングに関するTips、ノウハウ、メモを簡単に記録し、他の開発者と共有可能。


### 2.豊富なカテゴリーとコミュニティ
Qiitaには多くの技術関連カテゴリーがあり、さまざまなトピックに関する記事が投稿可能。また、Qiitaユーザーコミュニティが存在し、他のエンジニアと交流し、新しい知識を得る機会を提供。

### 3.Qiita Team
Qiita Teamは組織内での閉じた情報共有が可能（けっこう高い）。企業やチーム単位でQiitaを利用し、プロジェクトに役立つ情報を共有できる。


### 4.ランキングとモチベーション
Qiitaの記事は閲覧数やいいね数によってランキングされる。ランキング上位に表示されることで、執筆者はモチベーションを高めれる。

### 5.編集しやすいマークダウン形式
Qiitaはマークダウン形式で記事を編集でき、シンプルかつ美しい記事を作成できます。これは技術情報をわかりやすく表現するのに！

### 6.Google Analyticsで分析できる
https://help.qiita.com/ja/articles/qiita-google-analytics



### 7.デザイナー向け記事とコミュニティもある
Qiitaにはデザインに関する記事や情報が豊富にあり、デザイナー向けのコンテンツも充実している。デザイナー向けタグやコミュニティが存在し、デザインに関するトレンドやベストプラクティスについて学び、共有可能。

### 8.デザインシステムとUI/UX
QiitaにはデザインシステムやUI/UXに関する情報も提供されており、デザイナーは最新のデザイントレンドやデジタルプロダクトのデザインシステムについて知識を深めることができる。


### 9. デザインガイドライン
Qiitaにはデザインガイドラインに関する記事もあり、デザイナーがデザインの基準やガイドラインを共有できる。
Ubuntu 22.03 + nvidia Cuda with Docker インストールメモ

以下を参考にしました。

https://takayama-rado.com/articles/update_nvidia_0.html

https://qiita.com/ketaro-m/items/4de2bd3101bcb6a6b668

https://zenn.dev/naga3/articles/0c2f4c284fe5d4

https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&Distribution=Ubuntu&target_version=22.04&target_type=deb_network

https://github.com/NVIDIA/nvidia-docker/issues/1766

https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html

ポイントは
- カーネルが変わっていないか？(generalがoracleに。。。とか、genericを入れてもgrubで元のoracleが上がってとか）
- 再起動はしているか
です。

あとDockerで
docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]]
とでる場合の私のワークアラウンドは

1. sudo apt remove docker-ce docker-ce-cli containerd.io
2. sudo reboot
3. sudo apt install docker-ce docker-ce-cli containerd.io

です。
複数の Root#render() 間で状態を共有する

かなりのレアケースではありますが、例えば [React を使った Web Components のカスタム要素](https://ja.legacy.reactjs.org/docs/web-components.html#using-react-in-your-web-components)を複数定義する場合などで、 `Root#render()` を複数回呼び出すことがあります。

```tsx:src/index.tsx
import { createRoot } from "react-dom/client";
import { App } from "./App";
import { Button } from "./Button";

class MyButton extends HTMLElement {
  connectedCallback() {
    const shadow = this.attachShadow({ mode: "closed" });
    const root = createRoot(shadow);
    root.render(<Button />);
  }
}

class MyApp extends HTMLElement {
  connectedCallback() {
    const shadow = this.attachShadow({ mode: "closed" });
    const root = createRoot(shadow);
    root.render(<App />);
  }
}

customElements.define("my-button", MyButton);
customElements.define("my-app", MyApp);

```

また更にレアケースですが、このカスタム要素間で状態を共有したい場合があります。
当然ながら React 自体に `Root#render()` 間を跨いで状態を共有する方法はありませんが、React の外側で確保したメモリをポーリングするすることでそれっぽいことができます。

```typescript:src/utils/str.ts
export let str = "aaa";

export function setStr(s: string) {
  str = s;
}
```

```tsx:src/Button.tsx
import { setStr } from "./utils/str";

export function Button() {
  return (
    <button
      onClick={() => {
        setStr("bbb");
      }}
    >
      set "bbb"
    </button>
  );
}

```

```tsx:src/App.tsx
import { useEffect, useState } from "react";
import { str } from "./utils/str";

export function App() {
  const [text, setText] = useState(str);

  useEffect(() => {
    const id = setInterval(() => {
      if (str !== text) {
        setText(str);
      }
    }, 1000);

    return () => {
      clearInterval(id);
    };
  }, []);

  return <span>テキスト: {text}</span>;
}

```

ボタンをクリックすると、少し遅れてテキストが `bbb` に変わります。

![動作.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138531/85c27c66-58bd-2ad4-f503-a50a4a0258a4.gif)

こんな怪しいアイデアが役に立って欲しくはありませんが、もし何かの刺激になれば幸いです。
今回紹介したコードは[こちらのリポジトリ](https://github.com/hey-cube/react-polling-state)にもプッシュしているので、興味のある方は覗いてみてください。
（もっと良いやり方をご存知の方がいれば、コメントにてお教えください。）
【お名前.com】ドメインを取得してみた

## はじめに
気温も肌寒くなり部屋の中でも半袖で過ごすにはキツくなってきたこの頃、エンジニアが休日することと言ったら何でしょうか？

そうです、個人開発ですね。（←最近始めたばかり）

僕は個人開発をするにしても、「ローカル環境で動いたらまぁ完成でいっか、、(^q^)」と思っていたのですがふと恐ろしいことに気づきました。

**あれ、僕って用意されたインフラがなければ自分が作ったものを公開する方法わかんないな、、、**

普段業務ではフルスタックエンジニアとして働いていてAWSを触ったりもするのですが、自分でAWSアカウントを作ったこともなければ、ドメイン回りの設定もしたことない、、、
名ばかりのフルスタック（笑）エンジニアでした。

エンジニアの皆さんも自分が作ったサイト・webアプリがネットで閲覧できるようになる流れは知識として知っていても、実際に0から構築～公開まで作業したことがあるという方は少ないのではないでしょうか。

そのため今回はまず第一歩として**自分用のドメインの取得**をしてみようと思います！

## お名前.comとは
ドメインが取得できるサービスです。
サイトのトップページにでかでかと「登録実績3,000万件突破！国内シェアNo.1の格安ドメイン登録サービス」書かれていました。

▼お名前.comサイト
https://www.onamae.com/

ドメイン取得するには～などで検索するとトップでヒットしますし、ちらほら名前も聞いたことありますのでこちらでドメインを取得しようと思います。


## 取得手順

### ドメインを考える
取得したいドメインを考えます。Qiitaなら「qiita.com」となってますね。
ここは自分が公開するものに対してわかりやすい名前を付けてあげるといいかと思います。


### お名前comサイトにアクセス
![スクリーンショット 2023-10-22 174955.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577451/fb75f7c5-8c55-3d33-fa97-d72da1520d5a.png)

[お名前.comサイト](https://www.onamae.com/)にアクセスし、上で考えた取得したいドメインを検索してみます。


### トップレベルドメインを考える

![スクリーンショット 2023-10-22 175718.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577451/2082f3e7-f0d1-ede0-bb16-b596b52b8cfc.png)

トップレベルドメイン（末尾につく.comや.jpなどの文字列）を何にするか選択する必要があります。
ものによって金額が変わってくるので慎重に選択しましょう。
「.com」が無料だったのでそれを選択して料金確認へ進みます。（無料ってすごい！）


### 会員情報の登録
僕の場合は今回初めての利用なので会員登録をしていきます。

![スクリーンショット 2023-10-22 180449.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577451/1e661116-783d-1674-5b13-1621e1f1269b.png)


諸々の情報を入力したらクレジットカードを登録する画面に移りますのでカード情報も登録します。

情報を入力したら申し込みが完了してお名前.comさんからメールが届きます。

![スクリーンショット 2023-10-22 220512.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577451/17fd0112-ba99-7c6c-e54d-a40198640d0e.png)

※**「WHOIS情報公開代行」について**
取得するドメインを選択して料金確認をする画面で、WHOIS情報公開代行を利用するかオプションで選択できる箇所があるかと思います。
ドメインを取得したらドメイン取得者の個人情報がネット上に公開されるらしいのですが、「WHOIS情報公開代行」はネットに公開する個人情報を肩代わりしてくれるサービスらしいです。
以下の記事がわかりやすかったです↓
https://unzip.co.jp/homepage/blog/hp_knowledge/351/

僕がドメイン取得した時は初年度無料だったので「WHOIS情報公開代行」もオプションで付けました。
オプション付けるかどうかは自由ですが、どんなサービスかは認識しておいた方がよいかと思います！


## ドメインの認証について

「【重要】[お名前.com] ドメイン 情報認証のお願い」という件名でお名前.comさんからメールが届いています。
ドメイン登録者情報のメールアドレスとして登録した情報が正しいか検証するために、メール本文に記載のあるURLをクリックして認証を完了させるのを忘れないようにしましょう。
**期日が2週間**とのことなので忘れないように注意しましょう、、、！
※忘れると該当ドメインを利用したホームページの閲覧やメールの送受信ができなくなるそうです( ;∀;)


## ドメインを登録できているか確認してみる
IDはメールで届いているはずなのでお名前.comにログインしてドメインの確認をしてみましょう！

![スクリーンショット 2023-10-22 221435.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577451/0ecde41d-4a9d-a4c7-0f81-c7bcdb59a84d.png)


おー！登録されてる！！

## この後

これでドメインは取得できました。
この後はDNSレコードの設定をして、IPアドレスとドメインを紐づける作業が必要になってくるはずです
ここら辺はまた勉強しながら別の記事で投稿する予定ですのでまたしばらくお待ちください。（サーバはAWSで構築する予定です）


### 追記
後日**ドメインプロテクション**なるものを選択するように迫られたので追記いたします。
ドメインプロテクションとはなんぞやと調べてみたところ、「ドメインを第三者に悪用されないようにする（簡潔）」機能らしいです。
こちらの記事が詳しかったです↓
https://www.plust.jp/column/domain-protection/

ドメインプロテクションをつけるか考える時はノリで付けない選択をするのではなく、自分のドメインに対しての必要性を調べて判断した方がよいかと思います！
特定のサービスを再起動し、起動に失敗したときにログを表示させる


||コマンド|
|---|---|
|再起動 | systemctl restart docker.service|
|ステータスの表示 | status docker.service|
|ジャーナルログの表示 | journalctl -xeu docker.service|

root権限でつなげる。


```bash
# systemctl restart docker.service || ( systemctl status docker.service | cat ; journalctl -xeu docker.service | cat )
```

sudo化してサービス名を変数化する

```bash
$ S=docker.service; \
sudo systemctl restart isuports.service ; \
(sleep 1 ; sudo systemctl status $S | cat ; sudo journalctl -xeu $S | cat )
```
ChatGPT+PaLM+Claudeを使った合議制システムReConcileを試してみる

# ReConcile（俗称MAGIシステム？）を試す

最近話題になった複数のLLMを使った俗称MAGIシステムを使ってみたので構築手順まとめ

生成AIが一般に注目され始めたあたりから、MAGIシステム的な活用方法はいろいろな人が試しているが、決定的に興味を持ったのはソフトバンクグループ孫会長のこのプレゼン
[AIは「AGI」へと進化し、今後10年で全人類の叡智の10倍を超える](https://www.softbank.jp/biz/blog/business/articles/202310/sbw2023-softbank-son-main-keynote/)

> GPTの中 にキャラクターをいくつか作って、キャラクター同士でディベートさして、僕が審判役で見ながら時々ちゃちゃを入れるというやり方で議論がガンガン進んでいく

YouTubeにも動画があがっているようなので、興味がある方はご覧あれ
[【ロングバージョン】ＡＩを世界一活用する企業に　ソフトバンクＧの孫氏が講演](https://www.youtube.com/watch?v=Gh0xzbgCIgg)

ちょうどこんなリリースを見た後だったので、実際どうなのか試してみた流れ（・・・そしてまだ結論には至っていない）
[GPT-4、Bard、Claude2などの異なるLLMが円卓を囲み議論した結果の回答は品質が高いとの検証報告。円卓ツールも公開](https://aiboom.net/archives/55853?fbclid=IwAR18HuId__1derRlF0BsRrNxIzJ_uIWZ_GBfYvrTV7U7CCkbwL_MJW0z6xM)

引用元の論文にも記載があるが、[こちらのレポジトリ](https://github.com/dinobby/ReConcile)で公開されているので便利。早速セットアップしてみる

```
git clone https://github.com/dinobby/ReConcile.git
```
git環境がセットアップされていない場合は、事前にgitをインストールしておく
```
sudo apt-get install git
```

インストールフォルダに移動して、pipでインストールできる
```
sudo pip install -r ./requirements.txt
```

:::note warn
Windows環境では、インストール時にC++ extentionをコンパイルするために、Microsoft Visual C++ 14.0 またはそれ以上のバージョンが必要になるようなので留意
環境によっては下記のインストールが必要となりそう
[Microsoft C++ Build Tools](https://visualstudio.microsoft.com/ja/visual-cpp-build-tools/)
::: 

git clone したReconcileのルートディレクトリに、以下の内容で.envファイルを作成する
```
OPEN_AI_API_BASE = "..."
OPEN_AI_API_VERSION = "..." 
OPEN_AI_API_KEY = "..."
PALM_API_KEY = "..."
CLAUDE_COOCKIE1 = "..."
CLAUDE_COOCKIE2 = "..."
CLAUDE_COOCKIE3 = "..."
CLAUDE_COOCKIE4 = "..."
CLAUDE_COOCKIE5 = "..."
```
OpenAI APIとPALM APIにアクセスするためにAPIキーをここに設定する

Claudeからは非公式Claude-APIを使って結果を取得する仕組みらしい
CLAUDE_COOKIESには、Chromeなどブラウザの開発ツールなどで参照できるCookie値を取得してセットする

5つまで設定できて、制限に達したら5つまで順次使うような仕様に思えるが、そんなDOSアタックようなことして大丈夫なのか。いつかバンされそうなので、用途にあわせて修正したほうが良いのかもしれない。。

参考: [Getting started with Claude](https://docs.anthropic.com/claude/docs)
参考: [Claude-API](https://github.com/KoushikNavuluri/Claude-API)

以下のコマンドで実行できる
```
python run.py --num_samples 100 --dataset SQA
```

--num_samplesは生成するサンプル数を指定、--datasetは使用するデータセットを指定する。現在、データセットとして[“SQA”, “GSM8k”, “ECQA”, “AQuA”]が選択できる

データセットはdatasetフォルダに含まれていて、それぞれのデータセットは以下のソースから取得される

StrategyQA: https://github.com/eladsegal/strategyqa
ECQA: https://github.com/IBM/ecqa
GSM8K: https://github.com/openai/grade-school-math
AQuA: https://github.com/google-deepmind/AQuA

システムの出力はoutputフォルダに保存される。出力ファイルには、質問、正解、生成された回答などの情報が含まれる。

::: note
システムの詳細な仕組みや評価については、以下の論文を参照との事

@article{chen2023reconcile,
  title={ReConcile: Round-Table Conference Improves Reasoning via Consensus Among Diverse LLMs},
  author={Chen, Justin Chih-Yao and Saha, Swarnadeep and Bansal, Mohit},
  journal={arXiv preprint arXiv:2309.13007},
  year={2023}
}

参考: [ReConcile: Round-Table Conference Improves Reasoning via Consensus among Diverse LLMs](https://arxiv.org/abs/2309.13007)
:::

# 参考文献：
- [GPT-4、Bard、Claude2などの異なるLLMが円卓を囲み議論した結果の回答は品質が高いとの検証報告。円卓ツールも公開](https://aiboom.net/archives/55853?fbclid=IwAR18HuId__1derRlF0BsRrNxIzJ_uIWZ_GBfYvrTV7U7CCkbwL_MJW0z6xM)


2023年10月時点
【退職エントリ】中途だけどポートフォリオ作ったうえで転職活動した話

[株式会社リンクバル](https://qiita.com/organizations/linkbal)で記事を投稿させていただいておりましたLaineusです！

このたび6年務めた同社を退職して久しぶりの転職活動をしましたので、その話を書こうと思います。

# 転職の背景

リンクバルでは、マッチングアプリ『[CoupLink](https://couplink.jp)』の開発チームで、Webフロントエンド/サーバーサイドを担当しておりました。

開発以外には、同開発チームのマネージャーの役割をいただき、チームマネジメントやメンバー育成などをやっておりました。

チームメンバーは、採用時から携わった新卒メンバー中心に構成されていたのですが、全員が優秀で非常に成長が早かったです。

僕は実装が好きなのでプレイング比率が高いマネージャーでしたが、
メンバーの成長によって、最後の1年は僕の開発タスクは大幅に減っていました。

その後、自分のチームのメンバーの一人が晴れてリーダーになったタイミングに合わせて、
バトンを渡す形で自分は次の会社に挑戦することに決めました。

# ポートフォリオ

完成したポートフォリオはこちらです。

https://portfolio.laineus.com?f=qiita

## なぜ作ったのか

未経験からエンジニアになる場合は、業務実績の代わりにポートフォリオを作る場合が多いようですが、中途エンジニアである僕は以下のような理由で作成しました。

- 「職務経歴書」は、自分がアピールしたいポイントを伝えるうえで適切なフォーマットではない
  - Qiita執筆物や個人開発といった業務外の成果物が多いため
  - 画像や実際のページへのリンクつきで載せたいため
- 面接の口頭のやりとりのみでは、自分がアピールしたいポイントを全て伝えきるのが難しい
- 転職とは関係なく、今までのエンジニアとしての実績をまとめてみたかった

## なにで作ったか

ポートフォリオを簡単に作れるサイトとかもあるようですが、
見せ方を自由にデザインしたかったので、HTML/CSS/JSで書きました。

（もし使いたい方が居りましたら、ソース勝手にぶっこ抜いてOKです）

## 気をつけたこと

- 成果物の列挙にならないこと
- 推したい内容に絞ること

見てもらうと分かる通り、内容量は結構多めになってしまっています。

とはいえ消したページも多く、業務実績は直近の1社分のみですし、個人開発物も3割くらいしか載せておらず、できるだけ見てもらいたいものに絞ってまとめました。

## どのように提出したか

応募の際に自由記述の欄や成果物の欄があればそこにURLを記入しました。

履歴書と職務経歴書の添付欄しかない場合もあるため、職務経歴書の最後のページにもURLを記載しました。

## 選考の結果はどうだったか

理想は「Web系企業フリーパス」として使えるような、最強のポートフォリオを目指して用意してきましたが、結果やいかに―――。

自分から直接応募が4社、
スカウトをもらった中から5社ほど受けました。

|フェーズ|件数|
|---|---|
|最終面接内定✨|2社|
|1～2次面接合格✨（辞退※）|5社|
|1次面接で不合格💥|1社|
|書類選考で不合格💥|1社|

いや落ちるんかーい👆💦

世の中そんなに甘くなく、最強とは程遠い結果となりました。

（※最も志望度の高かった2社から内定をいただいた時点で、この5社は辞退させていただきました。）

## 転職先

株式会社レコチョクへの入社を決めました。

音楽に関するサービスに携われるのがいいなと思ったのが一番惹かれた点ですが、
他にも、色々な細かな条件がマッチしていたためです。

既に先週から入社しているものの、まだ本格的には配属されていないので大した話はありませんが、

リンクバルはSlackのアイコンを自分の写真にする風潮があったので、同じノリでSlackに顔写真を設定したら、誰もそんな人居なくて恥ずかしかったので、ペットのイモリの写真に変えました。

![PXL_20230613_101252030.PORTRAIT.ORIGINAL.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151137/afcbec35-3a05-948e-8276-205beefcb2ab.jpeg)

## 作ってよかったか

よかったと思います。

1～2次面接では面接官が事前にポートフォリオを見てくれている場合が多く、
お互いに情報量が多い状態から面接をスタートでき、効率よく面接を進められたと思います。

また、完成したポートフォリオをあらためて眺めると、やはりこれら全てを既定の書類や面接だけでアピールするのは難しかったと思います。

なので、もしこれを作っていなかったら、不合格になったときに「あの質問のときあれもアピールしていれば受かったかな？」とか後悔していたと思います。

逆に今回不合格になったところは、アピールしたいもの全て伝えられたうえでの不合格なので、これで落ちるなら仕方ない、と受け止められました。

## 最近のWeb系企業の印象

あくまで僕が調べた会社（※）の中での印象です。

※toC系自社サービスを持っている会社かつ会社規模大きめなところを中心に探していました。

- 勤務形態はほぼフレックスor裁量労働制
- リモートは「0日+出社推奨日」や「週1-3日出社日あり」あたりが多い
- React多い・Vueは少数派
- RailsとPHP多い・たまにGo
- 大きい会社は大抵フロントとサーバーサイドで別れている

## おわりに

がんばります🛩
探索

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/c17bbeed-16f2-ad01-ac2a-d0783af25177.png)
　コンピュータを動かすためには、手順を細かく記述しなければなりません。処理の手順のことをアルゴリズムと言います。アルゴリズムには様々な種類がありますが、中でも、データを探すアルゴリズムは、最も基本的で重要なものです。
　データを探すアルゴリズム（探索アルゴリズム）には、線形探索、二分探索、ハッシュ法があります。線形探索は、探す対象範囲がどのような状態でも利用できますが、素早くデータを探すことができません。二分探索は、探す対象範囲が昇順や降順に並んでいる必要がありますが、比較的早くデータを探せます。ハッシュ法は、し早くデータを探せますが、メモリの利用効率が良くないという欠点があります。

１：時間計算量（オーダ）
　時間計算量（単に計算量ということもあります。）は、データ数が増加した場合に、処理時間がどの予定度増加するのかを示す指標です。アルゴリズムの効率の良さを表す指標として使われています。
オーダ記法(O記法)という記法を用いて、O（n）などのように書きます。なお、nは処理するデータの数を表しています。

（良い）　O（１）　O（log n） O(n) O(nlog n) o(n C)　（悪い）

O(１)は、データ数に関係なく処理時間がほぼ一定であることを意味します。
デザインパターン　Commandパターン

# Command パターン
リクエスト、命令、あるいは振る舞いそのものをオブジェクトとして**カプセル化**することでアクションの要求者と実行者を分離するデザインパターン。

コマンドオブジェクトをパラメータとして渡したり、履歴管理したり、逆に取り消したりすることができる。コマンドオブジェクトは **イベント** と呼ばれることもある。

:::note iofo
Commandパターンは **アクションの要求者** と **アクションの実行者** を分離する
:::

# Command パターンの構成要素
![Command.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1069520/d14ab8f2-f622-c3b0-40c5-5a5e4cc8aeb8.png)

## *Command*
命令を `execute()` として定義したインターフェース、もしくは抽象クラス。

```java:Command.java
public interface Command {
    public void execute();
}
```

## ConcreteCommand
`Command`の具象クラス。

`execute()` 内で `Reciever` の アクションを呼び出す（`Receiver` を保持することにより実現）。

:::note info
ConcreteCommand は **Receiver を介して** アクションを実行する
:::

```java:LightOnCommand.java
// Concrete Command
public class LightOnCommand implements Command {

    // Receiver を保持
    Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
    // Receiver の action() を呼び出すだけ
        light.on();
    }
}
```

```java:LightOffCommand.java
// Concrete Command
public class LightOffCommand implements Command {

    // Receiver を保持
    Light light;

    public LightOffCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
    // Receiver の action() を呼び出すだけ
        light.off();
    }
}
```

## Receiver（受信者）
*Command* からアクションの要求を受け取り、**アクションの実装を提供する**。

`ConcreteCommand`によって保持されている。

```java:Light.java
// Receiver
public class Light {

    // action()
    public void on() {
        System.out.println("電気をつける。");
    }

    // action()
    public void off() {
        System.out.println("電気を消す。");
    }
}
```

## Invoker（呼出者）
クライアントに対して**アクション実行のトリガー**を提供する。

アクションの実行が要求されると、 *Command* の `execute()` を実行する。

```java:RemoteControl.java
// リモコン
// Invoker（Client と Command の橋渡し役）
public class RemoteControl {

    // Invoker は Command を保持している
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    // doSomething()
    public void pressButton() {
        // Invoker は Client と Command の橋渡しをするが、
        // 処理の内容や、どの具象クラスの execute() 実行されるか知らない
        command.execute();
    }
}
```

## Client（クライアント）

**アクションの要求者**。

Command パターンによってアクションの実行者と分離されているため、アクションを要求するだけ。アクションの詳細に関与しない。

```java:Main.java
// Client
public class Main {
    public static void main(String[] args) {

        // Receiver のインスタンス化
        Light light = new Light();

        // ConcreteCommand のインスタンス化
        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);

        // Invoker のインスタンス化
        RemoteControl remote = new RemoteControl();

        // Command の設定
        remote.setCommand(lightOn);

        // Invoker にアクションを要求する
        remote.pressButton();
        // >> 電気をつける。

        // Command の設定
        remote.setCommand(lightOff);

        // Invoker にアクションを要求する
        remote.pressButton();
        // >> 電気を消す。
    }
}
```

# 参考
・<a href="https://amzn.asia/d/8MCJXIB" target="_blank" rel="noopener noreferrer">Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本</a>
[初心者向け] 認証時に頻出するCookieとSessionについて徹底解説

## 概要
ログイン認証時に頻出する
- Cookie
- Session

とその関係について解説していきます

## Cookieとは
WEBサイトを閲覧したときに、訪問者が訪れたサイトや入力したデータ、利用環境などの情報をWebブラウザに保存する仕組みのこと
CacheはHTMLなどの静的な情報を一時的に保存する仕組みに対してCookieは後述するSessionIDなどユーザの情報を保存する仕組みなので混同しないようにしましょう

https://qiita.com/shun198/items/59f2d59263930b30d1bd

通常RestAPIを使うとステートレスなやり取りになります
そのため、認証情報を格納してステートフルな状態にするには後述するSessionという概念について理解する必要があります

RestAPIとは何か？ステートレスとは何か？について知りたい方は以下の記事を参考にしてください

https://qiita.com/shun198/items/5cd0870ef95e0fc248bc

## Sessionとは
アクセスの開始から終了までの一連の通信のことです
もっと具体的な話をするとユーザが認証が必要なページにログイン(Sessionを開始)してからログアウト(Sessionを終了)するまでの期間のことを指します
ログイン認証でも説明しますがSessionが開始済み(ログイン済み)かどうかはSessionIDを使って管理するのが一般的です

## 一般的なログイン認証について
CookieとSessionについて説明したのでこの2つを使った一般的なログイン認証について説明します

![session.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/7a821006-8d23-2d15-d6d1-61cd9de6f078.png)

まず、ログイン情報を入力した状態でリクエストします
その際、サーバ側はログイン情報を認証し、該当するユーザが存在するのであればSessionIDを作成し、DBに格納します
(図では便宜上sessionid1などと記載されていますが実際は推測されづらいランダムな値です)
その後、ログイン成功時のレスポンスにSessionIDを返します
SessionIDをブラウザ内のCookieに格納することで認証が必要なリクエストでもステートフルな通信を実現することができます
Cookie内は誰でも見ることができる都合上、ログイン情報はそのまま返さずに一意のSessionIDを使って行うのが一般的です
そのため、SessionIDは推測されないような値にする必要があります

## Cookieの中身を確認しよう
今回は簡単なログイン用のフォームを例に紹介します
ログイン用フォームに社員番号とパスワードを入力し、ログインするとログイン成功画面に遷移します
![スクリーンショット 2023-10-22 20.02.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/1e44b2dd-615e-c0e7-732d-9d32a112bdd0.png)
![スクリーンショット 2023-10-22 15.38.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/e98c7e72-621e-2594-e18b-7aaa993526ba.png)

Cookieの中身はChrome Developer ToolのアプリケーションのCookieから確認できます
ログイン前にCookieを開くと下記のように何も入ってない状態です
![スクリーンショット 2023-10-22 20.05.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/38ae7d17-54eb-e634-f9a0-2505b01ffd75.png)

ログインに成功すると以下のようにSessionIDがCookieに保存されます
![スクリーンショット 2023-10-22 21.15.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/dd03349e-1cde-864b-d358-dc288153e4c6.png)

今回はフレームワークをDjango、DBをPostgresを例に説明していますが、DB上でもセッションIDが格納されていることを確認できます
```
postgres=# \d django_session
 session_key  | character varying(40)    |           | not null | 
 session_data | text                     |           | not null | 
 expire_date  | timestamp with time zone |           | not null | 
postgres=# select * from django_session;
 fjnp91385waomnbjeyrj9d5xv1yghwhu |.eJxtjEsOAiEQRO_CWgm_6UGX7j0DaWiQUQPJfFbGuzskLDSxFpVKql69mMNtzW5b4uwmYmcmuo5_rEuywzfmMTxiaSzdsdwqD7Ws8-R5m_DeLvxaKT4vfftzkHHJjSZAYEkDAqyQfuYRhIBtA0K9iohyFGBMkNKSRjac7RehkErTxI8e38AJ_E-gQ:1quXMh:m_UZbRXoULHFeFe6lyeb52dJw0Cpuq6VxCr8U8eOWCk | 2023-11-05 12:15:31.119386+00
```

## 参考
https://www.engilaboo.com/definitely-understand-cookie-session/

https://yutaro-blog.net/2021/08/27/session-cookie/

https://gmotech.jp/semlabo/webmarketing/blog/cookie/

https://gc-seo.jp/journal/session/
javascriptで日付セレクトボックスを作る

```html:日付チェックボックス
<!DOCTYPE html>
<html>

<head>
    <title>日付選択</title>
    <script>
        //数値カウンターまとめ
        function Counter(elementId, start, end) {
            document.getElementById(elementId).innerHTML = '';
            for (let i = start; i <= end; i++) {
                let option = document.createElement("option");
                option.value = i;
                option.text = i;
                document.getElementById(elementId).appendChild(option);
            }
        }

        //年月はまとめてカウンターに渡して生成
        function showYearCounter(yearId, monthId, dayId) {
            Counter(yearId, 1800, 2020);
            Counter(monthId, 1, 12);
            showdayCounter(yearId, monthId, dayId);
        }

        //日だけ年月で３パターンを判定してカウンター関数に投げる
        function showdayCounter(yearId, monthId, dayId) {
            let year = document.getElementById(yearId).value;
            let month = document.getElementById(monthId).value;
            let februaryDays = leap(year) ? 29 : 28;

            if (month == 2) {
                Counter(dayId, 1, februaryDays);
            } else if (month.match(/^(4|6|9|11)$/)) {
                Counter(dayId, 1, 30);
            } else {
                Counter(dayId, 1, 31);
            }
        }

        //閏年判定
        function leap(year) {
            return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
        }

    </script>
</head>

<body>

    <body onload="showYearCounter('year', 'month', 'day');">
        <select id="year" onchange="showdayCounter('year', 'month', 'day');"></select>年
        <select id="month" onchange="showdayCounter('year', 'month', 'day');"></select>月
        <select id="day"></select>日
    </body>

</html>
```
docker composeで.envが読み込まれない

docker composeを使ってnode製アプリを動かそうとしたら、しょうもない.envのミスでめちゃくちゃ時間を溶かしてしまいました‥
戒めを込めて何がダメだったのか書き残しておきます。

## TL;DR

commandに関して、プロジェクトのルートで`node app.js`とすべきところを`node /app/app.js`としてしまっていた。
これだと.envが正しく読み込まれないので、`/app`に移動してから`node app.js`しましょう。

## 詳しい状況

こんなdocker-compose.yml書いてました。`←ここがダメ`と書いてあるところが問題で、こいつを`node app.js`に書き換えて、working_dirを付け足せばokです。

```docker-compose.yml
version: '3.1'

services:
  app:
    image: node:latest
    command: node /app/app.js # ←ここがダメ
    volumes:
      - ./:/app/
  tunnel:
    image: cloudflare/cloudflared
    command: tunnel run
    environment:
...
```

直したやつ：

```docker-compose.yml
version: '3.1'

services:
  app:
    image: node:latest
    working_dir: /app
    command: node app.js
    volumes:
      - ./:/app/
  tunnel:
    image: cloudflare/cloudflared
    command: tunnel run
    environment:
```

これで.envが読み込まれるようになります
【入青】 中3がAtCoder青色になるまでにやったこと

# 0. はじめに

初めましてnouka28です。
先日のABC325で2回目の黄perfを出し、青コーダーになりました！！
https://atcoder.jp/users/Thinkingpegasus/history/share/abc325

![スクリーンショット 2023-10-22 14.59.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512071/0b1cc2d8-0647-401a-f6ff-7765de9c7e27.png)

AtCoderの色ランクの評価を見ると、
>青色 (Aランク R1600~1999　上位7%)
 青は超優秀です。学生時代を競技プログラミングに注ぎ込んでも、ここにたどり着けない学生は大量にいます。競技プログラミング未経験者では、このレベルと競技プログラミングで戦うことは殆どの場合は無理です。8割以上のIT企業において、アルゴリズム力はカンストです。一部企業においては、少し持て余してしまうかもしれません。
https://chokudai.hatenablog.com/entry/2019/02/11/155904

ここにたどり着けない学生がたくさんいるなか、中3でなることができたので感無量です。
普段の地道な努力が結果として実ってくれて、競プロを出会って、続けていて良かったと思っています。

# 1. 自己紹介

中学3年生です。
プログラミングは中1の秋くらいScratchをはじめ、Python、競プロは中2になってから初めたので他の中高生erと比べたら始めた時期が若干遅いかもと思ったりしています。
得意教科は数学で、OMC水色ですが、競プロの数学についてはまだ初心者だと思っています。いつか数学つよつよマンになりたいです。

# 2.やったこと
### 茶色まで
それと言ったことは何もやっていません。当時は競プロに関する情報を何も知らなかったのでただコンテストに参加するということをしていました。

### 緑色まで
JOIの2次予選にたまたま通ってしまい、JOIの本選に向けてC++とアルゴリズムの勉強をしていました。
「競技プログラミングの鉄則」という本を買って猛スピードで読み進めていました。
JOI本選は177点で終わりましたが、それ以降も競技プログラミングの鉄則を1周して累積和や二分探索、DPなど基本的なアルゴリズムを身につけて、そのペースで入緑することができました。

新たに覚えたアルゴリズム：

- bit全探索
- 累積和
- 二分探索
- 尺取り法
- 基本的なDP (部分和、ナップザック、LCS、区間DP、bitDPなど）
- DFS、BFS

### 水色まで
蟻本を買いました。初級編と中級編を読んで、競技プログラミングの鉄則の復習にもなり、よりアルゴリズムがしっかり身につきました。

新たに覚えたアルゴリズム

- $O(\sqrt N)$ の素数系諸々
- modをとるnCr、繰り返し2乗法
- Grundy数
- Dijkstra法
- UnionFind
- ダブリング
- ローリングハッシュ
- セグメント木（RMQ,RSQ)
- 最小全域木

### 青色まで
PythonとC++を2つ使いこなしながらコードを書けるようになりました。
C++はテンプレートを作り、可変長の関数input,printなどはとても役に立ってます
aclibraryを使うようになり、また自分のライブラリの整備をするようになりました
ライブラリを整備することで実装がめんどいDijkstraなどをコピペするだけの状態にできたりなど色々便利になりました。

![スクリーンショット 2023-10-22 20.30.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512071/84f56331-6442-a000-ae03-427345fd987c.png)

アルゴリズムを覚えるというより過去問を埋めることに専念していました。
![スクリーンショット 2023-10-22 20.48.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512071/955ef203-3535-0eee-a440-4a7b1bae04fe.png)
水色になってからはABCの水~青diffを中心に解いていました。毎日最低1問を欠かせずに埋めていきました。

新しく覚えたアルゴリズム：

- Weighted UnionFind
- 抽象化セグメント木、抽象化遅延セグメント木
- Mo's algorithm
- LCA
- Euler Tour
- SCC
- PrioritySum （概要だけ）
- FPS （概要だけ）

そしてABC325でついに黄perfを出し+100で青色になりました！！

# 3. 今後について
3ヶ月で緑から水になり、3ヶ月で水から青になりました。だから3ヶ月で青から黄になりますというのは無理なので、青色を維持しつつ黄色を目指して頑張りたいです。JOIも過去問を埋めていきたいところ。

# 写真集
![スクリーンショット 2023-10-22 21.08.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512071/38022a9f-4e81-4267-e57f-b2ff12bd49aa.png)
![スクリーンショット 2023-10-22 21.09.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512071/5d65e38d-a32e-fd10-72de-ed6e0d44f841.png)
![スクリーンショット 2023-10-22 21.12.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512071/dbb4256b-fef2-63df-de9f-87a3b3885498.png)
ABC325回答メモ

2023/10/23 D問題を解けたので追記

# 0.はじめに
　Daily Trainingもちょいちょい取り組んで
　スキルアップした気になって臨みましたが
　相変わらずC問題まででした。
　Cまで解く速さは早かったようで、レートは微増でした。


# 1.A - Takahashi san
　ちょっと懐かしい感じの簡単な問題でした。
　文字列S,Tを入力しS+sanを出力するだけの簡単なお仕事でした。

　https://atcoder.jp/contests/abc325/submissions/46793511


# 2.B - World Meeting
　Aと打って変わって難しい問題でした。
　標準時と現地時間の差と9時の差がごっちゃになって
　考えがまとまりませんでした。

　例題を軸に考え落ち着いて整理して考えをまとめました。

　考え方
　0時～23時に会議を始めた時に参加できる人が何人になるかのリストＴを作る。
　WとXを読み込み、始業時間を9-X(マイナスになったら24を加算)で求め、
　始業時間から9時間分ＴにＷを加算する。
　最後にＴ内の最大値を出力して終了。

　https://atcoder.jp/contests/abc325/submissions/46804116


# 3.C - Sensors
　考え方はそれほどではないのですが、ややこしいの一言に尽きる問題でした。
　もう再帰関数を使うしかないと思い、現在の座標の周囲8マスに
　センサーがあるか、あった場合さらにそのマスの周囲にセンサーがあるかを
　調べる・・・と、再帰を回し、1回のチェック内で見つかったセンサーに
　同じグループ№をつけていき、最後に、作れたグループ数を表示しました。


　https://atcoder.jp/contests/abc325/submissions/46813260

# 4.D - Printing Machine
　コンテスト内では、解けず、さらにそのあとも悩みましたが
　結局解けませんでした。
　後でリベンジしたいと思います・・・
　→以下10/23追記

　コンテスト後落ち着いて整理して解きました。

　【考え方】
　　1.準備処理
　　　・TとDを読み込みながら辞書LとLTを作成
　　　　辞書L：キー_印字可能となる時間
　　　　　　 値(リスト)_T+D(あるアイテムが印字可能範囲から出る時間)
　　　　LT：印字可能範囲から出る時間の最後の時間(以下のループ終了時刻として使用)
　　　・LのキーリストNTを作成(印字可能アイテムが無くなった時何秒まで飛ばすかに使用)
　　　・Lを昇順にソート
　　　・ヒープQue：Wを作成
　　　　（現在の秒数で印字可能なアイテムの印字可能範囲から出る時間を保持）
　　　・現在の経過時間nowを1で初期化、印字した個数ansを0で初期化
　　2.メイン処理(nowがLTを超えるまでループ)
　　　・辞書Lから、現在の経過時間nowで印字範囲に入るリストを取得しWに格納
　　　・Wに格納しているアイテムを小さい順（印字不可となる時間が早い順）に
　　　　アイテムを取り出す。
　　　　(Wが空になるか、取り出したアイテムが現在印字可能な場合まで)
　　　・取り出したアイテムが印字可能な場合
　　　　-ansに1加算
　　　　-nowに1加算
　　　・取り出したアイテムが印字不可な場合（＝Wが空になった場合）
　　　　-NTに格納しているアイテムを、now以上になるかNTが空になるまで取り出し
　　　　　-取り出したアイテムがnow以上の場合、nowをその時間に変更
　　　　　-NTがからになった場合、nowにLT+1を格納
　　3.最後にansを出力して終了

　heapqueを使うことによって高速化＆簡略化ができました。
　　
　https://atcoder.jp/contests/abc325/submissions/46869128

以上
【Photoshop】初心者でも分かる！PhotoshopでRGBをCMYKへ変換する方法

## 概要
前回は「RGBとCMYK」の違いについて説明した記事を書いたのですが、
今回は実際にPhotoshopでRGBをCMYKへ変換する方法について説明していきます。
前回の記事↓

https://qiita.com/fujino_slj/items/e04d29faed1f66038d7a

## 「RGBとCMYK」の違いについて
そもそもどんな時に「RGB」「CMYK」を使用すればいいのか、上記にのせた記事でも詳しく違いについて説明してますが、軽くここでも説明したいと思います。

## RGBを利用した方がいいもの
パソコンやスマートフォンなどのモニターで見るもの向けのデザインはRGBで行うのが一般的です。
また、RGBはCMYKに比べて表現できる色の幅が広く、特にパステルカラーなどの薄い色彩はRGBの方が思い通りに表現できるとされています。

## CMYKを利用した方がいいもの
印刷物など、本や雑誌、ポスターなどのデザインはCMYKで色の指定をするのが一般的です。
また、CMYKはRGBに比べて表現できる色の幅が少ないため、デザインをパソコン上で行う場合は調節しないと、印刷物の色が異なることがあります。

## どんな時に変換するべき？
パソコンで作成する作品がデフォルトでRGBを使用しています。
もしポスターやチラシなどに印刷したいなら、データをCMYKに変換して、色味などを確認することがおすすめです。

## Photoshopで「RGB」から「CMYK」に変換する方法
ここからはPhotoshopでRGBからCMYKに変換する方法について紹介していきます。

### モードから変換する方法
Photoshopのメニューから『イメージ 』⇒『モード』⇒『CMYKカラー』を選択することで、簡単にRGBからCMYKに変換することができます。しかしこの場合、もとのRGBカラーと変換後のCMYKカラーの色彩が若干異なることがあるため、気になる方は濃度補正等を行うようにしましょう。

### プロファイル変換する方法
メニューから『編集』⇒『プロファイル変換』で変更することも可能です。プロファイル設定画面で「プロファイル」のリストを開くと、変換後のプロファイルが自由に選べます。プレビュー機能があるため変換後の色彩を確認しやすいです。

## 最後に
今回はPhotoshopでRGBをCMYKへ変換する方法について説明しました。
RGBとCMYKはそれぞれ表現の方法が異なるため、RGBで表現した色をCMYKでまったく同じように表現したい場合、色彩にこだわればこだわるほど変換＆調整が難しくなります。RGBの方が表現できる色の幅が多いため、パソコン上でデザインした色とまったく同じものを印刷物で表現するには、CMYKに変換した後の色彩調整などが必要になります。特に淡い色だとCMYKにしたとたんくすんだり、全体的に色調が暗くなるため注意が必要です。
【SwiftUI】ListCellに灰色矢印を追加する

# はじめに
UIKitだと`cell.accessoryType = .disclosureIndicator`で灰色の矢印を付ける事ができました。
しかし、SwiftUIにはそのような機能はないのでコネコネして作ります

# 実装
```swift
import SwiftUI

struct NavigationButton<T: View>: View {
    var action: () -> Void
    
    @ViewBuilder var label: () -> T

    var body: some View {
        Button(action: action) {
            NavigationLink(destination: EmptyView.init, label: label)
                .foregroundColor(Color(uiColor: .label))
        }
    }
}
```

# 使い方
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            List {
                NavigationButton {
                    print("押しました")
                } label: {
                    Text("サンプルセル")
                }
            }
        }
    }
}
```

# 完成
![simulator_screenshot_7AC16471-CB6A-4136-BD1B-8CB8A7FFD427.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/703c7547-bf09-1772-50e2-00b7507550e0.png)

# おわり
できました
Dependabot alertが出たら〜Rust編〜

## (0) まえがき
Rust、もといCargo圏はほぼ中央集権[^2]かつセマンティックバージョニングによる互換性が担保[^1]されているので脆弱性アラートは解消しやすい部類に入ります。

そのため、dependabotと呼ばれるGitHub公式のbotが脆弱性を持たないバージョンに更新するために巡回して勝手にPull Requestを置いていってくれることがあります。もし成功していたら、それをマージしてあなたの仕事は終わりです。
しかし、dependabotは万能ではないため、ときどきバージョンの自動更新に失敗することがあります。
そこで、今回は[GHSA-c827-hfw6-qwvm](https://github.com/advisories/GHSA-c827-hfw6-qwvm)を例に取り、脆弱性アラートを**無視せず正しく**解決する方法を残します。

## (1) 脆弱なパッケージの特定
通常、Dependabot alertによって当該パッケージが表示されるはずです。RustSecによる脆弱性データベースから流入してくることが結構あります。

今回のGHSA-c827-hfw6-qwvmは`rustix`というクレートが脆弱性を抱えています。

## (2) 直接的な依存か、間接的な依存か見極める

パッケージ管理システムによってダウンロードされるパッケージは大きく分けて2つあります。
* 自分のパッケージが直接依存しているパッケージ
* 自分のパッケージが依存しているパッケージが依存しているパッケージ (推移的依存; transitive dependency)

しかし、その制約を解いた解の一つである`Cargo.lock`を眺めただけでは各バージョンがフラットに記述されており読み解くのは大変です。

そこで、`cargo-tree`の出番です。組み込みのサブコマンドによって、すぐにどの経路か特定することができます。

早速次のコマンドを打ってみましょう。

```
cargo tree -i rustix
```

[私のプロジェクト](https://github.com/KisaragiEffective/origlang/blob/922262ab360ced35d6f9abcf2f4a5751faaebaf3/Cargo.lock)では、次のように表示されました。

```
rustix v0.37.6
└── is-terminal v0.4.6
    └── env_logger v0.10.0
        ├── origlang-cli v0.1.0 (/home/kisaragi/IdeaProjects/origlang/package/origlang-cli)
        └── origlang-testsuite v0.1.0 (/home/kisaragi/IdeaProjects/origlang/package/origlang-testsuite)
```

## (3) 手でがんばる

制約さえ満たされればどの戦略を選んでも良いです。しかし、一般に古いバージョンを一気に新しいバージョンに上げることは大変なのでついでに直してしまいましょう。

`Cargo.lock`を手で触るわけには行かないので、`cargo-update`というこれまた組み込みのサブコマンドを使います。
ただし、何もスイッチをつけないとすべてが更新されてノイズになってしまうので`-p`スイッチでクレートを指定して必要最小限のクレートを更新します。

まず、`cargo update -p env_logger`を試します。しかし(執筆時点では)何も変化がありませんでした。

次に`cargo update -p is-terminal`を試します。すると以下のような出力が出ました:
```
    Updating crates.io index
    Updating errno v0.3.0 -> v0.3.5
    Removing errno-dragonfly v0.1.2
    Removing io-lifetimes v1.0.9
    Updating is-terminal v0.4.6 -> v0.4.9
    Updating linux-raw-sys v0.3.1 -> v0.4.10
    Updating rustix v0.37.6 -> v0.38.13
```

`rustix`が`0.38`系列にアップグレードされました。しかし、このバージョンは脆弱なバージョンです。

最後に`cargo update -p rustix`を試しましょう。しかし、何も出ませんでした！なぜでしょう？

それは、`-p`をつけるとそのクレートの依存クレートのバージョンを変えない範囲で探索するようになるからです。

これをオプトアウトするためには、`--aggressive`フラグをつける必要があります。早速やってみましょう：

```
    Updating bitflags v2.4.0 -> v2.4.1
    Updating libc v0.2.147 -> v0.2.149
    Updating rustix v0.38.13 -> v0.38.20
    Updating windows-targets v0.48.0 -> v0.48.5
    Updating windows_aarch64_gnullvm v0.48.0 -> v0.48.5
    Updating windows_aarch64_msvc v0.48.0 -> v0.48.5
    Updating windows_i686_gnu v0.48.0 -> v0.48.5
    Updating windows_i686_msvc v0.48.0 -> v0.48.5
    Updating windows_x86_64_gnu v0.48.0 -> v0.48.5
    Updating windows_x86_64_gnullvm v0.48.0 -> v0.48.5
    Updating windows_x86_64_msvc v0.48.0 -> v0.48.5
```

うまく行きましたね！

## (4) 終わりに
最近はdependabotやrenovateのおかげでだいぶ楽になりましたが、彼らはまだこういった込み入った問題を解決できる力を持っていません。

たまには手動で修正する必要もありますが、がんばりましょう :muscle:

[^1]: 互換性があるとみなされるバージョンに上げてコードを変えずに再コンパイルしようとした際動かなければライブラリ作者が「悪い」
[^2]: https://crates.io に大体ある
数値を２倍にして表示するプログラムを実行したら、、、

## 数値を２倍にして表示するプログラム


▫️やりたいこと

1.ユーザーは好きな数値を入力できる
2.ユーザーが入力した２倍の数が表示される

学習したことをもとに記述してみました！

```ruby

puts "数字を入力してください"
number = gets.chomp

dobble_number = number*2

puts "入力した数の２倍は#{dobble_number}です"

```


**これでうまくいくはず、、、**


結果は！？

```
数字を入力してください
１
入力した数の２倍は１１です
```


**１×２はもちろん「２」ですが、結果は「１１」と出てしまいました、、、**

2と入力すると２２、３と入力すると３３と出てしまいます。

## なぜ数字が並べられて出力されてしまうのか？

答え： `gets`メソッドはユーザーからの入力を文字列として受け取るから

ユーザーが入力したものは、数値であっても、テキストであっても通常文字列として扱われます。

もし、数値として扱いたい場合**文字列から数値に変換**する必要があります！


### 😅文字列を数値に変換して、再度挑戦！

```ruby
puts "数字を入力してください"
input = gets.chomp

# 文字列から整数への変換
number = input.to_i

# 整数の2倍を計算
double_number = number * 2

puts "入力した数の２倍は #{double_number}です"

```

結果は！？

```
数字を入力してください
１
入力した数の２倍は2です
```

👏👏👏👏👏👏

ちゃんと２倍になってくれました:relaxed:

### 今回使用したメソッド
- getsメソッド・・・テキスト入力を受け取るために使用されるメソッド。
- chompメソッド・・・改行文字を文字列から除くためのメソッド。
- to_iメソッド・・・文字列を整数に変換するメソッド


### ⭐️補足⭐️

getsメソッドは、改行文字（Enterキーによって挿入される）を含んだ文字列として入力を受け取る。

例）ユーザーが `1` を入力した
　　　　　プログラム　：`1\n`を取得する

上記のように、プログラムは改行文字を１と同時に文字列として取得してしまうため、場合によってはエラーを起こしてしまう可能性がある。

**必要に応じて、改行を取り除くためにchompメソッドを使用する！**
optparseを使用してRubyでオプションを指定する

# はじめに
今回はRubyのライブラリ機能の1つである``optparse``について解説していきます。

# optparseとは？
Rubyの公式リファレンスには
>コマンドラインのオプションを取り扱うためのライブラリです。

https://docs.ruby-lang.org/ja/latest/library/optparse.html

と書かれています。
コマンドラインというのはMacでは``ターミナル``、Windowsでは``コマンドプロンプト``と呼ばれていて、
キーボード（文字を入力するときに使う機械）だけで操作する画面のことです。

https://wa3.i-3-i.info/word11158.html

optparseライブラリでは、コマンドラインにてオプションにて指定した値を、``引数``としてファイル内の配列に代入し、実行することが可能になります。

# オプションの定義
optparseを用いてオプションを設定する場合、以下の流れで設定することができます。

1. **OptionParser オブジェクト opt を生成する。**
2. **オプションを取り扱うブロックを opt に登録する。**
3. **opt.parse(ARGV) でコマンドラインを実際に parse する。** 

```sample.rb
require 'optparse'

# 1.OptionParser オブジェクト opt を生成する。
opt = OptionParser.new

# 2.オプションを取り扱うブロックを opt に登録する。
opt.on('-a') {|v| p v }

# 3.opt.parse(ARGV) でコマンドラインを実際に parse する。
opt.parse!(ARGV)

# 出力
p ARGV
```

```出力結果.
$ ruby sample.rb -a foo bar
# => true
     ["foo", "bar"]
```

``onメソッド``は、optオフジェクトに登録するオプションを定義しています。
``ARGV``にはコマンドラインで渡された``オプション(-a)``、``引数(foo,bar)``が配列として渡され、``parse``することで``引数(foo,bar)だけ``取り出すことができます。


# おわりに
今回はRubyライブラリのoptionparseについて解説させていただきました。
まだまだ理解が浅い部分があるので、引き続き学習する中で理解を深めていければと思います。
最後まで閲覧いただきありがとうございました！
ルートドメインリダイレクトをローコストで実現した

諸般の事情により、今まで使っていたお名前ドットコムの「DNS追加オプション」を解約することとなった。（月110円から30円値上げもあり）
この影響により、ページへのアクセスがWWWをつけないといけなくなっていたことでご迷惑をおかけしていたが、ローコストで解決することが判明したので、参考にしてくれると嬉しいです。

## つくりかた
1\. Azure Portalを開く
2\. リソースグループを開き、Webサイトが入っているリソースを開く
3\. 「作成」をクリックし、「Static」とワードを入れると「静的Webアプリ」が出るので、それをクリック。
4\.  サブスクリプション・リソースの位置を確認し、Webアプリ名称を入力する。例）topxxxxx（ドメイン名称）
5\. 接続は後程行うとして、先にドメイン名の接続を行う。

:::note info
（2023年10月22日現在）
Onamaeでは、CNAME、A、TXTレコードが利用できます。
先にTXTレコードで接続を行い、検証が完了された後にCNAMEもしくはAレコードの登録が可能です。
:::

いずれも入力値は表示されているものをそのままコピペする。
TXTでの検証に時間がかかるため、時間をおいての接続となることをご了承いただきたい。

6\. Githubリポジトリで接続用のリポジトリを作成し、その中にindex.htmlとads.txtを入れる。

htmlは以下の通り。

```html:index.html
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
    <meta http-equiv="Refresh" content="0; URL=https://www.nhk.or.jp" />
</head>
```
ads.txtはGoogle Adsenseの通りに操作する。

7\. 6\.で作ったリポジトリの「Actions」をクリックし、Workflowの画面が出るので、「Static Web」と検索すると専用のコードが出てくる。ここで示される"AZURE_STATIC_WEB_APPS_API_TOKEN"というコードを覚えつつ、「Github」のタブと「Azure」のタブを2つあることを確認し、「Azure」のほうのタブに移動する

8\. 静的Webアプリの「概要」に移動し、「デプロイトークンの管理」をクリックし、トークンの用意をする。

9\. 6\.で作ったリポジトリの「Settings」を新しいタブで開き、「Secrets and variables」タブを開き、「Acrions」を開く。

10\. 「New repository secret」をクリック。

11\. タイトルに「AZURE_STATIC_WEB_APPS_API_TOKEN」とし、8\.で用意したトークンをコピペする。

12\. トークン　→　Workflowの順でで保存を行い、正しくアップロードされるかを確認する。

13\. ドメイン直下のads.txtが正しくあるかも確認してエラーになっていなければ完成です。

走り書きでしたが、今後希望あればスクショ乗せようと思います。wwwなしでもページどうにかしたい方いればぜひお声掛けください。

（ちなみに、トップドメイン用にわざわざ証明書を入れなくていいようです。Azureで証明書あるみたいです。無料で）
Jenkinsの環境構築手順

仕事でjenkinsを使うことがあったのですが、初めて触るため
練習しておこうと、dockerでjenkins環境を立ててました。
その時の、構築メモです。

1. **Dockerイメージの取得**:
JenkinsのDockerイメージをDocker Hubから取得します。
    
    ```bash
    docker pull jenkins/jenkins:lts
    
    ```
    
2. **docker-compose.yml ファイルの作成**:
`docker-compose.yml`ファイルを作成し、以下の内容をコピー&ペーストします。
    
    ```yaml
    version: '3.7'
    services:
      jenkins:
        image: jenkins/jenkins:lts
        ports:
          - "8080:8080"
          - "50000:50000"
        volumes:
          - jenkins_home:/var/jenkins_home
    volumes:
      jenkins_home:
    
    ```
    
3. **Dockerコンテナの起動**:
    
    ```bash
    docker compose up -d
    
    ```
    
4. **Jenkinsのセットアップ**:
Webブラウザを開き、`http://localhost:8080`にアクセスします。初回アクセス時には、アンロックコードが必要になります。コードはコンテナのログから取得できます。
    
    ```bash
    docker logs [コンテナ名またはコンテナID]
    
    ```
    
5. **プラグインのインストール**:
必要に応じて、Jenkinsのプラグインをインストールします。
6. **ジョブの作成と実行**
Jenkins上でジョブを作成し、必要に応じて実行します。

以上がJenkinsの環境構築手順です。詳細な手順は参考リンクをご覧ください。