OmniAICreator/Qiita-1.07M huggingface dataset:
VSCodeでDockerコンテナにアタッチして開発

## 前提
・今回の記事は新たに環境構築を行うのではなく、すでに動いているプロジェクトへ途中でアサインした場合など、もうできている環境で開発を行う為のものです。
・今回はVSCodeで実施しています。またVSCodeに限らずPHPStormや他IDEなどでも同様のプラグインは何かしら出ていると思います。
・使用するプラグインは、[Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)（旧：Remote Containers)を使います。

# 内容
Dockerでnodejs環境を構築する時に、node_modulesをDockerの名前付きボリュームとして管理すると思います。[(以前記事であげた際のgitリポジトリです)](https://github.com/nonamenme/docker-react)
その場合当然ですが、ホスト側のnode_modulesには作成されないので、`VSCode`などのエディタで開発を行う際、このようなエラーで怒られると思います。
`Cannot find module 'react' or its corresponding type declarations.ts(2307)`
![スクリーンショット 2023-05-22 16.24.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364644/cbc52e4f-2cda-c12c-88a7-d52ace5ad540.png)
これをエディタ側でなんとかしようというのが今回の内容です。

**もしnode_modulesもホスト側とマウントしている場合は、これを機にホスト側とは切り離すようにしましょう。**
理由として、ホスト側のnode_modulesでDockerコンテナ内（ゲスト側）のnode_modulesが上書きされてしまう為です。（ホスト側で`npm install`しちゃった等）
コンテナ内の環境でnodeのバージョンを固定し、全員が同じ環境で開発できるようにしているのに、ホスト側の人によって違う環境でパッケージ管理をしては、Dockerで環境を構築している意味が全くないとは言いませんが、だいぶなくなってしまいます。


## 手順
### 1. プラグインのインストール
まず、VSCodeの`Extension`から`Dev Containers`をインストールします。
![スクリーンショット 2023-05-22 16.44.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364644/8e6d4bcb-5ca8-d0b9-cf85-0f5af9165fab.png)

### 2. コンテナへアタッチ
左下の`><マーク`①をクリックすると、上からベロンとRemote接続するメニュー②が表示されるので、`Attach to Running Container...`を選択します。
![スクリーンショット 2023-05-22 16.58.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364644/cf6f5ec3-20c3-f908-3eb5-7ebc46370bb8.png)すると、現在立ち上がっているDockerのコンテナが一覧で表示されるので、アタッチしたいコンテナを選択。（スクリーンショットでは1つですが、立ち上がっているコンテナの数だけ表示されます。）
![スクリーンショット 2023-05-22 17.12.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364644/49549620-0ca3-4049-ebaa-e7bf6bf7d541.png)
コンテナを選択したら、新たにウィンドウが立ち上がると思います。

## 3. フォルダーを指定
新たに立ち上がったウィンドウでこのような画面が表示されていると思います。
その`Open Folder`①をクリックすると、パスを入力するメニュー②が表示されるので、コンテナ内のソースコードを置いてあるディレクトリまでのパスを指定してください。（**ホスト側ではなくコンテナ内のソースを置いている場所です**）
スクリーンショットの例では、[こちら](https://github.com/nonamenme/docker-react)のリポジトリを例にしています。
![スクリーンショット 2023-05-22 14.16.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364644/4220145a-8cbb-6f92-57a9-3f4391df544b.png)
入力後`OK`をクリックすると、指定したところのディレクトリが開いている状態になると思います。
これで、コンテナ内にアタッチした状態で開発できます。
先ほどのエラーが発生していた箇所を参照しても、ちゃんとnode_modulesがあるのでエラーが出ずに出来てますね。![スクリーンショット 2023-05-22 17.25.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364644/46150ccb-ec0b-29b7-7999-0ba51d2182f2.png)

## まとめ
今回は、DevContainersを使ってコンテナ内で開発できるようにしました。
結構、備忘録的なところや新しくプロジェクトへアサインした際の新人への説明用に作ったので、ところどころ雑な感じはありますが、ご容赦ください。

そんな私は未だにEmacsをメインで使ったり、たまにVSCodeも使ったりの二刀流ですが、
会社のメンバーは８割がVSCodeを使っているので、せっかく便利な機能があるなら使って快適な開発ライフを送りたいですね。

## 参考リンク
https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers
https://zenn.dev/yumemi_inc/articles/3d327557af3554
https://www.aipacommander.com/entry/2022/08/19/160756

~Emacsで同様のことをしたい方はこちら~
https://qiita.com/kai2nenobu/items/7af012e327b8dd078ba4
https://blog.agile.esm.co.jp/entry/2022/03/01/090000
GA4：デモアカウントとウォークスルー

# デモアカウント

次のページにアクセスします。

https://support.google.com/analytics/answer/6367342?hl=ja

赤枠のリンクをクリックします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/a7150fee-9f22-e72e-b9df-0fe668945c96.png" width="600">

デモアカウントは、実際に測定した結果を示しています。

[Google Merchandise Storeのページ][demo]

[demo]: https://analytics.google.com/analytics/web/?utm_source=demoaccount&utm_medium=demoaccount&utm_campaign=demoaccount#/p213025502/reports/intelligenthome

# ウォークスルー

| ページ | 特徴  | 
| :--- | :--- | 
| 概要 | カードが並んだもの | 
| 詳細 | 表形式のテーブルが表示されたもの | 

### ホーム

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/08731081-8b4a-085a-c773-ea914574cd36.png" width="600">

### レポート

#### レポートのスナップショット

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/8cbecbf2-0981-332d-f7c5-2640e6b4f315.png" width="600">

#### リアルタイム

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/7e0fa785-a158-dfd8-2d08-be67ae09f089.png" width="600">

#### Life cycle

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/b68a2d74-7c2d-16ac-5d77-8e8892d1e5dd.png" width="600">

#### Life cycle-集客-Acquisition Overview

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/32ffe064-58d1-5c1b-66ef-d83856ee03db.png" width="600">

#### Life cycle-集客-ユーザ獲得

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/b7b39b1e-b2de-5161-dc48-306388f5513d.png" width="600">

## 探索

テンプレートを使って、レポートを作成できる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/fa8ee37e-011f-1426-80f2-40a5f2b75200.png" width="600">

## 広告

#### 広告のスナップショット

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/158e7f73-0746-d601-90aa-5c49e5b6f48b.png" width="600">

#### パフォーマンス-すべてのチャネル

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/c994e608-e194-244b-14e1-4f4da90a57c1.png" width="600">

## 管理

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/d19826ad-5659-ebcf-270a-f950705cf652.png" width="600">

# 参考

https://qiita.com/Qiita/items/c7f704e3786df3aa7a11
paiza.ioでelixir その226

# 概要
paiza.ioでelixirやってみた。
練習問題、やってみた。

# 練習問題
gtkwaveのvcdファイルを生成せよ。
2ch、実装せよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/eb832294-5590-3005-0466-944cd13eec3b.png)


# サンプルコード

```
defmodule Va do
	use Agent
	def start_link() do
		Agent.start_link(fn ->
			0
		end, name: __MODULE__)
	end
	def get() do
		Agent.get(__MODULE__, fn v ->
			v
		end)
	end
	def inc() do
		Agent.update(__MODULE__, fn v ->
			v + 1
		end)
	end
end

defmodule Main do
    def main(src0, src1) do
        IO.puts "$date"
        IO.puts "  Sat Mar 27 16:11:10 2022"
        IO.puts "$end"
        IO.puts "$version"
        IO.puts "  plunker"
        IO.puts "$end"
        IO.puts "$timescale"
        IO.puts "  1ms"
        IO.puts "$end"
        IO.puts "$scope module test $end"
        IO.puts "$var reg 1 ! a $end"
        IO.puts "$var reg 1 # b $end"
        IO.puts "$upscope $end"
        IO.puts "$enddefinitions $end"
        IO.puts "#0"
        IO.puts "$dumpvars"
        IO.puts "x!"
        IO.puts "x#"
        IO.puts "$end"
        Enum.map(0..2, fn i ->
	        Enum.reduce(String.split(src0, ""), 0, fn x, n ->
	            if x != "" do
	                Va.inc
	                IO.puts "##{Va.get}"
	                IO.puts "#{String.slice(src0, n, 1)}!"
	                IO.puts "#{String.slice(src1, n, 1)}#"
    	            n = n + 1
    	        else
    	            n
	            end
	        end)
        end)
    end
end

Va.start_link
Main.main("111111111000", "111111000111")




```

# 成果物

https://paiza.io/projects/GccP-faEK6Z3yLV0bmnAhg

以上。
[TypeScript] フィールドの初期化子でthisは使える

## 先に結論だけ

フィールド初期化子で`this`にアクセスできます。したがって、このコードはトランスパイルできます。

```ts
interface A {
   parent:B
}

class B {
    readonly instanceA : A = {parent:this}
}
```

[PlayGround](https://www.typescriptlang.org/ja/play?#code/JYOwLgpgTgZghgYwgAgILIN4Chm4A5xQTgBcAQlgL5ZYIA2cAzo8mZjrskXACYD2IOgE9koRmDggk6EmmQBeTASKkwAC2CNqlIA)

## はじめに

この記事は、TypeScriptにおけるフィールドの初期化子とthisの関係を記録、共有するためのものです。

### 想定する読者

- JavaScriptおよびTypeScriptの開発経験がある

### 対象とする環境

- TypeScript 5.0.4

## フィールドの初期化子とは

https://typescriptbook.jp/reference/object-oriented/class/field-initializers

フィールドの初期化子とは、クラスのメンバー変数に初期値を与える演算子です。

## フィールド初期化子はJavaScriptコードにどう変換されるか

フィールドの初期化子は、JavaScriptに変換するとコンストラクター内での処理になります。記事冒頭のサンプルコードをトランスパイルすると、以下のようになります。

```js
"use strict";
class B {
    constructor() {
        this.instanceA = { parent: this };
    }
}
```

したがってフィールド初期化子の中の`this`はクラスBのインスタンスになります。

フィールドの初期化子を使うと、コンストラクターの可読性が向上します。また、readonly修飾子を使うことで初期化忘れや再代入といったヒューマンエラーを抑止できます。フィールドの初期化子は積極的に利用しましょう。

以上、ありがとうございました。
ファイルをGit管理から外す3つの方法

## 先に結論だけ

Gitにはファイルをバージョン管理から外す方法が3つあります。

- `.gitignore`
- `.gitignore_global`
- `.git/info/exclude`

それぞれの方法には長所と短所がありますので、用途によって使い分けましょう。

## はじめに

この記事はファイルをGit管理下から外す方法を紹介、記録するものです。

### 対象とする環境

- git version 2.40.1

### 対象とする読者

- すでにGitを使っている

## Gitでファイルを管理下から外す方法

Gitでは、特定のファイルをバージョン管理から外す方法が3つあります。

### `.gitignore`

https://docs.github.com/ja/get-started/getting-started-with-git/ignoring-files#configuring-ignored-files-for-a-single-repository

- 設定したGitリポジトリだけを対象にする
- リポジトリに参加するすべての開発者に共有される

#### 利用ケース

- ビルド済みのコード
- パッケージマネージャーで管理されるコードやバイナリー

`.gitignore`には、開発チーム全体でバージョン管理が不要なファイルを指定します。他のファイルから再生成できるファイルは、積極的に除外しましょう。

### `.gitignore_global`

https://docs.github.com/ja/get-started/getting-started-with-git/ignoring-files#configuring-ignored-files-for-all-repositories-on-your-computer

- コンピューターのすべてのGitリポジトリを対象にする
- リポジトリに参加する開発者には共有されない

#### 利用ケース

- `.DS_Store`のようなテンポラリファイル

`.gitignore_global`にはOSやエディターなど、開発環境によって生成されるファイルを指定します。リポジトリを作成するたびに`.gitignore`を設定すると抜けや漏れが発生するので、`.gitignore_global`で除外するか`.gitignore`のテンプレートを作成しましょう。

### `.git/info/exclude`

https://docs.github.com/ja/get-started/getting-started-with-git/ignoring-files#excluding-local-files-without-creating-a-gitignore-file

- 設定したGitリポジトリだけを対象にする
- リポジトリに参加する開発者には共有されない

#### 利用ケース

- 開発中に書き換える可能性があるが、デプロイしてはいけない設定ファイル

`.git/info/exclude`でファイルを除外する場合は、開発環境のディレクトリ構成が複雑化しているかもしれません。ディレクトリ構成を見直し、バージョン管理下のディレクトリから除外対象となるファイルを切り出せないか検討してください。どうしても切り出せないファイルだけを`.git/info/exclude`で除外しましょう。

## 参考記事

https://qiita.com/aki4000/items/c64b9ce2b98ef63ad23b

以上、ありがとうございました。
リレーショナルデータベースとNoSQLデータベースの違いについて

# はじめに
リレーショナルデータベースとNoSQLデータベースという二つの主要なデータベースの種類について、その違いとそれぞれの利点・欠点について探っていきます。

## リレーショナルデータベース
リレーショナルデータベースは、データをテーブルに格納し、それぞれのテーブルが行（レコード）と列（属性）を持つという構造を持っています。これらのテーブルは一意のキーによって互いにリンクされ、SQLを使用してデータを操作・取得します。

### 利点
- 一貫性：リレーショナルデータベースは、ACID（原子性、一貫性、分離性、耐久性）プロパティを提供します。これにより、トランザクションが確実に完了し、データの一貫性が保たれます。
- 構造：データは整理された形（テーブル、行、列）で格納され、関連性を持つことができます。これにより、データ分析やクエリの作成が容易になります。
- 成熟性：リレーショナルデータベースは長年にわたり使用され、テストされてきた技術です。そのため、多くのツール、ライブラリ、そして経験豊富な開発者がいます。

### 欠点
- スケーラビリティ：リレーショナルデータベースは垂直スケーラビリティ（単一のサーバーのパワーアップ）には適していますが、水平スケーラビリティ（複数のサーバーへの拡大）は困難です。
- 柔軟性：リレーショナルデータベースは固定スキーマを必要とします。そのため、データの構造が頻繁に変わる場合や、構造が不明瞭な場合には不適です。


## NoSQLデータベース
NoSQLデータベースは、非リレーショナルデータベースの一種で、従来のテーブル形式のデータモデルではなく、キーバリューストア、ドキュメントストア、ワイドカラムストア、グラフストアなど、さまざまなデータモデルを採用しています。SQLを使用しないため、スキーマが固定されていない柔軟なデータモデルを持つことが可能です。

### 利点
- スケーラビリティ：NoSQLデータベースは分散システムに対する強力なサポートを提供し、大量のデータとトラフィックを扱うことができます。これにより、水平スケーラビリティが容易になります。
- 柔軟性：NoSQLデータベースはスキーマレスで、データ構造の変更が頻繁に起こるアプリケーションに適しています。これにより、新しいデータタイプや新しいビジネス要件に対応するのが容易になります。
- 多くのNoSQLデータベースがキー-バリュー形式のデータモデルを採用しているため、特定のキーを用いたデータの読み書きが非常に高速です。

### 欠点
- 一貫性：多くのNoSQLデータベースは一貫性を犠牲にしてパフォーマンスとスケーラビリティを追求します。これはCAP定理（一貫性、可用性、パーティション耐性のトレードオフ）の一部であり、一部のNoSQLデータベースでは、これをEVENTUAL一貫性と呼びます。
- 複雑なクエリ：SQLのような強力なクエリ言語がないため、NoSQLデータベースは複雑なクエリや複数のテーブル間の結合などを処理するのが難しい場合があります。

## まとめ
リレーショナルデータベースとNoSQLデータベースのどちらを選ぶべきかは、プロジェクトの具体的な要件によって異なります。リレーショナルデータベースは一貫性と構造を重視し、データ分析に有用ですが、スキーマの変更が難しいです。一方、NoSQLデータベースはスケーラビリティと柔軟性に強く、大量のデータと頻繁に変わるデータ構造に対応するのに適しています。

大まかですがリレーショナルデータベースとNoSQLデータベースの違いについて、以上になります。
[Azure][備忘録] サービスエンドポイント"Microsoft.Storage.Global"がAzurePortalで表示されない時の対策

# はじめに

私は画面に出るのに、他のメンバだと見れないってことが発生したので、問い合わせ内容をメモ。

2023/05/22時点の情報です。

## 本来ならこちらが表示されるはず

仮想ネットワークのサブネットより、サービスエンドポイントを選択する画面にて。
本来は「`Microsoft.Storage`」・「`Microsoft.Storage.Global`」のどちらも表示されるはず。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647946/5f27a728-1b4c-d002-d2a1-f357b635495a.png)

他のメンバは「`Microsoft.Storage.Global`」が表示されず、キャッシュクリアやシークレットタブでのアクセスを試みても改善しなかった。

# `Microsoft.Storage.Global`サービスエンドポイントって？

https://learn.microsoft.com/ja-jp/azure/storage/common/storage-network-security?toc=%2Fazure%2Fvirtual-network%2Ftoc.json&tabs=azure-portal#azure-storage-cross-region-service-endpoints

>リージョン間サービス エンドポイントを使用すると、サブネットでは、別のリージョン内のストレージ アカウントを含めて、ストレージ アカウントとの通信にパブリック IP アドレスを使用しなくなります。 代わりに、サブネットからストレージ アカウントへのすべてのトラフィックで、ソース IP としてプライベート IP アドレスが使用されます。

リージョンが異なるストレージアカウントに対し、サービスエンドポイントを使用した特定経路通信を行いたい時に使用する。

# 問い合わせによって明らかになった原因

以下の Azure RBAC 権限が必要

- アクセス権限: `Microsoft.Network/locations/virtualNetworkAvailableEndpointServices/read`
- スコープ: サブスクリプション全体
 
従って、サブスクリプション全体に閲覧権限を持つユーザーであれば参照可能となる。動作確認も取れた。

調べたところ、こんなような権限みたい。

https://learn.microsoft.com/ja-jp/azure/role-based-access-control/resource-provider-operations#microsoftnetwork

>`Microsoft.Network/locations/virtualNetworkAvailableEndpointServices/read`	使用可能な仮想ネットワーク エンドポイント サービスの一覧を取得します。

# Portalでは見えなくて、サブスクリプションに閲覧者権限をもらえない時のために

`az　cli`でできないか試してみる。
ただし、自分のユーザはサブスクリプションに作成者の権限を持ってしまっているので、認可の部分でエラーが出るかもしれない。

https://learn.microsoft.com/ja-jp/cli/azure/network/vnet/subnet?view=azure-cli-latest#az-network-vnet-subnet-update

`az network vnet subnet update`を使用したら、サブネットに`Microsoft.Storage.Global`サービスエンドポイントを追加できた。

```terminal
# 使用できるサービスエンドポイントを確認
$ az network service-endpoint list --location japaneast --output table
Name
------------------------------
Microsoft.Storage
Microsoft.Sql
Microsoft.AzureActiveDirectory
Microsoft.AzureCosmosDB
Microsoft.Web
Microsoft.KeyVault
Microsoft.EventHub
Microsoft.ServiceBus
Microsoft.ContainerRegistry
Microsoft.CognitiveServices
Microsoft.Storage.Global

# Microsoft.Storage.Globalをサブネットに追加
$ az network vnet subnet update --subscription MySubscription -g MyResourceGroup --vnet-name MyVnet --name MySubnet --service-endpoints Microsoft.Storage.Global
{
...略...
  "serviceEndpoints": [
    {
      "locations": [
        "*"
      ],
      "provisioningState": "Succeeded",
      "service": "Microsoft.Storage.Global"
    }
  ],
...略...
}
```

# 参照

https://learn.microsoft.com/ja-jp/cli/azure/network/service-endpoint?view=azure-cli-latest
GASで頻繁に使う自作ヘルパ関数まとめ

自分用のgasのヘルパ関数をアウトプットとしてまとめたものです。
逐次追加します。



---
```javascript:fileURLからfile IDのみ抽出して戻す関数
function main(){
  fileUrl = "https://drive.google.com/file/d/hogehogefugafugapiyopiyonyanya123/view?usp=sharing"

  getFileIdFromUrl(fileUrl)
}

// ファイルURLからファイルIDを抽出するヘルパー関数
function getFileIdFromUrl(url) {
  var match = url.match(/[-\w]{25,}/);
  if (match) {
    return match[0];
  } else {
    throw new Error('Invalid file URL');
  }
}
```


---

```javascript:特定の行または列の最終行を取得する関数
// VBAだと特定のセルから行または列の最終セルのインデックスが取得できるのですが、
// それができないので作ったヘルパ関数
function main(){
  const cellIndexObj = {
    row : 3,
    col : 1
  }
  const sheetName = "シート1"

  checkSetValueInCell(sheetName, "row", cellIndexObj)
}

function checkSetValueInCell(sheetName="sheetName", countCellType="row or col", searchStartCellIndexObj={row:1, col:1}) {

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  let countNumber = 0;
  let flag = true;
  let row;
  let col;


  if(countCellType == "row"){
    row = searchStartCellIndexObj.row;

    while (flag) {
      const cellValue = sheet.getRange(row, searchStartCellIndexObj.col).getValue();

      if(cellValue === ""){
        flag = false
      }else{
        row++;
      }
    }
    countNumber = row - searchStartCellIndexObj.row;

  }else if(countCellType == "col"){
    col = searchStartCellIndexObj.col

    while (flag) {
      const cellValue = sheet.getRange(searchStartCellIndexObj.row, col).getValue();

      if(cellValue === ""){
        flag = false
      }else{
        col++;
      }
      
    }
    countNumber = col - searchStartCellIndexObj.col;
  }

  return countNumber;
}
```
【Flutter】Imageのサイズが変わらないときに試してみる

# どういうことか

こんな感じで書いているが、画像のサイズが変更されない。

```dart
Image.asset(
  'assets/user_icon.png',
  color: Colors.grey,
  width: 12,
  height: 12,
),
```

## なんとかする

```dart
Padding(
  padding: const EdgeInsets.all(10.0),
  child: Image.asset(
    'assets/user_icon.png',
    height: 12,
    fit: BoxFit.fill,
  ),
),
```

`BoxFit` を書いてないからか？？と思ったけどそういうことではないらしい。
【ポエム】ABC302参加記

ABC302に参加した
- ABC299に参加していたが、DDoS攻撃によりunratedになった
- そのため、rated参加はABC273（2022年10月）以来
# [A - Attack](https://atcoder.jp/contests/abc302/tasks/abc302_a)
やるだけ……ではなかった
Pythonの浮動小数点はdoubleなのでこの条件だと誤差が出る
サンプルすらACできないのを見逃すのはよくなかった

# [B - Find snuke](https://atcoder.jp/contests/abc302/tasks/abc302_b)
とても実装が重かった
最初に外枠を4文字分意味のない文字で埋めたのは良かったが
4重ループくらいになってしまったのは良くなかった
itertoolsを使いこなせばネストを減らせたり、関数定義を一個減らせたと思う

# [C - Almost Equal](https://atcoder.jp/contests/abc302/tasks/abc302_c)
制約を見た瞬間、重い総当りを疑った
- 結果として当たっていたのでよかった
- itertoolsは便利

この問題の注意点として、違う文字の数が**1文字である必要がある**こと
違う文字の数が2になった瞬間にreturnするアドリブを入れたのは、ACに寄与したか分からないので、なんとも言い難い

# [D - Impartial Gift](https://atcoder.jp/contests/abc302/tasks/abc302_d)
コンテスト中の思考
- 想定解は尺取りのような気がする
- しかし、この制約なら$O( N\log N)$でも間に合う
- - 結果として二分探索で間に合ったのでよかった
- - めぐる式二分探索は思考コストが少ないので好き

# [E - Isolation](https://atcoder.jp/contests/abc302/tasks/abc302_e)
グラフの連結をsetで管理するまでは想定解通りだった
想定解はsetの更新のたびにansをプラマイすること
- そこまで考えが及ばず、総和を求めてしまった
- - 総和を求めるために平方分割を行った
- - Nの最大値が300000だったため、長さ548の配列を準備した

結果、間に合わず1ペナを出した
いらない処理を削ってぎりぎり通った
# 総括
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210433/02189a11-ca6e-be3f-3d5c-b4b785554c2e.png)
![Untitled 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210433/50ab93de-0170-0a9c-4b3c-80ca5f95bf84.png)

Aの反省：この問題でペナを出したのは痛かった……よく考えよう
Eの反省：総和をすぐ求めようとするのはやめよう
それはそれとして、これだけ頑張って緑パフォなのはしんどい……
- とはいえ、これだけの頑張りを必要とするということは、実力が低いということ
- - 実力とは、競プロ慣れや、計算量の見積もり、あるいは頻出ACや頻出WAを頭に入れておくこと
# 余談
数年前から[Myrica](https://github.com/tomokuni/Myrica/blob/master/product/Myrica.md)を自己流にカスタムして使っていた
- 一部の記号を使うとターミナルの表示が崩れたりしていたが、だましだまし使っていた
- が、モダンではないなあと感じていた
- 日本語ユーザ向けのプログラミングフォントを探したところ、[HackGen](https://qiita.com/tawara_/items/374f3ca0a386fab8b305 "Rictyを神フォントだと崇める僕が、フリーライセンスのプログラミングフォント「白源」を作った話")があった
- - 2019年にたわら氏によってリリースされたフォント
- 導入したところ、前述の表示崩れもなくなり、快適

コメントが濃い緑色だったため、黒背景に溶けるように感じた
- 以前は気にならなかった。視力の低下？
- そのため、VSCodeのコメントの配色を`#FF8C00`に変更した。
- - カラーコードは拡張機能のBetterCommentsをパクった。[参考](https://qiita.com/take_me/items/ae0772646dd59630a8b5)
【VSCode】コードが右端までいったら折り返す設定

# はじめに
前回はAndroidStudioの折り返し設定の方法を記事にしました。
今回はVSCodeの折り返し設定をやってみます。

https://qiita.com/SNQ-2001/items/6e0287a13f6c144514ee

# やりかた
① 「Code」を選択します
② 「基本設定」を選択します
③ 「設定」を選択します
![スクリーンショット 2023-05-14 11.40.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/3f94326c-2268-0bb0-3416-2678ec72302f.png)

④ `Word Wrap`と検索します
![スクリーンショット 2023-05-14 11.42.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/ce7dc67f-9114-7c63-b70e-5e2d4075ef75.png)

⑤ 「Editor: Word Wrap」をonに変更します
![スクリーンショット 2023-05-14 11.43.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/b97c7f84-aced-a85e-303a-f92c7ad61ff6.png)

# おわり
折り返し設定が好みです
【JavaScript】bit全探索を勉強しました

# 記事にした背景
Atcoder（JavaScript）で挑戦中にbit全探索に出会ったのですが、まったく手が出せなかったので、勉強がてら記事にしました。

# 参考にさせていただいた記事
[@u2dayo様](https://qiita.com/u2dayo)の以下の記事を参考にさせていただきました。
- [1. 入門編 bit全探索ってなに？](https://qiita.com/u2dayo/items/68e35815659b1041c3c2) 

# bit全探索とは？
参考にさせていただいた記事の[1. 入門編 bit全探索ってなに？](https://qiita.com/u2dayo/items/68e35815659b1041c3c2) によると、以下のように記述されています。

> 『ありえる選択肢の組み合わせ方を全てもれなく列挙』して、『一つ一つの組み合わせに対して計算や判定を行う』ことで、答えを見つけるアルゴリズム

ただし、制約として以下も記述されています。
> bit全探索は、選択肢の数 $N$が比較的小さいときでないと使えません。

> 処理の複雑さにもよりますが、$N≤20$が実行時間制限に余裕を持ってbit全探索を使える目安です 。

では、実際にbit全探索を使用して例題を解いてみましょう。
# 例題
$N = 1,3,4$のとき、Nの部分集合の合計$S$が$S = 4$となる部分集合はいくつあるか？

# 解き方
1. すべての部分集合を求める。
空集合$, ｛1｝, ｛3｝, ｛4｝, ｛1, 3｝, ｛1, 4｝, ｛3, 4｝, ｛1, 3, 4｝$

2. 1のうち$S = 4$となるものを求める。
$｛4｝, ｛1, 3｝$

以上の通り、$2$が解となります。

# アルゴリズムを考える
## 1. すべての部分集合を求める。
ここでは2進数を使用して考えてみます。0を使用しない、1を使用するとして以下の表をご覧ください。

| 1 | 3 | 4 | 部分集合 | 
|:-:|:-:|:-:|:-------:|
| 0 | 0 | 0 |  空集合　|
| 0 | 0 | 1 | {4} |
| 0 | 1 | 0 | {3} |
| 0 | 1 | 1 | {3, 4} |
| 1 | 0 | 0 | {1} |
| 1 | 0 | 1 | {1, 4} |
| 1 | 1 | 0 | {1, 3} |
| 1 | 1 | 1 | {1, 3, 4} |

すると使用するNの個数が3なので、3桁の2進数ですべての部分集合の組み合わせを求めることができます。

では、3桁の2進数の組み合わせを求めるコードを以下に記述します。

```
function calcAllC(){
    newBox = [];
    for(let i = 0; i < (1 << 3); i++){
        newBox.push(i.toString(2).padStart(3, '0'));
    }

    console.log(newBox);

}
```
- 1 << 3 は1を左に3シフトする
- .toString(2)は2進数表記に変換する（ただし文字列になる）
- .padStart(3, '0')は3桁になるよう0で埋める
という意味です。

この関数を呼び出すと以下のように出力されます。

```
[
  '000', '001',
  '010', '011',
  '100', '101',
  '110', '111'
]
```

## 2. 1のうちS = 4となるものを求める。
1で求めた組み合わせを1件ずつ取り出し、処理します。1の場合は仮の合計値に足します。例えば、取り出した組み合わせが「110」の場合は、1x1 + 1x3 + 0x4となります。最後に$S$と一致すれば$count$の値を1増やします。

```
   
   // すべての2進数の組み合わせを1つずつ処理する
   for(target of allC){
        targetC = target.split(/(?!$)/u);
        sum = 0;

        // 2進数の組み合わせを1桁ずつ処理する
        for(let j = 0; j < targetC.length; j++){
            // 1(使用する)の場合はsumに足す
            if(targetC[j] === "1"){
                sum += nums[j];
            }
        }
        // （すべての桁の足し算が終わり、）sumの値が4の場合はcountに1を足す
        if(sum === targetSum){
            count++;
        }
   }

```
## 最終的なコード
```
function Main(input){
  
   targetSum = 4;
   nums = [1, 3, 4];
   allC = calcAllC();

   count = 0;
   
   // すべての2進数の組み合わせを1つずつ処理する
   for(target of allC){
        targetC = target.split(/(?!$)/u);
        sum = 0;

        // 2進数の組み合わせを1桁ずつ処理する
        for(let j = 0; j < targetC.length; j++){
            // 1(使用する)の場合はsumに足す
            if(targetC[j] === "1"){
                sum += nums[j];
            }
        }
        // （すべての桁の足し算が終わり、）sumの値が4の場合はcountに1を足す
        if(sum === targetSum){
            count++;
        }
   }

   console.log(count);

}

function calcAllC(){
    newBox = [];
    for(let i = 0; i < (1 << 3); i++){
        newBox.push(i.toString(2).padStart(3, '0'));
    };

    return newBox;
}

// Main関数の実行
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
```
Youtube V3 Data APIで401に詰まった話

# 概要
Youtube V3 Data APIを使用して再生リストを作成したようとした際に401のエラーが出てしまい、解決に苦労してしまいました。

# 結論
YouTubeチャンネルを作成していないのが問題でした。

問題解決にStackoverFlowの回答を参考にしました
> The reason "youtubeSignupRequired" usually means the YouTube account has not been set up properly or you have not created your YouTube channel yet. This is a requirement before you can upload videos. It would be great if Google could improve their error message for this case and make it a bit more verbose.

翻訳
> 理由「youtubeSignupRequired」は通常、YouTubeアカウントが適切に設定されていないか、まだYouTubeチャンネルを作成していないことを意味します。これは、動画をアップロードする前に必要な手順です。Googleがこの場合のエラーメッセージを改善し、もう少し詳細な情報を提供してくれると良いでしょう。

# エラーの詳細
```json:response
{
    "error": {
        "code": 401,
        "message": "Unauthorized",
        "errors": [
            {
                "message": "Unauthorized",
                "domain": "youtube.header",
                "reason": "youtubeSignupRequired",
                "location": "Authorization",
                "locationType": "header"
            }
        ]
    }
}
```


## 参考
https://stackoverflow.com/a/17621982
npm-check-updatesを導入【プロジェクトをUpdateしてく！-➃】

## 今回行った一連の流れ

➀[nodistをvoltaへ変更](https://qiita.com/kusaharajiji/items/7c7e7bde129fb8880f34)
➁npm-check-updatesを導入
➂gulp-sassをgulp-dart-sassへ変更
➃bootstrapを使用したプロジェクトの場合、bootstrapのアップデート　←今回ここをpick up☆
 
 

## 経緯
新しいプロジェクトを任されることに。そのプロジェクトをクローンしたらnpx update-browserslist-db@latestのコマンドがnpx gulpで常にでてきてしまうことに気づき、さらに元々プロジェクトを担当していた人と開発環境が違ったためgulpファイルの追記と修正が必要になった。

以上のことから、「一連の流れ」を行うことになった。
上記の項目ごとに備忘録として記事を書くことにした。



## 前提

- windows 
- nodistをパッケージマネージャーとして使用
- bootstrapバージョン4を使用
　
　　
　
　
　
## 【npm-check-updatesを導入】

※この記事は続き記事です。
　項目ごとに記事わけしているので単体でも活用していただけます。

### 《目次》
- npm-check-updatesとは
- npm-check-updatesをインストール
- npm-check-updates手順
　
　
　
　
### ＜npm-check-updatesとは＞
npmの取得モジュールのアップデートをチェックしてくれるライブラリ
一括アップデートも行ってくれるので今回のように全体をアップデートする時は特に便利。

　
　
### ＜npm-check-updatesをインストール＞
```:インストールコマンド
npm i -D npm-check-updates
```
 　※voltaがグローバル非推奨なので。ローカル「-D」
 　
 　
### ＜npm-check-update使用手順＞
インストールしたら以下の手順でコマンド

```:新しいバージョンがあるか確認
npx npm-check-updates
```

```:全部一括でアップデート
npx npm-check-updates -u


　#上記のコマンドをしたら
　npm install
　
　#もし以下のコマンドを上記のコマンド後に使用するか聞かれたら１度使用しておく
　npm audit fix
```
※-u のコマンドはpackage.jsonへの書き込みだけ。
　なのでnpm installが必要


##### Update完了！

　
　
　

## ◆◆次回はgulp-sassをgulp-dart-sassへ変更を導入◆◆

#### 次回
[「gulp-sassをgulp-dart-sassへ変更する【プロジェクトをUpdateしてく！-➄】」](https://qiita.com/kusaharajiji/items/cfd1a7be0129fee7ed6d)
Falcor とは何か？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/8a38340f-3864-c50b-572b-6c6f94269cd7.png)

こんにちは、初めての方でもわかるように、Netflixが開発したJavaScript用のプログラミングライブラリ、Falcorについて説明します。

## 1. Falcorとは何か？

Falcorとは、データを効率的に扱うためのツールです。
このツールはJavaScriptのライブラリで、Netflixから生まれました。
特にウェブアプリケーションで重宝されています。

https://netflix.github.io/falcor/

## 2. Falcorの役割

Falcorの役割は、フロントエンドとバックエンド間の通信を効率化することです。

複数のAPIエンドポイントからデータを要求するとき、一つ一つ別々に要求する代わりに、Falcorを使って一括で要求することができます。
これはAPI呼び出しの数を減らし、ネットワークの遅延を最小限に抑えるのに役立ちます。

## 3. Falcorの特長

Falcorの大きな特長は、すべてのリモートデータソースを単一のドメインモデルとして扱う能力です。
これはどういうことかというと、データがどこにあっても（ローカルでもリモートでも）同じようにアクセスできるということです。

また、Falcorは「グラフ指向」です。
つまり、データはグラフという形でモデリングされ、このグラフはパスを使ってアクセスされます。これにより、関連データの読み取りと書き込みが一元化され、効率化します。

## 4. Falcorを使うメリット

Falcorを使うと、コードがシンプルになり、エンドポイントの管理が楽になります。

また、ネットワークの遅延を減らすことができ、パフォーマンスを向上させることが可能です。


## 5. FalcorとGraphQLの違い
FalcorとGraphQLはともに、データをフロントエンドから効率的に取得するためのツールですが、その設計思想と使い方にはいくつかの重要な違いがあります。

### **1. 設計哲学:**
**Falcor:** Falcorはすべてのリモートデータを単一の仮想JSONオブジェクトとして扱います。このオブジェクトは、必要な部分を選択し要求することができます。その結果、リモートデータソースをあたかもローカルデータのように扱うことが可能となります。

**GraphQL:** GraphQLはデータをグラフとして表現します。クライアントは必要なデータを明示的に要求し、それに応じた形式でデータを受け取ります。これにより、不要なデータの取得を防ぎ、データ通信のオーバーヘッドを削減します。

### **2. データ取得:**
**Falcor:** Falcorはパスベースのクエリ言語を使用します。データ要求はJavaScriptのオブジェクトパスを使用して記述されます。

**GraphQL:** GraphQLでは、取得したいデータを詳細に記述する独自のクエリ言語を使用します。これにより、クライアントは必要なデータだけを取得することができます。

### **3. 一般的な用途:**
**Falcor:** Falcorは多くのAPIエンドポイントに跨る複雑なデータ要求を単一の要求に統一化するのが得意です。これは大規模なウェブアプリケーションで特に有用とされています。

**GraphQL:** GraphQLは特に柔軟性と効率性が求められる場面で強みを発揮します。また、APIを公開する際にもよく使用され、サードパーティの開発者が必要なデータを自由にクエリできるようにします。

どちらを選ぶかは、あなたのプロジェクトの要件と目標によるところが大きいでしょう。


## 追記： Falcorのコード例

Falcorでは、JSON Graph形式でデータをモデル化します。この形式では、データはツリーやグラフ構造を取り、各ノードにはパスが存在します。

以下に、JSON Graphとそのパスを使ったデータアクセスの簡単な例を示します。

まずはFalcorのModelを作成し、それにJSON Graph形式のデータを設定します。

```javascript
var falcor = require('falcor');
var model = new falcor.Model({
  cache: {
    users: [
      {
        id: 1,
        name: "John",
        friends: [{ $type: "ref", value: ["users", 1] }]
      },
      {
        id: 2,
        name: "Jane",
        friends: [{ $type: "ref", value: ["users", 0] }]
      }
    ]
  }
});
```

上記のデータモデルでは、2つのユーザーがおり、それぞれに名前と友人リストがあります。友人リスト内のオブジェクトは参照型（"$type": "ref"）であり、別のユーザーへのパスを指定します。

次に、特定のユーザーの友人の名前を取得するためのFalcorパスを使用します。

```javascript
model.getValue(['users', 0, 'friends', 0, 'name'])
  .then(name => console.log(name)); // prints: "John"
```

このパスは、`users[0].friends[0].name`へのアクセスに相当します。Falcorは参照（`{ $type: "ref", value: ["users", 1] }`）を透過的に解決し、最終的な値を取得します。このようにFalcorを使用すると、グラフ内の複雑な関連データに容易にアクセスできます。

注意点としては、これらのコード例は基本的な使用方法を示していますが、実際のアプリケーションではデータは通常リモートサーバーから取得し、特定の操作（例えばFalcorのRouterを使用したルーティング）を行う必要があります。
RHEL7 (pam_krb5) から RHEL8 (sssd) へのインプレースアップグレード時の前準備

この記事は、Kerberos認証(pam_krb5モジュール) を利用している RHEL7 を、RHEL8 へインプレースアップグレードする際に、問題となる事象とそれを解決する手順をまとめる。

## 前提とやりたいこと
...と、文章で書くと長くてわかりにくかったので、箇条書きでまとめよう。

- 現行サーバ：　　RHEL7 で kerberos認証(pam_krb5モジュール) を利用している
- やりたいこと：　構成はそのままに RHEL8 へインプレースアップグレードしたい
- 問題点と解決策：RHEL8 には pam_krb5 がないため、代わりに SSSD を利用する必要がある
- その際の注意点：下手な手順を実行した場合、ロックアウトされて手詰まりになる

単純な pam_krb5 -> SSSD への移行手順などは、RHEL公式サイト(本記事最下部参照)に掲載されているんだけど、
上手く読み合わせないで作業していくと、途中でシステムからロックアウトされてしまう。

SSHログインして作業するならともかく、Ansibleで実施する場合は特に手順を工夫しないと、実行が途中で止まってしまう...。※実体験済み

## 手順

手順の概要としては単純で、SSSD を有効化 → pam_krb5 を無効化 の順番で実施するだけ。

(1) SSSD のインストールと有効化
```
yum install sssd
authconfig --enablesssd --enablesssdauth --update
```
→ これにより、/etc/nsswitch.conf の一部が sss を利用できる形に更新される

(2) /etc/nsswitch.conf の修正 ("services" に "sss" を追記)
```
services: files sss
```
※当方環境(RHEL7.8)の場合、この作業は不要だった

(3) /etc/sssd/sssd.conf の修正
- service, domain 等の情報を環境に合わせて設定。
- パーミッションを 600, root:root に設定。

(4) SSSD の再起動
```
systemctl restart sssd.service
```

(5) pam_krb5 の無効化
```
authconfig --disablekrb5 --update
```

(6) PAM構成ファイルの修正
```
/etc/pam.d/system-auth
/etc/pam.d/password-auth
```
→ 修正内容は元の記述によると思うけど、当方環境では pam_krb5.so が記載されている部分を pam_sss.so に修正するだけで大丈夫だった。


これで、RHEL8へのインプレースアップグレードで、pam_krb5 が削除されても大丈夫！
（でもロックアウトには十分気をつけて、検証してから実施してね！）

----
<b>参考サイト</b>
> Red Hat Enterprise Linux 8 で pam_krb5 から SSSD に移行する方法
> https://access.redhat.com/ja/solutions/6098441

> RHEL 7 から RHEL 8 へのアップグレード > 9.3. 既知の問題
> https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/upgrading_from_rhel_7_to_rhel_8/known-issues_troubleshooting

> RHEL 7 システムレベルの認証ガイド > 7.5. SSSD のシステムサービスの設定
> https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system-level_authentication_guide/configuring_services
【学習記録02】JavaScript　関数で引数を使う

# 関数の作り方
関数の定義方法には2種類ある。
1, アロー関数
```diff_javascript
const 定数名 = () => {
    処理内容
}
```
2,関数宣言
```diff_javascript
function 関数名(){
    処理内容
}
```

## 関数名の付け方
関数名は基本的に、「動詞＋目的語」で作る。
例：addProduct

# 引数を使った処理を行う
## 処理内容
値段と税を引数で受け取り合計金額を計算する
3000円以下の場合、送料が500円
3000円以上の場合、送料が無料
請求金額を計算する。

## コード
```diff_javascript
const calculateTotal = (price, tax) => {
    if(price * tax < 3000){
        let shoppingFee = 500;
        console.log('合計金額は' + price * tax + '円です。3000円未満なので、送料は500円です。');
        console.log('請求金額は' + (price * tax + shoppingFee) + '円です。');
    }else{
        let shoppingFee = 0;
        console.log('合計金額は' + price * tax + '円です。3000円以上なので、送料は無料になります。');
        console.log('請求金額は' + (price * tax + shoppingFee) + '円です。');
    }
}

calculateTotal(2000, 1.08);
```
これからの時代求められる品質②

# 前回のつづき
この記事は１つ手前の【これからの時代求められる品質①】の続きに該当する記事である。
書きながら希望と夢を感じ、同時に多くの人に理解されないこの素晴らしい品質という、
わが子のようなものに対して向き合っていたら号泣しながら書いていた。
そのため誤字脱字は許してほしい。

# モノからコトへ
SaaSなどがいい例であり、シェアリングエコノミーなども進んできている昨今では、
これからもモノを【所有】することから必要な時だけ【利用】する流れが進む。

所有していた際に求められる利用者がモノの品質を重視していた過去と違って、
これからはコトの品質、つまりServiceビューの品質とその先にどんな目的を達成したいのか？
といったものへの品質へと観点を変えなくてはならない。

つまり、モノの品質の上で成り立つ、コトの品質の観点へと変換しなくてはいけないため、
全く異なる観点の品質特性まで考慮しなくてはいけない。

そのサービスを利用することによって
・どのくらい快適なのか？
・どのくらい安心して利用できるのか？
・どのくらい面白いと感じることができるのか？
・どのくらい自分たちが成長しあえたと感じることができるのか？
といった【感情を伴う価値】、いわば【感動体験】を満たす品質特性が重要視される。

## 自動車業界の変化
これまでの【所有】する時代では、
・高耐久性
・安定性
といった品質が重要視されてきたが、

【利用】する時代においては、耐久性といったものよりも
予期せぬ事態を予測できること、故障とかする前にメンテナンスできることが求められる。
つまり、コードの不吉なニオイと同様に
リスクの兆候の香りがしやすい、分析しやすい構造であることと、高いメンテナンス性が求められる。
そのため今まで以上に迅速に最適なアーキテクチャにすることが求められる。

田舎とかみたいな一家に数台車があるような状況下では、
【所有】が求められる品質になることがまだまだ続くと予想されるが、
都市部のようなそもそも車を【所有】ではなく、【利用】するような場合ではコトへの品質が強く求められる。

これはどのように計測するのだろう？と思ったが、
ユーザーからのフィードバック内容だけではないことに気づいた。
というのも、多くのユーザーは自分の内情になんて気づけてはいないから、
その瞬間にどの程度「うわ✨」て感動したか？だけでは、品質を十分に考慮できているとは言えない。
表面的なフィードバック内容だけでなく、製品を使った後こんな行動をするはずだよね、
仮にその瞬間喜んでいなくても、心の奥底でキッカケをつくることができれば、
昨日まで行動していなかった人が、さっそく別の行動をとり始めるかもしれない。
このような行動予測を事前に建てたうえでデータ集計によって検証したうえで、
そのユーザーがいまこの瞬間嬉しいではなく、ある程度時間をかけたうえで
「あのサービスを利用したおかげでいまのこの嬉しさがあるんだ」と実感できるという、
未来時点でのユーザーっていう観点での品質の考慮も非常に重要であると感じた。

## これを用いてアナロジーに展開
製品もヘヴィユーザーに対する製品の品質（所有観点での品質）と、
たまにしか利用しないライトユーザー向けの品質（利用観点での品質）とで
分けなくてはいけないことが予想できる。
現状の製品の品質は、ヘヴィユーザー向けであるため、ライトユーザーは他の製品に浮気しがち。
かといって１つの製品にヘヴィユーザー向けの品質とライトユーザー向けの品質両方を
盛り込んでしまうのは、今の強みのとがった部分が削れてしまうため危険とみている。
競合相手たちと柔軟に手を取り合って、
ヘヴィユーザー向けサービスとライトユーザー向けサービスの両方を実現することが求められる。
もちろんそこへは「売り上げがどうの～～」とかいったリスクは絡んでいるが、
コトへの時代を生き抜くには競合相手達とお互いの強みを生かし合うように手を取り合わなくてはいけない。
これはSoSが表現している性質とまさにそっくりである。
さらにその組織を超えた体験を経て私たちがどんな感動体験をゲットするのか？
使ったユーザーが使ってみてどんな嬉しい体験をするのか？
もっとモデリング初心者の人々も議論に参加できることでアイデアが拡がりやすくなるとか
そのような体験に関する品質まで考慮する必要があると考えられる。

## SoSでの利用
システム同士も所有から利用へシフトチェンジ。
何でも１つのシステムで実現しようって考えるのではなく【ないものは外部のものを利用する】ていう思考へ。
めちゃくちゃ頻繁にしかも密に利用するサービスならばそれは所有サービスになるから、
自分のとこに統合してしまうって考えるのありだが、
そんなに高頻度でなく疎結合なサービスであるならば、外部のものを使って連携するって考える。


# 組織同士のコラボレーション
通常のシステム以上にSoSでは、受託先と依頼先のコラボレーションが求められる。
というのも、SoSに異なる強み・特性が求められる者同士を連携させて１つの大きな目的を達成するのと同様に、
組織同士でもこのような連携をしてさらに大きな目的を達成するという体験を
アーキテクトチームだけでなく組織レベルで体感すること、
強いコラボレーションによって組織という壁を超えて顧客の成し得たいことをお互いに達成することに注目することが求められる。

プロジェクトというイベントを通して組織を超えて他のメンバーとの繋がり、
共に成長したという実感、大切にしてる価値観の共有といった感動体験を体感できること
がSoS×DXプロジェクトに求められる　感情を伴う品質　である。

次の③記事へつづく
【検証：ChatGPT】AIとの効果的なコミュニケーション方式とは①

# はじめに
ChatGPTなどの大規模言語モデル(LLM)の発展に伴い、直接的あるいは間接的にAIとコミュニケーション[^1]する機会が増加していくことが予想されます。本記事では、AIとの「効果的なコミュニケーション[^2]」の方式を見つけるため、シチュエーションとUIに着目し、長所と短所について検証[^3]しました。今回は検証結果から最もおすすめの構成を紹介します。また、具体的な検証について[次回記事](https://qiita.com/motonobu_ut/items/5275dd6441b14fbe61ab)に掲載しております。




# おすすめ構成
本記事における、おすすめのAIとのコミュニケーション方式のデモとイメージ図です。この例では最初に「日本のファッションの歴史」という議題を与えたところ、画面右上のスライドが自動生成され、3Dモデルであるユニティちゃんが画面右下の発話内容を読み上げています。また、システム内の複数のエージェントが自動的に3Dモデルの発話にコメントをすることで、利用者のアイディエーションを促しています[^4]。
 
![3D_Gif](https://github.com/utmoto/HITL/assets/17790965/2b4d895b-b40d-4666-b354-a0f20cd1b389)
<strong>デモ © Unity Technologies Japan/UCL</strong>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/892617/161c6154-836b-7f5c-bf7f-57bee45700a6.png) 
<strong>イメージ図</strong>

### 構成
-	**台本**：ChatGPTに、議題についての解説を提案させる
-	**スライド**：文や章単位で、画像生成AIを使用してイメージ画像を作成、
発表時は手動でページを遷移可能でページごとに対応した台本が読み上げられる
-	**3Dモデル**：台本の読み上げと人間からの質問応答を合成音声で対応。スライド進行にあわせ3Dモデルが発話し、人間やコメント欄はそれに反応する流れ
-	**発話内容表示部**：３Dモデルが現在読み上げている内容、応答している内容を表示
-	**コメント欄**：発話内容や人間の質問を入力に、異なる初期設定を与えられたエージェントが更新。コメント欄で質問がでると、コメント欄にその質問の回答がつく

# おすすめ理由
上記の構成は、「議題」を与えるだけで台本とスライドが生成され、コメント欄を用いてアイディエーションすることができるため、1人の人間とAIとがコミュニケーションするシチュエーションにおける「効果的なコミュニケーション」を満たすと考えています。
より具体的には、以下2点を試行錯誤した結果できあがったものです。
- AIエージェントの数をいくつにするか
- 言語モデルだけを使用する場合と、３Dプラットフォームを活用した場合の違い　　

それぞれの試行結果や、このような構成に至るまでの考え方については、次回の記事でご紹介する予定です。

# 使用技術
- 言語モデル：ChatGPT API (gpt-3.5-turbo)[[参考1](#参考)]
- 音声認識：Whisper API[[参考1](#参考)]
- 3Dプラットフォーム：Unity Pro（エディターver：2021.3.0f1）[[参考2](#参考)]
- 3Dモデル：unity-chan（unitychan.unitypackage ver.1.1.1）[[参考3](#参考)]
- 合成音声：VoiceVox [[参考4](#参考)]（VOICEVOX:春日部つむぎ[[参考5](#参考)]）※本記事中に音声なし
- 口パク：uLipSync[[参考6](#参考)]
- 3D空間背景：Skybox AI(v0.3.0 alpha) [[参考7](#参考)]、Wispy Skybox [[参考8](#参考)]
- 画像生成：stable diffusion ver1-4[[参考9](#参考)]

# 参考
1.	Introducing ChatGPT and Whisper APIs https://openai.com/blog/introducing-chatgpt-and-whisper-apis
2.	Unity Pro https://unity.com/products/unity-pro
3.	unity-chan  https://unity-chan.com/  © Unity Technologies Japan/UCL
4.	VOICEVOX  https://voicevox.hiroshiba.jp/
5.	VOICEVOX 春日部つむぎ https://voicevox.hiroshiba.jp/product/kasukabe_tsumugi/
6.	uLipSync  https://github.com/hecomi/uLipSync
7.	skybox AI  https://skybox.blockadelabs.com/
8.	Wispy Skybox  https://assetstore.unity.com/packages/2d/textures-materials/sky/wispy-skybox-21737
9.	Rombach, Robin et al. “High-Resolution Image Synthesis with Latent Diffusion Models.” 2022 IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR) (2021): 10674-10685.  https://huggingface.co/CompVis/stable-diffusion-v1-4



[^1]: 本記事では 、「AIに議題を投げかけ、AIから知識や見識を得ること」を想定
[^2]: 本記事では 、「人間が気軽に、効率よく、有益な知識や見識が得られること」とする
[^3]: 検証での評価は主観的な意見のため、あくまでご参考としていただければ幸いです
[^4]: 発話内容とそれに対するコメント例は以下です。コメントの信憑性が高いとは限りませんが、アイディエーションツールとしては効果的な可能性があります。
**発話内容**：
平安時代（794-1185年）には、貴族文化が隆盛し、色鮮やかな十二単や縫い目の美しさを追求する「縫取り」が流行しました。
**コメント**：
  ・　QA：
Q. 和装において、平安時代の「縫取り」はどのような意味や美意識を表しているのでしょうか？
A. 平安時代の「縫取り」は模様の形成を通じて和服の美しさを追求する美意識を表し、植物や動物の形を織り込んで自然美や多様性を表現する意味もあります。
  ・　用語説明：「縫取り」とは、平安時代に流行した縫い目の美しさを追求する貴族文化の一つ
  ・　アイデア喚起：「和装から学ぶ美意識」というテーマで、自分なりの和装コーディネートを考えてみよう
Wordpressでページによってヘッダーの画像を変える【アイキャッチ版】

前回、「投稿・固定等ページによって指定した画像をヘッダーに表示する」という投稿をしました。（下記ページ参照）

https://qiita.com/makkie/items/eb17cc062af41fa1ebac#%E3%81%BE%E3%81%A8%E3%82%81

今回は、前回のパターンだと、Webサイト開設当初に設定した画像がそのままになってしまい、商品画像等を表示していた場合、既に販売していない等で改修をしなくても、都度お客様側で修正できるように、「アイキャッチ画像をヘッダーに表示する」というものです。

# はじめに
`functions.php`にコードを追加しますので、必ず本番環境ではなく、ローカル環境もしくはテスト環境で作業を行ってください。
デバックモードをONにするのも忘れずに。

```wp-config.php
define( 'WP_DEBUG', true );
```

## アイキャッチ機能を有効化
（これもうWordpressで標準でONにしておいてくれないかな）
`functions.php`に下記コードを追加します。

```functions.php
//アイキャッチON
add_theme_support('post-thumbnails');
```
## 完成イメージ
前回記事と同様、画像を背景に置き、タイトルを上にのせて表示します。
前回の記事と違うのは、今回「アイキャッチ画像を背景に置く」ことです。
![header.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004345/79d0fc06-1643-82b9-c5d8-04c298f2f5fc.jpeg)

## コード（PHPとHTML）
`header.php`の各ページのヘッダーになる部分に下記コードを追加します。
このコードは、`if ( !is_home() || !is_front_page()) {`としていますので、`home`と`front_page`では下記処理は行いません。
```header.php
<?php
if ( !is_home() || !is_front_page()) {
    if( has_post_thumbnail() ) {
        $thumburl = wp_get_attachment_url( get_post_thumbnail_id($post->ID) );
    } else {
        $thumburl = get_template_directory_uri(). '/images/noimages.jpg';
    }
?>
```
TOP以外のページを表示した時に、`if( has_post_thumbnail() ) {`でアイキャッチがあるかどうかを判定して、アイキャッチのURLを変数に格納しています。
ない場合は`Noimages.jpg`が表示される様に、変数に`Noimages.jpg`のURLを格納しています。

:::note warn
ただ、この`Noimages.jpg`が表示されるのは、サムネイルとして表示される分にはいいのですが、画面横幅いっぱいに`Noimages`はどうなのかな？という疑問が残る処理ではあるので、どんなジャンルのページで表示しても問題ない、無難な完成イメージの様な画像を用意して表示させるのが良いかと思います。
:::

```header.php
<header class="subheader" style="background-image: url('<?php echo $thumburl; ?>')">
    <h1><?php the_title(); ?></h1>
<?php
}
?>
```
上記コードで取得した画像URLを`style="background-image: url`に入れます。

## コード（CSS）
あとはCSSで整えて完了です。
```diff_css
.subheader {
    position:relative;
    width:100%;
    height:300px;
    background-position: center center;
    background-size: cover;
    background-repeat: no-repeat;
}
    .subheader h1 {
		position:absolute;
		top:50%;
		left:5%;
		font-weight:bolder;
        color: #fff;
	}
```
:::note warn
アイキャッチのURLを取得して`header`に`style="background-images: `に入れているため、CSSでプロパティをまとめて指定することができません。
必ず`background-position` `background-size` `background-repeat`と個別に指定してください。
:::

# まとめ
各ページを表示した時に、アイキャッチのURLを取得して`header`に`style="background-images: `を指定してアイキャッチをヘッダーに指定すると言うやり方を紹介しました。

折角WPの機能として「アイキャッチ」があるので、これを利用してサイトの見栄えをよくし、それぞれのページの特徴を表せる良い機会なので是非実装してください。


毎度、WPで15年ほどWebサイトを制作していますが、独学の為、解釈が違ったり記述が間違えていたりという部分あるかと思います。その場合は、ぜひコメントで教えていただけると幸いです。
lualatexで画像が表示されないときの対処法

~~lualatexでの画像挿入がうまくいかない．~~
解決法が見つかった．

# 目次
[1. 解決前の状況](#1-解決前の状況)
[2. 解決した方法](#2-解決した方法)
[3. おわりに](#3-おわりに)


# 1. 解決前の状況

- ２つのエディター (overleaf, Texworks editor)で実行したがどちらもうまくいかない
    - エラーは発生せず，ただ実行結果に画像が映らない．画像が入るべき場所が空白になる
- uplatexでは普通に成功する
- 拡張子はpngとjpgを試したがどちらもダメ
- latexの知識はほとんどない
    - 今回は組織から配布されたテンプレートを使用

# 2. 解決した方法
以下のコードを追加し，
```tex
\usepackage[colorlinks=true, allcolors=blue]{hyperref}
```
以下のコードを削除．
```tex
\usepackage[dvipdfmx]{color}
```

修正後のlualatexのプリアンブル部分（無駄な部分が多いが，それを含めて参考になるかもしれないので残しておく）

```tex:lualatex.tex
\usepackage[top=5truemm,bottom=5truemm,left=10truemm,right=10truemm]{geometry}
\usepackage{luatexja-preset}
\usepackage{}
\usepackage{multirow}
\usepackage{latexsym} %記号追加
\usepackage{cite} %cite拡張
\usepackage{mathtools,amsmath,amsthm,amssymb} %数学関係
\usepackage{enumerate}	%列挙用
\usepackage{titlesec} %見出しの見た目変更
\usepackage{url} %URL記述
\usepackage{setspace} %余白制御
\usepackage[dvipdfmx]{graphicx}
\usepackage[colorlinks=true, allcolors=blue] {hyperref} %追加箇所
%\usepackage[dvipdfmx]{color}　削除箇所
\usepackage{siunitx}
\usepackage{listings}
\usepackage{ulem}
\usepackage{enumitem}
\usepackage{comment}
```
# 3. おわりに

今回はネットに転がってるシンプルなテンプレートからヒントが得られた．当たり前かもしれないが，理屈がわからずとも成功例から盗み取ってとりあえず形にするのはプログラミングするうえでは大事だと思った．
(リンクだけです)「ゼルダの伝説（英:The Legend of Zelda）」を調べた。

https://www.deepl.com/ja/translator#ja/en/非常に奥が深そうなので、さわりだけにしました.

# 公式

https://www.nintendo.co.jp/character/zelda/

https://www.zelda.com/

# wikipedia

https://ja.wikipedia.org/wiki/%E3%82%BC%E3%83%AB%E3%83%80%E3%81%AE%E4%BC%9D%E8%AA%AC%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA

https://en.wikipedia.org/wiki/The_Legend_of_Zelda

# 参考

https://news.yahoo.co.jp/byline/tokurikimotohiko/20230521-00350392

https://www.google.com/search?q=%E3%82%AF%E3%83%A9%E3%83%95%E3%83%88%E7%B3%BB%E3%82%B2%E3%83%BC%E3%83%A0+%E3%81%A8%E3%81%AF&rlz=1CAUHAM_enJP1038JP1038&sxsrf=APwXEdcnBomGiZfKF7sDLcjfYgqmYtt4rg%3A1684737658230&ei=eg5rZK3TDZb3-QbDmoPwDw&ved=0ahUKEwit-KHtqIj_AhWWe94KHUPNAP4Q4dUDCA8&uact=5&oq=%E3%82%AF%E3%83%A9%E3%83%95%E3%83%88%E7%B3%BB%E3%82%B2%E3%83%BC%E3%83%A0+%E3%81%A8%E3%81%AF&gs_lcp=Cgxnd3Mtd2l6LXNlcnAQAzIECAAQHjoKCAAQRxDWBBCwAzoICCEQoAEQwwQ6BggAEB4QDUoECEEYAFDyGVjhHmC7J2gBcAF4AIABiAGIAdoDkgEDMC40mAEAoAEByAEKwAEB&sclient=gws-wiz-serp

https://ja.wikipedia.org/wiki/Steam

https://en.wikipedia.org/wiki/Steam_(service)
ChatGPT-3.5のAPIを利用する際、文字コードEUC-JPのままだとうまくいかない

文字コードEUC-JPのデータにてChatGPT-3.5のAPIを利用しようとしたら、データが空で返ってきたのでメモ。

【環境】
文字コード：EUC-JP
言語：php7.4
OS：Amazon Linux

chatGPT-3.5に原因を聞いたところ下記内容が返ってきた。

```
★chatGPT-3.5★

文字コードEUC-JPは、日本語の文字エンコーディング方式の一つですが、
GPT-3.5モデルはEUC-JPを直接サポートしていません。
GPT-3.5はUTF-8文字エンコーディングを使用しており、日本語のテキストを
正しく処理するためには、入力テキストをUTF-8に変換する必要があります。

EUC-JPのテキストをUTF-8に変換する方法は、プログラミング言語や
環境によって異なりますが、多くのプログラミング言語には
文字エンコーディングを変換するための便利なライブラリや関数が存在します。
```

他の文献を調べても詳しい情報が見つけられなかったため、
今のところChatGPT側に送る時はutf-8に変換する必要があるとのことで認識。
passwdとshadowとgroupを結合

```
#!/bin/bash

# プライマリグループ名を取得するための辞書を作成します。
declare -A primary_group
while IFS=: read -r user pass uid gid rest; do
  primary_group["$user"]=$(getent group "$gid" | cut -d: -f1)
done </etc/passwd

# ユーザー情報とプライマリ・セカンダリグループを表示します。
while IFS=: read -r user pass uid gid gecos home shell; do
  primary=${primary_group["$user"]}
  secondary=$(id -Gn "$user" | tr ' ' '\n' | grep -v "^${primary}$" | paste -sd, -)

  shadow_info=$(getent shadow "$user")
  min=$(echo "$shadow_info" | cut -d: -f4)
  max=$(echo "$shadow_info" | cut -d: -f5)
  warn=$(echo "$shadow_info" | cut -d: -f6)
  inactive=$(echo "$shadow_info" | cut -d: -f7)
  password_hash=$(echo "$shadow_info" | cut -d: -f2)

  echo "$user:$uid:$gid:$primary:$secondary:$home:$shell:$min:$max:$warn:$inactive:$password_hash"
done </etc/passwd | sort -t: -k2 -n
```
【Ruby】イベント期間など、特定の期間に現在時刻が含まれるか判定する関数を作る

## 前提
現在時刻が、特定の期間に含まれるか判定する関数を定義する必要がありました。
実装の過程でアドバイスをいただいて改善されたので、前後でどのように変わったのかまとめます。
Railsで実装しています。

## 元々実装していたコード

```ruby
def event_period?()
  now = Time.now
  # 1月1日から1月31日まで
  event_start_day = Time.new(2023, 1, 1, 0, 0, 0, "+00:00")
  event_end_day = Time.new(2023, 2, 1, 0, 0, 0, "+00:00")
  now >= event_start_day && now < event_end_day
end
```

現在の日時が `event_start_day` より後かつ `event_end_day` より前である場合に `true` が返され、そうでない場合に`false`が返されます。

## 最終的なコード

```ruby
  def event_period?(now: Time.zone.now)
    Range
      .new(
        Time.zone.parse('2023-01-01 00:00:00'),
        Time.zone.parse('2023-02-01 00:00:00'),
        true
      )
      .cover?(now)
  end
```

### タイムゾーンに関して
元のコードでは、Time#newを使用してイベントの開始日と終了日を定義していました。

最終的なコードでは、Time.zone.parse()メソッドを使用して、Railsアプリケーションのタイムゾーンに設定されているタイムゾーンを考慮した時間を取得しています。

### 範囲をRangeクラスを使って表現する
また、Rangeクラスを使用して期間を表現することで、期間が直感的に理解できるようになりました。
最初のコードでは、開始日と終了日を定義して、さらに別の行で日付が含まれているか判定する手間がありました。

#### ※備考
Range#newの第三引数に`true`を指定すると、終端を含まないようにできます。（`2023-02-01 00:00:00`は含まれない）
[Range\.new \(Ruby 3\.2 リファレンスマニュアル\)](https://docs.ruby-lang.org/ja/latest/method/Range/s/new.html)

### 現在時刻を扱うため、デフォルト引数を指定
この関数は、現在時刻が特定の期間に含まれるかを判定します。
引数を取っていますが、デフォルトの値は`Time.zone.now`にしています。

理由としては、この関数が単体で使用される場合はそのまま呼び出して問題ないのですが、仮に複数の現在時刻を扱う関数と一緒に呼び出されたり、ループ処理の中で呼び出された際に**現在時刻がずれないように、外側からも渡せるようにするため**です。

ですから、引数の名前は`time`ではなく`now`になっています。

コードを見た方がわかりやすいと思うため、以下に例を書いておきました。

- 時間がずれるパターン
```ruby
def current_time(now = Time.now)
    now
end

result = []
100000.times { result << current_time }

p result.first # 2023-05-16 02:50:10.53720954 +0000
p result.last  # 2023-05-16 02:50:10.621344667 +0000 微妙にずれる
```

関数の内部で現在時刻を定義するとこのようなことが起こります。
もちろん、レアなケースだとは思うので気にならなければ良いのですが、外部から現在時刻を渡せるようにすると、以下のように改善されます。

- 時間がずれないパターン
```ruby
def current_time(now = Time.now)
    now
end

now = Time.now

result = []
100000.times { result << current_time(now) }

p result.first # 2023-05-16 02:51:53.278507445 +0000
p result.last  # 2023-05-16 02:51:53.278507445 +0000 一致
```

外側から渡しているので、一致していますね。
使い所に応じて変更できるので便利です。

詳しくは参考リンクの記事がわかりやすいので、是非一度読んでみてください。

以上です。

### 参考リンク

[現在時刻を扱うメソッドはデフォルト引数を使いましょうという話 \- けんちゃんくんさんのWeb日記](https://diary.shu-cream.net/%E7%8F%BE%E5%9C%A8%E6%99%82%E5%88%BB%E3%82%92%E6%89%B1%E3%81%86%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AF%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E5%BC%95%E6%95%B0%E3%82%92%E4%BD%BF%E3%81%84%E3%81%BE%E3%81%97%E3%82%87%E3%81%86%E3%81%A8%E3%81%84%E3%81%86%E8%A9%B1)

[「現在時刻」を外部入力とする設計と、その実装のこと \- クックパッド開発者ブログ](https://techlife.cookpad.com/entry/2016/05/30/183947)
(リンクだけです)「ぷよぷよ(英:Puyo Puyo (video game))」を調べた。

https://www.deepl.com/ja/translator#ja/en/非常に奥が深そうなので、さわりだけにしました.


私は、「ぷよぷよ」と「ぷよクエ」の区別がついていません。

# 公式

https://puyopuyoquest.sega-net.com/info/old/all/index.html?year=2023

http://puyo.sega.jp/program_2020/

「著作権」をまもろう＜
https://puyo.sega.jp/program_2020/#begin

# wikipedia

https://ja.wikipedia.org/wiki/%E3%81%B7%E3%82%88%E3%81%B7%E3%82%88

https://en.wikipedia.org/wiki/Puyo_Puyo_(video_game)

# 参考


https://www.sega.jp/topics/detail/210125_1/

https://edu.monaca.io/

＞参考(ゲーム)

https://qiita.com/mrrclb48z/items/c3a27c6a2848629ff90c#参考(ゲーム)

＞メンテナンス実施日時
＞2023年5月25日(木)19:00～20:30


# 参考(別件)

＞法律との兼ね合い

https://ja.wikipedia.org/wiki/日本eスポーツ連合#法律との兼ね合い

＞ゲーム産業白書

https://www.m-create.com/publishing/game.html

https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B2%E3%83%BC%E3%83%9E%E3%83%BC%E3%80%81%E6%A5%AD%E7%95%8C%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF%E3%81%8B%E3%82%89%E3%81%8A%E9%87%91%E3%81%AE%E8%A9%B1%E3%81%BE%E3%81%A7-e%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%84%E3%81%AE%E3%81%99%E3%81%B9%E3%81%A6%E3%81%8C%E3%82%8F%E3%81%8B%E3%82%8B%E6%9C%AC-%E9%BB%92%E5%B7%9D-%E6%96%87%E9%9B%84/dp/4534057016/ref=sr_1_1?adgrpid=111835783364&hvadid=651372150719&hvdev=c&hvlocphy=1009365&hvnetw=g&hvqmt=b&hvrand=6023235732260137862&hvtargid=kwd-970991947103&hydadcr=14090_13515350&jp-ad-ap=0&keywords=e%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%84%E3%81%AE%E3%81%99%E3%81%B9%E3%81%A6%E3%81%8C%E3%82%8F%E3%81%8B%E3%82%8B%E6%9C%AC&qid=1685936465&sr=8-1

上記より
日本の法律問題

https://ja.wikibooks.org/wiki/コンメンタール刑法

（賭博）

https://ja.wikibooks.org/wiki/刑法第185条


https://ja.wikibooks.org/wiki/コンメンタール不当景品類及び不当表示防止法

（不当な表示の禁止）
？？？条文番号が変わっています？？？

（不当な表示の禁止）第五条


https://ja.wikibooks.org/wiki/コンメンタール風俗営業等の規制及び業務の適正化等に関する法律

第23条(遊技場営業者の禁止行為)
Qtのプロジェクトでビルド時にWinMainのリンクエラーが出た場合

# はじめに

この記事は次の方がターゲット

- qmake を使っている方
- Windowsで開発をしている方
- なぜかリンク時にWinMainのリンクエラーが出てしまった方

# 経緯
Qt5.12 迄ではSUBSYSTEMが Windows の場合でも main関数で問題なく qmake で生成したMakefileでビルドできていたが Qt6.5 に移行してからビルド時に WinMain のリンクエラーが発生する様になってしまった
※ プロジェクトによっては今まで通りリンクエラーにならない
※ もしかしたらリンクするライブラリの関係かも

# 対応

次の対応で問題なさそう

- .pro ファイルへの記述

```.pro
contains(CONFIG, console) {
  DEFINES += SUBSYSTEM_CONSOLE
}
```

- main.cpp ファイルへの記述

```C++: main.cpp
#include <QtWidgets>

#ifdef SUBSYSTEM_CONSOLE
int main(int argv, char *argv[])
#else
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
#endif
{
#ifdef SUBSYSTEM_CONSOLE
    QApplication app(argc, argv);
#else
	QApplication app(__argc, __argv);
	Q_UNUSED(hInstance);
	Q_UNUSED(hPrevInstance);
	Q_UNUSED(lpCmdLine);
	Q_UNUSED(nCmdShow);
#endif

	app.setApplicationDisplayName(app.tr("app name"));
    QWidget w;

    app.connect(&app, &Application::lastWindowClosed, &app, &Application::quit);
    w.show();
    return app.exec();
}
```

```__argc``` と ```__argv``` は MSVCコンパイラの独自の拡張機能 との事

# おわりに

Qtのプロジェクトでも WinMain をエントリーポイントで書けることを10数年Qtを使用しているが初めて知る
本当に自分の知識とは些細なものであることを実感
NginxでWebアプリケーションにポート80でアクセスする

# はじめに
[論文検索アプリケーション](https://qiita.com/nomnomnonono/items/71fe14f5493a42f9b15d)をEC2にデプロイするという作業を始めて行いました。
WebアプリケーションフレームワークとしてGradioを用いており、ポート8080でアプリケーションが立ち上がるようになっていたのですが、アクセスする際に```https://exmaple.com:8080```のようにポート番号を指定してアクセスしなければなりませんでした。
これはあまり好ましくなかったので、ポート番号を指定せずにアプリケーションにアクセスするために**リバースプロキシ**という手法を用いたのでその設定方法を簡単にまとめておきます。

# EC2にNginxを導入する
EC2のマシンイメージとして```Amazon Linux 2023```を用いたのですが、今までのインストール方法ではなく次のようなコマンドでインストールします。
```bash
sudo dnf install nginx
```
（Amazon Linux 2023以前）
```bash
sudo amazon-linux-extras install nginx1
```
Nginxを起動しておきます。
```bash
sudo service nginx start
```

# リバースプロキシの設定
ここからが本題になるのですが、上で立てたNginxのHTTPサーバのポート80で受け取ったリクエストを自分のアプリケーションに受け渡すようにします。
そのために設定ファイル```/etc/nginx/nginx.conf```に以下を追加します。（アプリケーションのURLは任意で変更してください）
```bash
server {
    ...
    location / {
        proxy_pass http://0.0.0.0:8080/;
    }
    ...
}
```
このように修正することで、ポート番号を指定せずにアプリケーションにアクセスできるようになります。