OmniAICreator/Qiita-1.07M huggingface dataset:
Leetcode 224. Basic Calculator

# 224. Basic Calculator
https://leetcode.com/problems/basic-calculator/

## 難易度
### HARD

## アプローチ
### Stack
O(n)


```java
package com.leetcode.hard;

import java.util.Stack;

public class BasicCalculator224 {
    public static void main(String[] args) {
        System.out.println(calculate("2+(3)"));
    }


    public static int calculate(String s) {
        int sum = 0;

        // one: +
        // minus one: -
        int isSignPlus = 1;

        Stack<Integer> stack = new Stack<>();

        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (Character.isDigit(ch)) {
                // プラスと数値を合わせて計算する

                // valを初期化
                int val = 0;

                //数値の場合、数値をvalに保存する
                while (i < s.length() && Character.isDigit(s.charAt(i))) {
                    val = val * 10 + (s.charAt(i) - '0');
                    i++;
                }

                i--;
                val = val * isSignPlus;
                // プラス、マイナスの適応

                isSignPlus = 1;
                // 初期化

                sum += val;
                // 結果と合算する

            } else if (ch == '(') {
                //括弧が始めた場合は状況を保存
                stack.push(sum);
                stack.push(isSignPlus);

                // 初期化
                sum = 0;
                isSignPlus = 1;

            } else if (ch == ')') {
                //括弧が終わったら、今の状況と保存されている状況と合わせる
                sum *= stack.pop();
                sum += stack.pop();
            } else if (ch == '-') {

                // マイナスの場合、-1を掛け算する
                isSignPlus *= -1;
            }
        }
        return sum;
    }
}


```


> [こちらを参考しました](https://leetcode.com/problems/basic-calculator/solutions/2831476/java-solution-using-stack-with-o-n/)
認定Kubernetesクラウドネイティブアソシエイト (KCNA-JP) 受験体験記 

## はじめに
2022年11月に認定Kubernetesクラウドネイティブアソシエイト (KCNA-JP) に合格しました。
この記事では、受験した感想やAWSなどの試験でおなじみのPearsonVUEで提供されている試験との違いなどをご紹介できればと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134250/a5a98b87-a7e7-27ec-fc48-d417d1841ec4.png)

## 認定Kubernetesクラウドネイティブアソシエイト (KCNA-JP)
認定Kubernetesクラウドネイティブアソシエイト (KCNA-JP) は、2021年11月にリリースされたKubernetes and Cloud Native Associate(KCNA)の日本語版として、2022年7月にリリースされました。

### 試験概要
* 問題数: 60問（多肢選択式）
* 合格ライン: 75% (45問正解)
* 試験時間: 90分
* 対応言語: 日本語
* 受験料: $275
* 実施形式: オンライン受験

## 試験対策
* 正直エントリー資格だし、そんなに難しくないだろうと思ったため、[バンドル（認定試験+トレーニングコースのセット）](https://training.linuxfoundation.org/ja/training/kubernetes-and-cloud-native-essentials-lfs250-kubernetes-and-cloud-native-associate-kcna-exam-bundle/)についてきたトレーニングコースの内容を一通り眺めたくらいでした。

### [Kubernetes and Cloud Native Essentials (LFS250)](https://training.linuxfoundation.org/ja/training/kubernetes-and-cloud-native-essentials-lfs250/)
* クラウドネイティブとは？コンテナとは？Kubernetesとは？といった初歩的な内容について解説しているコースです。
* 章ごとにクイズが用意されており、類似した問題も本番試験で出題されましたので、内容は細かいところまで一通り抑えておくとよいと思いました。

## 受験方法
* 試験はオンライン形式です。
* 30分前から試験が開始できるようになっています。初見だとかなりワタワタすると思いますので、早めに開始することをおすすめします。
* PearsonVUEで提供されている試験と比較すると、プロクターによるチェックがそこそこ厳しめだったように感じました。
* カメラ越しにチェックされた内容は下記の通りです。ノートPCに備え付けカメラでもできなくはないと思いますが、普通に大変なので外付けカメラを使用されることをおすすめします。
    1. 部屋を360度見せてください
    1. 天井と床、机の上を見せてください
    1. キーボードやラップトップの下に何も置いていないか見せてください
    1. 腕時計などをしていないか、腕を見せてください
    1. イヤホンなどをしていないか、耳を見せてください
    1. スマホをカメラに映しながら試験中は手が届かないところに置いてください
    1. コップの水や透明なペットボトルを持ち込む場合は見せてください

## 受験した感想
* 日本語訳が非常にわかりにくいという点もあり、思っていたよりは難しかった印象です。
* ひどいことに日本語で書かれた内容と英語の原文で書かれた内容が全く違う問題もありましたので、日本語の問題文だけではなく、英語の問題文も念のため参照することをおすすめします（同じ文章の問題が2問連続で出てこなかったらたぶん気づかなかった。。）
* クラウドやKubernetesに関する経験をお持ちの方であれば、LFS250の内容を一通り抑えておけば問題なく合格できると思います。
* 個人的な体感としては、LFS250で取り上げられている内容の問題が7割くらい、それ以外の問題 or LFS250で取り上げられているものの詳しい説明などがない問題が残り3割くらいかな、という印象ですので、残りの3割くらいの部分をいかにカバーするかが合格の鍵になると思いました。
[GAS] ライブラリ内のグローバル変数が参照できない

## はじめに

表題の件、変数名がわかっているなら、`【ライブラリの識別子】.【変数名】` で済む話、と思っていたら落とし穴に嵌まるかもしれません。

今回は他者開発のライブラリを使用したプロジェクト解析が必要な案件で遭遇した内容についての備忘録です。クライアント様から見ても他者開発品のライブラリのため、当然、編集はできないという前提です。

なお、GASにおいて、他者が作成したライブラリ本体を解析したい場合は、拙記事ですが、以下を参考にしていただければ幸いです。

https://qiita.com/STSHISHO/items/2828d3011873f9923bbf

## 検証

ライブラリ内でグローバル設定されている変数を参照するため、以下のようなライブラリを作成。既存プロジェクトへ `LIB` として登録している前提です。

```Javascript: liblary.gs
const test01 = 'test01';
let   test02 = 'test02';
var   test03 = 'test03';

function hoge(){
   return 'fuga';
}
```

グローバル変数を参照しログ出力してみます。また、関数の戻り値も取得してみます。

```javascript: sample.gs
Logger.log(LIB.test01);
// null

Logger.log(LIB.test02);
// null

Logger.log(LIB.test03);
// test03

Logger.log(LIB.hoge());
// fuga
```

ライブラリのグローバル変数を参照するには `var` による定義が必要ということになります。この件につきましては、[公式ガイド、Best practices](https://developers.google.com/apps-script/guides/libraries#best_practices) の３番目にしれっと記載されています。

> Only enumerable global properties are visible to library users. This includes function declarations, variables created outside a function with **var**, and properties explicitly set on the global object.
> ※原文の一部の文字を太字にしています

余談ですが、関数名の末尾に `_` を付加することで、ライブラリ外から直接利用ができなくなります。

```javascript: sample02.gs
// ライブラリ
function hoge_(){
   return 'fugafuga';
}

// 参照プロジェクト
Logger.log(LIB.hoge_());
// TypeError: LIB.hoge_ is not a function
```

## 最後に

当該の案件につきましては、グローバル変数が `const` で定義されていたため参照ができない状態でした。ライブラリを編集できない以上、結果的に参照は諦めました。

ライブラリ作成者とコンタクトが取れるようなら、`var` による変数定義への修正リクエストを送るのも一手段と思います。もしくは、いわゆるゲッターセッターを追加して頂く、ということも考えられます。しかし、意図して外部から参照できないようにしているなら、その対応は難しいでしょう。

当該案件の詳細には触れていませんが、本稿執筆に際し、クライアント様には事前に承諾を頂きました。

誰かのお役に立てたなら幸いです。

## [参考・引用]
+ [Libraries | Apps Script | Google Developers](https://developers.google.com/apps-script/guides/libraries)
javascriptで100マス計算プログラム

問題ボタンで新しい問題が表示される。
解答ボタンで解答の表示、非表示が切り替え可能。

<a href="https://note.nonbiri3.com/100masu2.php">javascriptで百マス計算プログラム</a>

なんとか動きましたがコードむちゃくちゃです。
アドバイスお願いします。

```html:100masu.html

<div align="center">

<script>

function arrayShuffle(array) {
  for(var i = (array.length - 1); 0 < i; i--){
    var r = Math.floor(Math.random() * (i + 1));
    var tmp = array[i];
    array[i] = array[r];
    array[r] = tmp;
  }
  return array;
}

function mondai(){
let num1 = [...Array(9)].map((_, i) => i + 1);
let num2 = [...Array(9)].map((_, i) => i + 1);
let num3 = "";
arrayShuffle(num1);
arrayShuffle(num2);

document.write("<table border=1>");
for(let y = 0; y < 9; y++){
	document.write("<tr>");
	if(y=="0"){
		document.write("<td>＋</td>");
		for(x=0;x<9;x++){
			document.write("<td>");
			document.write(num2[x]);
			document.write("</td>");
		}		
    }else{
		document.write("<td>");
		document.write(num1[y]);
		document.write("</td>");
		for(x=0;x<9;x++){
			document.write("<td class='kaitou'>");
			num3 = Number(num2[x]) + Number(num1[y]);
			console.log(num3);
			document.write(num3);
			document.write("</td>");
		}
	}
	document.write("</tr>");
}
document.write("</table>");
}

let count = 0;
function kaitou(){
	count++;
	let kaitou = document.getElementsByClassName('kaitou');
	if(count % 2 == 1){
		for(i=0;i<kaitou.length;i++){
			kaitou[i].style.color = "#ffffff";
		}
	}else{
		for(i=0;i<kaitou.length;i++){
			kaitou[i].style.color = "#000000";
		}
	}
}

mondai();

</script>

<style>
	<!--
	td{
		text-align:center;
		width:40px;
		height:40px;
	}
	-->
</style>

	<div style="margin:15px 0px;">
		<input type="button" value="問題" onclick="location.reload()">　<input type="button" value="解答" onclick="kaitou()">
	</div>

</div>

```
PowershellでGitを使う

## Oh My Posh

https://ohmyposh.dev/

### Oh My Poshのインストール

1. wingetでインストールする
    ```powershell
    winget install JanDeDobbeleer.OhMyPosh -s winget
    ```
1. ターミナルを再起動する

### フォントのインストール

1. ターミナルを __管理者権限__ で起動する
1. フォントをインストールする
    ```powershell
    oh-my-posh font install
    ```
1. ターミナルを再起動する

### フォントの設定

#### Windows Termainal

1. [設定(Ctrl+,)]→[JSON ファイルを開く]
   もしくは
   Json ファイルを開く(Ctrl+Shift+,)
1. フォントを設定する
    ```json
    {
        "profiles":
        {
            "defaults":
            {
                "font":
                {
                    "face": "MesloLGM NF",
                    "size": 10
                }
            }
        }
    }
    ```

#### VS Code

1. [設定(Ctrl+,)]→[Terminal > Integrated: Font Family(`terminal.integrated.fontFamily`)]
1. フォントを設定する
   `"MesloLGM NF"`

### プロファイルにOh My Poshを追加

1. プロファイルを開く
    ```powershell
    notepad $PROFILE
    ```
1. oh-my-poshの設定を追記する
    ```powershell
    oh-my-posh init pwsh | Invoke-Expression
    ```
1. プロファイルを再読み込みする
    ```powershell
    . $PROFILE
    ```

### カスタマイズ（オプション）

#### テーマ

1. テーマを確認する
    ```powershell
    Get-PoshThemes
    ```
1. テーマファイル名を確認する
   `%LOCALAPPDATA%\Programs\oh-my-posh\themes`
    ```powershell
    $env:LOCALAPPDATA\Programs\oh-my-posh\themes
    ```
1. [プロファイルの設定](#プロファイルの設定)を変更する
    ```powershell
    $ThemePath = $env:LOCALAPPDATA + '\Programs\oh-my-posh\themes\powerlevel10k_rainbow.omp.json'
    oh-my-posh init pwsh --config $ThemePath | Invoke-Expression
    ```

## Posh-Git

### Posh-Gitのインストール

    ```powershell
    Install-Module posh-git -Scope CurrentUser -Force
    ```

### プロファイルにPosh-Gitを追加

1. プロファイルを開く
    ```powershell
    notepad $PROFILE
    ```
1. oh-my-poshの設定を追記する
    ```powershell
    Import-Module posh-git
    ```
1. プロファイルを再読み込みする
    ```powershell
    . $PROFILE
    ```
Shopify チェックアウト機能の実装で詰まった話


# はじめに
Shopifyでの注文アプリをNext.jsとGraphQLを用いて作ろうとしたのですが、全然うまくいかずにかなりドはまりしてしまったので、今後同じような実装をする方が役に立てるように共有させていただきます。
## やりたかったこと
+ Next.jsと状態管理ライブラリであるRecoilを用いてカート機能
+ カート商品に応じた **決済機能(チェックアウト)** の実装
## 試したこと
+ Shopify storeFront APIの**checkoutCreate** mutationの使用
+ [公式ドキュメント]("https://help.shopify.com/en/manual/checkout-settings")でチェックアウトページ自体の調査

## 試した結果
Shopify側が提供しているGraphQl mutaitonでは必須項目に購入者名や住所などの個人情報をVariableとして渡す必要があり、今回実装するアプリの仕様からずれてしまうため断念（他の方は[このやり方]("https://help.shopify.com/ja/manual/products/details/checkout-link")でも実装できると思います。）
## 解決策
[こちらの記事（Shopify公式ドキュメント）](URL "https://help.shopify.com/ja/manual/products/details/checkout-link")を参考にチェックアウトリンクをカスタマイズ実装しました。記事によると下記のような実装で可能です。

:::note info
 1\. https://(ストア名[例: example-shop.myshopify.com])/cart/ というURLを配置する
 2\.　商品の**variant_id**と数量をvariant_id:2のように並べる

 例　商品variant_id:36485954240671、数量 5の場合
  https://(ストア名[例: example-shop.myshopify.com])/cart/36485954240671:5 
:::

　ただGraphQLからIDを取得した場合”gid://shopify/ProductVariant/36485954240671”のように取得されるため先頭の文字列が不要なため削除してあげる必要があります。

また上記の方法では複数商品に対応できないため、文字列の整形が必要になります。
不要な文字列の削除と整形を行ったのが下記のコードとなります。


```javascript:cart.js
  const orderList = cartItems.map((item)=>{
    const newObj =  { checkoutId:item.variantId.replace("gid://shopify/ProductVariant/",""), checkoutQuantity: item.quantity}
    return newObj
   })
    const products = productValue?.join(",")
    const checkoutLinkTest = `https://${shopName}.myshopify.com/cart/${products}`
```

## 参考記事
[Shopify公式ドキュメント](URL "https://help.shopify.com/ja/manual/products/details/checkout-link")
【WSL2】Kali-linuxでapt updateした時に「 Temporary failure」が発生した

# 実行環境
 - OS: Windows11
 - WSL2
 - kali-linux
 - /etc/apt/sources.listはデフォルト
# エラー内容
1. WSL2のディストリビューションをkali-linuxに設定
1. 「wsl -d kali-linux」でkali-linuxを起動
1. 初回起動のため、「sudo apt update」を実施
1. エラー発生
```:Error発生
└─$ sudo apt update
[sudo] password for kali:
Ign:1 http://http.kali.org/kali kali-rolling InRelease
Ign:1 http://http.kali.org/kali kali-rolling InRelease
Ign:1 http://http.kali.org/kali kali-rolling InRelease
Err:1 http://http.kali.org/kali kali-rolling InRelease
  Temporary failure resolving 'http.kali.org'
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.
W: Failed to fetch http://http.kali.org/kali/dists/kali-rolling/InRelease  Temporary failure resolving 'http.kali.org'
W: Some index files failed to download. They have been ignored, or old ones used instead.
```

# 対処法
1. 「sudo vi /etc/resolv.conf」を開く
1. 「nameserver 8.8.8.8」を追加
※「ipconfig /all」で自分のDNSを調べて使用してもいい
```
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 8.8.8.8
# 8.8.8.8: Google Public DNS
```
3．保存して閉じる
4．もう一度、「sudo apt update」を実施
```: 通った！
Get:1 http://ftp.jaist.ac.jp/pub/Linux/kali kali-rolling InRelease [30.6 kB]
Get:2 http://ftp.jaist.ac.jp/pub/Linux/kali kali-rolling/main amd64 Packages [18.8 MB]
Get:3 http://ftp.jaist.ac.jp/pub/Linux/kali kali-rolling/contrib amd64 Packages [111 kB]
Get:4 http://ftp.jaist.ac.jp/pub/Linux/kali kali-rolling/non-free amd64 Packages [237 kB]
Fetched 19.2 MB in 8s (2,504 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
143 packages can be upgraded. Run 'apt list --upgradable' to see them.
```

# 参考文献
この記事は、以下の情報を参考にしました。
- Failed to update Kali "failed to fetch http.kali.org/kali" #1258
　https://github.com/CypherpunkArmory/UserLAnd/issues/1258
- WSLにてapt update時の『Temporary failure resolving ~』を解決する方法
　https://qiita.com/ryosukeYamazaki/items/c04ec3ff78aac6eb8d26
paiza.ioでelixir その83

# 概要
paiza.ioでelixirやってみた。
ローパスフィルターが、上手く動かない。
調査してみた。

# 問題点

```
src = [1, 2, 3]
v = 0
Enum.map(src, fn x -> 
    IO.puts(v)
    v = x
end)
```

- 自分の期待値は、0,1,2ですが、結果は0,0,0です。


# 解決策

- Agentを使いました。

```
defmodule Out2 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 put(o) do
	    Agent.update(__MODULE__, fn v ->
			o
		end)
    end
end

Out2.start_link
src = [1, 2, 3]

Enum.map(src, fn x -> 
    v = Out2.get
    IO.puts(v)
    Out2.put(x)
end)

```

# 成果物

https://paiza.io/projects/-yZIsBBJoin3aLvJebZYRw?language=elixir


以上。
コンパイル方式とインタープリタ方式の違い

# はじめに
こんばんは。
本記事はProgaku Advent Calendar 2022 5日目担当のハヤシと申します。

#  なぜコンパイル方式、インタプリタ方式などが存在するのか？
第一前提として
プログラミング言語は人間が機械語（マシン語）を生成するために用いるツールです。

なので、これらのプログラミング言語で書かれたコードは、人間にはある程度分かりやすくても、コンピュータには全く理解できない文字列なのです。

コンピュータが理解できるのは、「0」と「1」で書かれた「機械語」と呼ばれるものです。

最終的には、プログラミング言語で書かれたコードは機械語に### 翻訳されてから実行されています。

## コンパイル方式とは
* ソースコード(プログラム)を一旦すべて機械語(バイナリコード = 0,1)に翻訳して、その機械語になったプログラムを実行する方式です。

* 簡単に表すと英語で書かれたスピーチ内容をすべて日本語に翻訳してから文章を読み上げるイメージです。

例
C, C#, C++, Java, Goなど

## インタプリタ方式とは
* プログラミング言語の命令を一つずつ直接インタプリタに渡し、そのソースコードを直接解釈しながら実行する方式で、解釈実行方式とも呼ばれます。

* ソースコードをインタプリタに渡してから内部的には中間コードなどに変換されている場合がありますがユーザーはそれを意識する必要はありません。内部の変換がどうなっているかは関係なく、ソースコードを直接解釈しながらプログラムを実行します。

* 一行の記述ごとに変換と実行が並行して行なわれるため、コンパイラのように実行用ファイルは作られません。その代わり、実行時には毎回ソースコードを必要とします。
* 簡単に表すと英語のスピーチを一つずつ横にいる通訳さんに翻訳してもらいながら文章を読んでいくイメージです。

例
Ruby, Python, JavaScript, PHPなど

## メリット・デメリット
### コンパイル方式
#### メリット
* 一度すべて翻訳してからプログラムの実行することによって実行速度が速い

#### デメリット
* プログラムの実行に手間と時間がかかる

(プログラムがすべて完成するまで実行結果を確認できないため)

* プログラムのデバッグが行いづらい

(コンパイラ型言語は、プログラムをまとめてコンパイルするので、エラーにもまとめて対応しなければならない)

### インタプリタ方式
#### メリット
* プログラムのデバッグが行いやすい

* 作成したプログラムをすぐに実行・確認できる

(Webサイトの画面を作るときでも、書いたコードをすぐに実行することで、画面デザインを確認しながらプログラミングを進められます)

#### デメリット
* コンパイラ型言語と比較して実行速度が遅い

(「今の命令を読んで実行→次の命令を読んで実行」というように、記述されたプログラムを一つずつ実行するため)

* 処理速度が求められるシステムには向いていない

## 結局何が違うのか？

結論から
#### 「一括で全て機械語に翻訳するか」「一回一回機械語に翻訳しながら実行していくか」

ということでした。

それぞれ向き不向きなどあるので、今後開発していくにつれて何が一番適しているのか考える必要がありそうですね。

以上になります。
[sidekiq schduler]Cron形式での定期処理の書き方

## 自分用の書き方メモです。

```
:schedule:
  push_line:
    cron: '* * 12 * * *'
    class: PushLineJob
```
- 上記のようにconfig/sidekiq.ymlに定期処理をしたいものを書きますが、cronで時間指定をする際の書き方がよくわからなかったのでメモしておきます。

## cronを用いた書き方の説明
- cronでは基本的に*を５つ用いて時間を表します。
- 左から、分・時・日・月・年で時間を指定して指定日時になったらシステムを動かすというような形で予約できます。

## sidekiqschedulerの場合
- sidekiqschedulerの場合は*が6つあります。
- 最初は何を表しているかわからなかったのですが、公式のGitHubで「一番左は秒だよ」と書いてありました。
- そのため左から、秒・分・時・日・月・年を表しています。

## 注意点
- ここまででsidekiqschdulerの時間の指定は大丈夫でしょう。
- 最後に、Railsの時間設定を共通時刻から日本時間に直すのを忘れないようにしましょう。
- 時の指定あたりから直し忘れるとあたふたします。
- ５分ごとに繰り返し処理のような場合は以下のようにしましょう。
```
cron: '0 0/5 * * * *'
```
ちなみにこう書くと5分ごとに無限に処理が繰り返されました...
```
cron: '* */5 * * * *'
```
秒数を指定してないので、5分の間は処理を繰り返すという意味になっているからのようです。

### 参考記事
https://www.yoheim.net/blog.php?q=20190902
https://zenn.dev/yoiyoicho/articles/538af41a66867d
【Android】Unknown FragmentsでXMLプレビューが表示されない場合の対処法

# はじめに
Jetpack Compose登場してからじわじわと浸透が進んでいる現在ですが、まだXMLを使用した開発は現役ですよね。
そんな中XML上でfragmentコンポーネントを使用しているとエラーが発生し、プレビューが表示されない問題があります。
この問題の対処法を備忘録的にまとめておこうと思います。

# 対処法
まずエラー内容は以下になります。
![スクリーンショット 2022-11-20 17.03.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354522/9e214d08-f05d-1dd8-2581-6acf4874254c.png)

こちらのエラーは主にfragmentタグを使用している場合などが当てはまりますね。
メッセージにもヒントがあるのですが、原因としてはfragmentは実行時に挿入されるため、対象のコンポーネントをIDEが認識できないことです。

そのため、対応方法としては以下のようにtoolsを使用してエラーの対象であるコンポーネントに対してレイアウトを設定してあげることで解決できます。

```main.xml
   <fragment
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      tools:layout="@layout/dummy_layout"/>
```
対応としては以上となります。
ちなみにこの方法以外にもエラー下部の**Choose Fragment Class**を選択することで、手書きをしなくても選択したレイアウトを上記のように設定してくれます。

# さいごに
こういったエラーは度々起こりますよね。
また同様のエラーが発生した際には対処法を備忘録的にまとめておこうと思います！
[Authorize]を使わなくても有効にする方法

# はじめに
ASP.Net を使用してControllerを使うとき、認証キーがなければ通過できないように[Authorize]を使用しますが、たくさんのControllerを使用していると、書き忘れてしまうことがある・・・かもしれません。
そんなときには、書いてなくても有効にできる方法がありましたので記載します。

# 環境
ASP.Net 6.0
Program.csの書き方が6.0に合わせていますが、それ以前の環境でも少し違うだけなので大丈夫かなと思います。

# 初期値
ASP.NET Core Web API をVisual Studioで作成すると以下のようなProgram.csとWeatherForecastController.csができると思います。6.0はかなりシンプルですね。
## Program.cs
```C#
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseAuthorization();

app.MapControllers();

app.Run();

```

## WeatherForecastController.cs
```C#
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
```

# Authorizedのやり方
よくある方法は各コントローラーに[Authorize]をつけて、だれでも使用できるAPIに[AllowAnonymous]をつけることです。
```C#
    [Authorize]
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase


    [AllowAnonymous]
    [HttpPost("login")]
    public async Task<ActionResult> Login(LoginModel loginModel)
```

これでも問題はないのですが、Controllerが作成された場合[Authorize]はついていないので、毎回書き足す必要があります。もし書き忘れていたらセキュリティ的な問題となります。
ということで、対策方法ですが、とても簡単で、Program.csに設定を書いてしまうという方法です。

# Program.csにフォールバック認可ポリシーを追記する
```C#
builder.Services.AddControllers(options =>
{
    options.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build()));
});
```
このようにすることで、インスタンスにDenyAnonymousAuthorizationRequirementが追加されて、すべてのコントローラーが[Authorize]となります。
[Authorize]がデフォルトとなり、[AllowAnonymous]をつけたものだけが誰でも許可という属性になります。

ちなみに、JwtToken認証を使用する場合は以下のようにすればOKです。
```C#
options.Filters.Add(new AuthorizeFilter(new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme).RequireAuthenticatedUser().Build()));
```

これを知ってから、作業効率が上がった気がしています。
チャットボットをAzureにデプロイする

https://qiita.com/debonn/items/72d566d9aa986445e907

今回はローカルで動かしたチャットボットをクラウドにデプロイしてみました。

参考サイト
https://learn.microsoft.com/ja-jp/azure/bot-service/abs-quickstart?view=azure-bot-service-4.0&tabs=userassigned

## Webアプリのデプロイ

GitHubに置いてあるソースコードをAzure WebAppへデプロイしていきます。

![スクリーンショット 2022-11-20 15.43.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/6ea451a9-6da5-a0f8-ccfc-2c26e71804b1.png)


![スクリーンショット 2022-11-20 15.45.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/102e88b5-06de-f2e1-3680-ac45b2bff19c.png)
デプロイの設定にて「有効化」を選択すると、WebAppsからGitHubのリポジトリにアクセスできるようになります。

![スクリーンショット 2022-11-20 16.21.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/455c7af5-5219-7d4c-0b52-4e10f66b62e4.png)

![スクリーンショット 2022-11-20 16.23.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/da268301-70c5-466a-e649-bb062217c3d7.png)

## settings.jsonの編集

アプリの種類(認証方法)はユーザー割り当て済マネージドIDを選択する。

https://learn.microsoft.com/ja-jp/azure/bot-service/bot-builder-concept-authentication-types?view=azure-bot-service-4.0#bot-authentication
認証の種類についてはこちら


![スクリーンショット 2022-11-20 16.33.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/e6c6c695-49fb-87c7-f1ec-4b055a263726.png)

リソース作成後に「構成」を選択して、Microsft AppIDとTenant IDをメモしておく。
先ほどデプロイしたWebAppsのエンドポイントURLを「構成」で設定する。

![スクリーンショット 2022-11-20 16.49.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/416ae068-2b58-0c69-89c1-eff7e96e7f86.png)


## WebAppsサービスを更新

ボットがユーザー割り当てマネージド ID アプリケーションである場合は、ボットのアプリ サービスを更新する必要がある場合があります。

![スクリーンショット 2022-11-20 16.52.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/73c1bb09-eb11-a379-df73-a96e567c9141.png)

https://learn.microsoft.com/ja-jp/azure/active-directory/managed-identities-azure-resources/overview

![スクリーンショット 2022-11-20 16.54.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/f5c43d06-a972-6f1e-72a7-4878ef1dba87.png)

Azure Botをデプロイしたリソースグループを選択する。


## LINE Developers ConsoleからAzure Botへアクセスする


![スクリーンショット 2022-11-20 17.01.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/6d9b63c7-eb09-520e-1743-f19a19bb9f6d.png)

![スクリーンショット 2022-11-20 17.01.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/d3bdcda2-4599-cc12-e16b-a7582a9ed99f.png)

必要な項目を入力してOKをクリック

![スクリーンショット 2022-11-20 17.03.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/adca450c-ceb5-3145-0607-8151fc10daf5.png)

Basic Settings > channel secret
Messageing API > Chanel access token

![スクリーンショット 2022-11-20 17.06.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/dca38359-e06a-5b0b-6ab8-efaeeae31560.png)

適用をクリック、生成されたWebhook URLをLINE Developers Consoleに登録する

![スクリーンショット 2022-11-20 17.07.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235110/36622142-6680-29d7-8120-1594967eecc7.png)
AWS FIS を利用して Fargate を対象に障害注入実験

# 前提

- ECS Fargate タイプで、タスクを 2 つ起動していること。
- サービスの設定で、最小および最大実行タスクを最小 100% および最大 200%にしていること。

# FIS の設定

FIS の設定で押さえておさえておきたいのは、基本「アクションタイプ」と「ターゲット」の　2 つです。
また、FIS が実験を行うためのアクセス許可をIAMロールで作成する必要もあります。

S3 または、CloudWatch Logs へログを送ることもできますが、今回は省いています。

## アクションタイプ

FIS では次のようなアクションがサポートされています。

https://docs.aws.amazon.com/ja_jp/fis/latest/userguide/fis-actions-reference.html

ここでは、**aws:ecs:stop-task** を指定しています。
![スクリーンショット 2022-11-20 16.30.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/f04028f1-e947-0425-3983-dd6f0e6ad688.png)

## ターゲット

ターゲットでは、先程設定したアクションに対して 1 つ以上の AWS リソースを指定します。
ここでは、対象のクラスター、サービスをリソースパラメータとして指定し、その内の半分(50%)を停止させるように指定します。

![スクリーンショット 2022-11-20 16.31.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/0c86f770-c300-c89c-4163-6707555cd756.png)

## IAMロール

今回は、FIS が、ECSタスクの停止を実行するための次のようなIAMロールを作成すればよいと思います。

```json:信頼関係
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "fis.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

```json:ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "ecs:*",
            "Resource": "ecs:DescribeTasks",
                        "ecs:ListTasks",
                        "ecs:StopTask"
        }
    ]
}
```

# 実験開始

作成されたテンプレートを指定し、「実験を開始」をクリックしてやってみます。

今回は、FIS の実行結果を S3 または、CloudWatch Logs へログ送っているわけではないため、単純にタスクやサービスのログから確認してみます。

タスクが 1つ停止済となり、新しくタスクが1つ立ち上がっているのがわかりますね。
![スクリーンショット 2022-11-20 16.58.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/3bdbc8fd-636f-1d27-0549-1d461be7f592.png)

実行したいアクションによると思いますが、今回のケースの場合直接タスクを停止させることと変わりはないため、FIS を利用するべきかどうかは、ケースバイケースですね。
UInt

<p>プログラミング言語の制限を付与する機能は誰に対してなのか？例えばプライベートに対して隠すというのは、ソースが読める時点で丸見えなような。これについて、相手に対して不必要な情報を見せないという上手い表現をする人もいて、自分の気に入って使わせてもらっている。</p>

<p>これらの制限はなんなのか？注釈で説明する手間を省くためのものなのか？</p>

<p>例えば、C++にはconst地獄という言葉があって、せっかくconstが付けられていても、仕様が変わって、constを外すために多くのファイルで修正が発生しまったり、const値をライブラリに渡そうとすると、受け取り側がconstでないのでキャストすることになってしまったり。</p>

<p>ファイル内でしか使われない変数にconstがついていると、これを書いた人は自分自身が信用できなかったのかなと想像してしまったりする。</p>

<p>また、unsignedはどう考えればいいのか？負の値があり得ない変数はunsignedを選択すべきなのか？0より小さな値にならない制限だとすると上限値の制限はどうするの？下限値にないしてはコンパイラに任せ、上限値はプログラマがif文でチェックするのか？例えば、上限値は100、下限値は10で、どちらもif文でチェックしている場合、コンパイラの0以上チェックななんなのか？</p>

<p>iBooksとWebで公開されている<a hre="https://docs.swift.org/swift-book/">The Swift Programming Language</a>を読んでいて、興味深い説明を見つけた。</p>

<table>
<tr><th>NOTE</th></tr>
<tr><td>Use UInt only when you specifically need an unsigned integer type with the same size as the platform’s native word size. If this isn’t the case, Int is preferred, even when the values to be stored are known to be nonnegative. A consistent use of Int for integer values aids code interoperability, avoids the need to convert between different number types, and matches integer type inference, as described in <a href="https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html#ID322">Type Safety and Type Inference</a>.>/td></tr>
</table>

<p>大雑把に訳すと、特別な理由がない限りUIntを使わずIntを使え。理由はキャストを発生させないため。</p>

<p>厳密は型を気にする人が、構造体のメンバーでInt32やUIntなどを細かく指定するのを見たことがあるが、ライブラリの関数に値を渡す場合は、演算の際にIntにキャストすることになってしまい、それが本当に安全か？というのモヤモヤしてましたが、基本的にIntとすればキャストが発生しないので、ある程、こちらの方が安全ですね。</p>

<p>公式のドキュメントに書いてくれると、周りに説明しやすいので助かる。ありがとう。</p>

【関連情報】
<a href="https://docs.swift.org/swift-book/">The Swift Programming Language</a>
<a href="http://www.bitz.co.jp/weblog/">Cocoa練習帳</a>
競プロ典型90問 010-Score Sum Queries（★2）をJavaで解いてみた！

こんにちは、[Kuni](https://qiita.com/kuniengineer)です。現在Javaを学習中で、Atcoderでコーディング力を高めているところです。
今回は[競プロ典型90問 010-Score Sum Queries（★2）](https://atcoder.jp/contests/typical90/tasks/typical90_j)の実装にチャレンジしてみました。

# ACのプログラム
```java:Main.java
import java.util.*;

public class Main
{ //クラス名はMain
    public static void main(String[] args) {

      //標準入力受け取り準備
      Scanner scanner = new Scanner(System.in);

      //生徒の人数を受け取る
      int N = scanner.nextInt();
      
      //各生徒の点数を格納する配列を定義
      int [][] number = new int[N][2];
    
      for(int i = 0; i < N; i++){
        //クラスと点数を読み込み
        int c = scanner.nextInt();
        int p = scanner.nextInt();
        //累計を出す
        //これまでのループの累計を格納
        if(i != 0){
          number[i][0] = number[i-1][0];
          number[i][1] = number[i-1][1];
        }
        //今回のループの値を足す
        if(c == 1){
          //1クラスの
          number[i][0] += p;
        }else{
          number[i][1] += p;
        }
      } 

      //Q個の質問を受け取る
      int Q = scanner.nextInt();

      //結果出力
      for(int i = 0; i < Q; i++){
        //スタート位置と終わりの位置を格納
        int first = scanner.nextInt();
        int last = scanner.nextInt();
        //スタート位置が1番である時
        if (first - 1 == 0) {
          //終わりの位置の累計をそのまま出力
          int sum1 = number[last - 1][0];
          int sum2 = number[last - 1][1];
          System.out.println(sum1 + " " + sum2);
        }else{
          //終わりの位置の累計からスタート位置までの累計を引いて出力
          int sum1 = number[last - 1][0]- number[first - 2][0];
          int sum2 = number[last - 1][1]- number[first - 2][1];
          System.out.println(sum1 + " " + sum2);
        }
      }
      scanner.close();
    }
}
```

# 　プログラムの方針
　今回は生徒のクラスと点数が与えられ、その後各クラス学籍番号の範囲の人の点数の合計を求めるというものでした。そのため、各クラスの学籍番号〇番までの累計の点数を配列に格納することで指定された学籍番号の範囲の合計を出力しようとしました。
　まず、クラスと点数が与えられるので、クラス毎に学籍番号〇番までの累計を配列に格納し保持しておきます。例えば配列の1番目には1番の点数、2番目には1,2番の点数の合計を保持します。
　そして指定された学籍番号の範囲の点数の合計を出力するというステップにおいては、指定された範囲の後ろの学籍番号の累計から、前の学籍番号の1つ前の番号までの累計を引いて求めます。例えば学籍番号3番から6番の人の点数の合計を求めるという指定であれば、学籍番号1-6番までの累計から学籍番号1-2番の累計を引いて求めます。
　
　参考になれば嬉しいです！！次は★3の問題に挑戦してみようと思います！
DDDがわからない～誰が何を作るのか～

# 今日は開発者のお話
開発者をだいざっくり分けるとこんな分類に分かれるかと思います。
・作ろうとしているシステムに詳しい開発者
・システムを作ることに詳しい開発者
・どちらもわからない開発者

# 誰が何を作るのか？
まず、一番中心となる人々は**システムを作ることに詳しい開発者**が作りましょう。中心となる部分は全体への影響が大きいのでなるべく技術力の高い人が作るべきです。
ただし、作ったシステムは必ず**作ろうとするシステムに詳しい開発者**が理解できるか確認を取りましょう。この確認作業を怠ってしまうと**ズレ**が起きてしまうので注意しましょう。

**作ろうとするシステムに詳しい開発者**が作って**システムを作ることに詳しい開発者**が確認をすることもできますが、難しいシステムから簡単にする方が楽なので前者の方法をお勧めします。
【SQL】チャットで各ユーザから受信した最新メッセージのみを表示する

## 概要
あるユーザAさんが、B～Zさんとメッセージをやり取りしている場合、B～Zさんの最新メッセージのみを一覧で表示したい。チャット ~~（lineとか）~~ でよくあるパターン。

|  名前  |  日時  | 最新メッセージ|
| ----   | ----  | ----         | 
|  Bさん | 22:10 |久しぶり       |
|  Cさん | 12:00 |宿題忘れた     |
|  Dさん | 9:20  |起きてる？     |
|  Eさん | 5:20  |二重の極み！   |


## テーブル

テーブル : **chat_list**
|  カラム         |  型      | 意味           |
| ----           | ----     | ----           | 
|  chat_id       | INTEGER  |チャットid       |
|  user_id_from  | INTEGER  |ユーザid（送信者）|
|  user_id_to    | INTEGER  |ユーザid（受信者）|
|  message       | TEXT     |メッセージ       |
|  datetime_send | DATETIME |送信日           |


## クエリ

イメージ的には、**送信者一覧**と**メッセージの最新送信日時**を取得してから、それにLEFT JOINで最新メッセージを付ける感じ。
**GROUP BY - MAX**で最新送信日時を取得する。
チャットidで管理したかったが、難しいかな。

```sql

 SELECT 
   /* メール送信者一覧 */
     tm.user_id_from
   , tm.user_id_to
   , tm.datetime_send_last 
   /* 最新のメッセージ（ユーザごと）*/
   , ts.chat_id      
   , ts.user_id_from  
   , ts.user_id_to    
   , ts.message     
   , ts.datetime_send
 FROM 
   /* メール送信者一覧 */
   ( 
     SELECT 
         tb.user_id_from       AS user_id_from
       , tb.user_id_to         AS user_id_to 
       , MAX(tb.datetime_send) AS datetime_send_last  /* 最新送信日時 */
     FROM 
       chat_list tb 
     WHERE 
       tb.user_id_to = 'my_user_id'  /* 修正する */
     GROUP BY
         tb.userIdFrom 
       , tb.userIdTo 
     ORDER BY 
       datetime_send_last DESC 
   ) tm 
   /* 最新のメッセージ（ユーザごと）*/
   LEFT JOIN ( 
     SELECT 
         tb.chat_id 
       , tb.user_id_from 
       , tb.user_id_to 
       , tb.message 
       , tb.datetime_send
     FROM 
       chat_list tb 
     ORDER BY 
       tb.datetime_send DESC 
   ) ts_1 ON     ts_1.user_id_from  = tm.user_id_from 
             AND ts_1.user_id_to    = tm.user_id_to   
             AND ts_1.datetime_send = tm.datetime_send_last
```

## ダメな例

下記でも出来るかと思ったが、**サブクエリの中ではlimitを使用できない**仕様らしい。
なので、正しく動作しない。
考え方的には似ているが、~~group byには軽いトラウマがあるので、~~ 出来ればこちらを使用したかった。
（MySQLを想定）

```sql
/* クエリ */
SELECT
  /* メール送信者一覧 */
    tm.user_id_from
  , tm.user_id_to
  /* 最新のメッセージ（ユーザごと） <- レコードが無い場合は、null */
  , ts.chat_id     
  , ts.user_id_from
  , ts.user_id_to  
  , ts.message     
  , ts.datetime_send
FROM
  /* メール送信者一覧 */
  (
    SELECT DISTINCT
        user_id_from
      , user_id_to
    FROM
      chat_list
    WHERE
      user_id_to = 'my_user_id'  /* 修正する */
    ORDER BY
      datetime_send DESC
  ) tm
  /* 最新のメッセージ（ユーザごと） */
  LEFT JOIN (  /* レコードが無い場合は、nullが1行表示される */
    SELECT
        chat_id
      , user_id_from
      , user_id_to
      , message
      , datetime_send
    FROM
      chat_list
    ORDER BY
      datetime_send DESC
    LIMIT 1 OFFSET 0  /* <-- この部分がNG */
  ) ts ON     ts.user_id_to   = tm.user_id_to   
          AND ts.user_id_from = tm.user_id_from
ORDER BY
  ts.datetime_send DESC

```

## その他

仕様の部分で、少し手間取った。
最初にメインテーブルを決めて、それにLEFT JOINでデータを繋げるパターンが多いと思うけど、今回はメインテーブルがクエリだというケース。

**group byを使っているので、データ数が増えると遅くなるかもしれない。**
その場合は、別途、最新メッセージテーブルなどを作る必要があるかな？
チャットは電話ではない。[ビジネスチャットの使い方（初心者向け）]

こんにちは。
土日はしっかり休んだ方が良いと思いつつ、お仕事っぽいことをやっている社畜です。

# はじめに
私の勤務している JTC では２年前にビジネスチャットが導入されました。
情報システム部門が基本的な使い方の教育やルール・マナー集の社内展開を地道に続けた結果、かなり普及してきました。
とはいえ、まだ電話やメールと同じ感覚でチャットを使う人が多いため、チャットの特性を知ってもらい、それに応じた使い方をしてもらう必要があると感じています。

私自身も２年しか使っておらず、あまり偉そうな事は言えませんが、現時点での考えを整理して言語化しておきます。

# チャットは「非同期」で「連続性がある」コミュニケーションツール
- 電話でのコミュニケーションは、通話者の間で同じ時間を共有する必要がありますが、
チャットは自分が返答したい時間に「<u><b>非同期</b></u>」で返答可能です。
時間がかかる考察・事実確認を、電話で即答するのは難しいですが、
チャットであれば自然な対話の流れの中で返信することができます。
- メールでのコミュニケーションは、一通ごとに非連続になりますが、
チャットは「<b>連続性がある</b>」対話として記録されていきます。
メールでは一通ごとに「書き出し」と「結び」が必要です。
また、「返信メールの返信の返信・・・」のような議論では、文脈を読み取るだけで苦労します。
チャットはそのようなムダを省くことができます。

この「<b>非同期</b>」と「<b>連続性がある</b>」という特性を意識することで、スマートにコミュニケーションできるはずです。

以下、私が社内でチャットを使っていて「こうしてほしい」と感じる事を、3つ挙げさせていただきます。

# 1. はじめに用件を伝えてほしい
あいさつ文や「ご相談したいことがあります」というチャットが先に届き、後から用件が届くことがあります。
<b>これ、地味に迷惑</b>です。
１通目のチャットをトリガーとして思考のスイッチがオンになってしまうので、続きのチャットが届くまでの間、他の作業に集中しづらくなります。
はじめから、用件（相談や依頼事項・緊急度・重要度など）を伝え、即答するか後回しにするか、受取り側に早く判断させてほしいです。

# 2. 選択肢で回答させてほしい
「どうすれば良いでしょうか？」と、思考自体を丸投げしてくるチャットをいただく事があります。
多くの場合、検討材料が不十分であるため、こちらが対話を仕切って情報収集することになります。
決定権が無く、「参考意見がほしい」程度しか関わらない業務に対して、この負担は大きすぎる。
考察に必要十分な材料をそろえ、自分なりの回答をまとめ、「選択肢から好きな方選べばいい」ぐらいの状態で持ってきてほしいです。

※ これ、チャットだけではなく、ビジネスコミュニケーション全般の心得ですね。

# 3. 短文にしてほしい
「ご多忙のところ申し訳ありません。初心者なので簡単な質問をさせていただくことをお許しください。」
といった文は、<b>正直いってジャマ</b>です。
「丁寧なあいさつ文」ではなく、<b>「相手に読ませる文字数を減らす努力」が誠意</b>であると考えてほしいです。

ついでに一言。
殺伐としている時期に上記のようなチャットが来ると、
『"ご多忙のところ" って言っても、チャットは非同期なので自分で余裕のある時に返信するから。
ひょっとして、忙しいのわかってて急かしてんの？』とか、
『難易度はこっちで判断するし、初心者は質問して当然だから。
"簡単な質問" って言われて、意外と難問だった場合、こっちが恥ずかしいじゃん。』
みたいな事を、自分で考えて自分でイラっとしたりします。

なので、できるだけ余計な情報は省いてほしいです。

# 余談
こういったメッセージを社内で発信すると、
「ボクは良いと思うんだけど、
上から目線で語られて不快だと思う人がいるかもしれないね。
ボクは良いと思うんだけど、
気を付けた方が良いよ。」
とありがたいご指摘をいただくことがあります。

業務外の活動として、とやかく言われる筋合いが無い場所で公開させていただきました。

以上です。
CloudFront 標準アクセスログをオンに

# CloudFront 標準アクセスログ

ちょっとどんな感じなのかな？と思って試してみただけです。

# CloudFront の設定

標準ログ記録を「オン」にし、ログ保存用のバケットを選択すると以下のエラーが出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/7de29387-4e68-de02-b207-7c01943ffaf8.png)


https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html

外部アカウント `c4c1ede66af53448b93c283ce9448c4ba468c9432aa01d700d3878632f77d2d0` からの許可必要のようです。

「Enable ACLs」 にてACLを有効にする事でログをオンにできました。
S3バケットのACL設定について確認してみると、以下の通り `外部アカウント` が追加されてます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/5555dada-9afb-b834-31af-5676c098ef52.png)

>バケットの ACL
ディストリビューションを作成または更新してロギングを有効にすると、CloudFront はこれらのアクセス許可を使用してバケットの ACL を更新し、awslogsdelivery アカウントに FULL_CONTROL のアクセス許可を付与します。awslogsdelivery アカウントはログファイルをバケットに書き込みます。アカウントに ACL を更新するために必要なアクセス許可がない場合、ディストリビューションの作成または更新は失敗します。

とあり、 `awslogsdelivery` のアカウントIDが `c4c1ede66af53448b93c283ce9448c4ba468c9432aa01d700d3878632f77d2d0` です。
が、「ACL有効化」は推奨されてないようです..バケットポリシーで制御するのが良いと思いますが、まだできないのでしょうか・・

# 標準ログファイル配信のタイミング

- ディストリビューションの標準ログを 1 時間に最大で数回配信
- アクセスログの出力が確実に行われるのは、ログ記録が有効になって約 4 時間後から。
    - この時間以前にも少しのアクセスログを取得できる場合もある

# 実際のログを見てみた

- 各カラム詳細は[こちら](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html)
- アムステルダムのエッジロケーションから .env に GET リクエストが・・
    - .env に対するGETなのでサーバー環境設定を取ろうとしているようです。
- `x-edge-location` にある `AMS1-P1` がアムステルダムです。
- POST アクセスもみられますね。

|date|time|x-edge-location|sc-bytes|c-ip|cs-method|cs(Host)|cs-uri-stem|sc-status|cs(Referer)|cs(User-Agent)|cs-uri-query|cs(Cookie)|x-edge-result-type|x-edge-request-id|x-host-header|cs-protocol|cs-bytes|time-taken|x-forwarded-for|ssl-protocol|ssl-cipher|x-edge-response-result-type|cs-protocol-version|fle-status|fle-encrypted-fields|c-port|time-to-first-byte|x-edge-detailed-result-type|sc-content-type|sc-content-len|sc-range-start|sc-range-end|
|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|:----|
|2022/11/20|3:42:45|AMS1-P1|682|109.206.243.95|GET|xxx.cloudfront.net|/.env|403|-|Mozilla/5.0%20(X11;%20Linux%20x86_64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/81.0.4044.129%20Safari/537.36|-|-|Error|xx|xxxx.xxx|http|226|0.001|-|-|-|Error|HTTP/1.1|-|-|44376|0.001|ClientGeoBlocked|text/html|212|-|-|
|2022/11/20|3:42:45|AMS1-P1|677|109.206.243.95|POST|xxx.cloudfront.net|/|403|-|Mozilla/5.0%20(X11;%20Linux%20x86_64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/81.0.4044.129%20Safari/537.36|-|-|Error|xx|xxxx.xxx|http|292|0.001|-|-|-|Error|HTTP/1.1|-|-|44378|0.001|InvalidRequestMethod|text/html|212|-|-|

# まとめ

- 雰囲気がわかった
- Athena でいい感じにクエリしてみる
- バケットポリシーで制御できるのか調べます
nodeのバージョンを簡単に切り替えることができるツール「n」のよく使うコマンドまとめ

## 概要

「n」というnodeのバージョン管理ツールが便利だったのでよく使うコマンドをまとめてみた。

https://github.com/tj/n

## nのインストール

### npmでインストールする

```shell
npm i -g n
```

下記をターミナルで実行し、バージョンが出力されれば成功

```shell
n --version
# => v9.0.1
```

### Homebrewでインストールする

```shell
brew i n
```

## インストール可能なnodeのバージョンを確認する

### 最新安定版(LTS)を確認
```shell
n --lts
```

or

```shell
n --stable
```

### 最新版を確認
```shell
n --latest
```

### 最新の20件を確認
```shell
n ls-remote
```

### 全て確認
```shell
n ls-remote --all
```

## nodeのインストール

### 特定のバージョンを指定してインストール
```shell
sudo n [バージョン]
```

### 最新安定版をインストール

```shell
sudo n lts
```

or

```shell
sudo n stable
```

### 最新版をインストール

```shell
sudo n latest
```

```shell
sudo n current
```

## キャッシュ済みのnodeのバージョンを確認する

一度インストールしたnodeのバージョンはキャッシュが作成される。
下記のコマンドでキャッシュ済みのバージョンのリストを確認できる。
```shell
n ls
```

## nodeのバージョンを切り替える

下記を実行するとインタープリターが起動し、キャッシュ済みのバージョンが表示される。
```shell
sudo n
```
※ ターミナルに下記のように出力される
![n_list.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599923/d9596430-ea2a-4a00-f3a5-7a185136b468.png)

↑↓で切り替えたいバージョンにカーソルを合わせ、
Enterすると、選択したバージョンの再インストールが行われ、
そのバージョンに切り替わる。

また、インストール同様
```shell
sudo n [バージョン]
```
で指定すると、指定したバージョンのインストールが行われ、そのバージョンに切り替えられる。


## nでキャッシュしたnodeのバージョンを削除する
特定のバージョンを指定してキャッシュを削除
```shell
sudo n rm [バージョン]
```

使用していないキャッシュを全て削除
```shell
sudo n prune
```

## インストール済みのnodeを削除

```shell
sudo n uninstall
```
GoAccessをUbuntu 20.04にインストール

# 1. 概要
nginxのアクセスログから何かわからないか？という状況になった。
nginxをよく知らない。というか運用という意味ではapacheを含めてhttpサーバーをよく分かってない。

世の中にはサーバーのアクセス解析を行う素晴らしいツールはいくらでもあるだろう。
何か作るようなことは考えず色々探してみたところ、GoAccessというツールが出てきた。

この記事の対象はWebサーバーの開発、運用もよく知らないのに色々やることになりそうな(なった)人。

# 2. 環境
解析をするのはWebサーバーとは別のローカルなPCとする(とりあえず)
* Ubuntu 20.04 のPC(VMでも可)
* テスト用のアクセスログ

# 3. GoAccessのインストール

GoAccessの公式
https://goaccess.io/

# 3.1. aptでインストール
```
$ sudo apt install -y goaccess
$ goaccess --v
```

インストール済み＆バージョン確認
```
GoAccess - 1.3.
For more details visit: http://goaccess.io
Copyright (C) 2009-2016 by Gerardo Orellana

Build configure arguments:
  --enable-geoip=mmdb
  --enable-tcb=btree
```
公式をみると最新よりはバージョンが古いらしい。

解析したいaccess.logを以下のようにすると見栄えのいいWeb表示にしてくれた。
```
goaccess access.log -o a.html --log-format=COMBINED
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865486/591b607c-cd59-e27d-52b7-83c5d62c8f94.png)


せっかくなので最新版を使いたいので、以下でアンインストール。
```
sudo apt remove  goaccess
```

# 3.1. ビルドしてインストール

GoAccess 公式サイトの手順は以下だが、エラーが出たので追加インストールは必要。
```
$ git clone https://github.com/allinurl/goaccess.git
$ cd goaccess
$ autoreconf -fi
$ ./configure --enable-utf8 --enable-geoip=mmdb
$ make
# make install
```

configureとmakeでエラーが出るので以下をインストールしておく
* autoreconf -fiでコマンドがないと言われた。 => autoconfとautopoint
* --enable-geoip=mmdbの部分でもエラーが出る。=> libmaxminddb-dev
* 「mv: 't-de.gmo' を stat できません: そのようなファイルやディレクトリはありません」 => gettext

```
$ sudo apt install autoconf
$ sudo apt install autopoint
$ sudo apt install libmaxminddb-dev
$ sudo apt install gettext
```

```
$ goaccess --v
GoAccess - 1.6.5.
For more details visit: https://goaccess.io/
Copyright (C) 2009-2022 by Gerardo Orellana

Build configure arguments:
  --enable-utf8
  --enable-geoip=mmdb
```
ちなみに1.3のargumentsにあった「--enable-tcb=btree」を付けたら、そんなのはないと怒られた。

当然、1.3のときと同じコマンドが使用できる。
```
goaccess access.log -o a.html --log-format=COMBINED
```

# 4. 結論
Ubuntu 20.04でも比較的容易に最新版GoAccessを試すことができる。

以上
Ansibleプレイブックの実行ロールを条件分岐できないかな？　と思って調べてみた

## 概要

[以前の記事](https://qiita.com/yoheier/items/7df934c8afe0eabf5576)で、CentOS8系CloneにRedmine5-stableを入れてみるAnsibleプレイブックを作ってみてお勉強していたわけですが。
あれ？　DBがPostgreSQL固定だな？　プレイブックで選択インストールできないのかな？

などと思いまして、休日にごちゃごちゃ試してみました。

## 結果
一番簡単に思いつく方法で、変数にどっちのDBを使うか書いて条件判断させればいいな？
という素人考えで、

```
# Redmineで使用するDatabase
#redmine_db: postgres
redmine_db: mysql
```

なんて感じで変数を定義して、

プレイブックの方で
postgreSQL用のRoleとmysql用のroleを用意して、

```
- hosts: redmine_servers

  roles:
    - system
    
    - role: pg
      when: redmine_db == "postgres"

    - role: mysql
      when: redmine_db == "mysql"
```

こんな感じで実行するRoleを分岐できました。
きっともっとスマートな方法もあるのでしょうけど。

とりあえずRockyLinux8.6でだけ起動確認、DBが変わっていることを確認しているのでgithubでリリースしました。

[Redmine5 stableをCentOS8 Clone系OSに自動インストールためのAnsibleプレイブック](https://github.com/yoheier/redmine-centos-ansible) 

mysqlのRoleを動かすのがそこそこ大変だったのは別のはなし……(´・ω・`)
ORIONをブートしてみた。

WZR-AMPG300NHでNetBSDをブートしてみました。

ORIONはSHEEVAPLUGで使われているKIRKWOODの前の世代のSOCですが同じくarmv5teです。

sys/arch/evbarm/confを見るとHPのNASのMV2120がORIONのようなので、これのカーネルをビルドしてみます。

```
===> Summary of results:
         build.sh command:    ./build.sh -j8 -U -m evbarm -a earmv5 -T /usr/home/hiroki/netbsd-tools/evbarm -V CPUFLAGS=-march=armv5te kernel=MV2120
         build.sh started:    Sun Nov 20 15:37:27 JST 2022
         NetBSD version:      9.3
         MACHINE:             evbarm
         MACHINE_ARCH:        earmv5
         Build platform:      FreeBSD 13.1-RELEASE-p3 amd64
         HOST_SH:             /bin/sh
         MAKECONF file:       /etc/mk.conf (File not found)
         TOOLDIR path:        /usr/home/hiroki/netbsd-tools/evbarm
         DESTDIR path:        /usr/home/hiroki/NetBSD93/usr/src/obj/destdir.evbarm
         RELEASEDIR path:     /usr/home/hiroki/NetBSD93/usr/src/obj/releasedir
         Updated makewrapper: /usr/home/hiroki/netbsd-tools/evbarm/bin/nbmake-evbarm
         Building kernel without building new tools
         Building kernel:     MV2120
         Build directory:     /usr/home/hiroki/NetBSD93/usr/src/sys/arch/evbarm/compile/obj/MV2120
         Kernels built from MV2120:
          /usr/home/hiroki/NetBSD93/usr/src/sys/arch/evbarm/compile/obj/MV2120/netbsd
          /usr/home/hiroki/NetBSD93/usr/src/sys/arch/evbarm/compile/obj/MV2120/netbsd-mvgbe0
          /usr/home/hiroki/NetBSD93/usr/src/sys/arch/evbarm/compile/obj/MV2120/netbsd-wd0e
          /usr/home/hiroki/NetBSD93/usr/src/sys/arch/evbarm/compile/obj/MV2120/netbsd-wd0f
          /usr/home/hiroki/NetBSD93/usr/src/sys/arch/evbarm/compile/obj/MV2120/netbsd-wd0g
          /usr/home/hiroki/NetBSD93/usr/src/sys/arch/evbarm/compile/obj/MV2120/netbsd-wd0h
         build.sh ended:      Sun Nov 20 15:39:16 JST 2022
===> .
```

ハングします。

https://dmesgd.nycbug.org/index.cgi?do=view&id=6776

USB関係を外せばrootfsまでいけます。

https://dmesgd.nycbug.org/index.cgi?do=view&id=6777

ハードはこれと同じだと思います。

https://openwrt.org/toh/buffalo/wzr-ag300nh

以下は88E6122のブロック図ですがおそらくEtherNet Switchの88E6131はこの構成と似ているのではないかと思われます。

![MV88E6121.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/5e648448-068c-e3ee-2f5c-b05d15340f71.png)

チップのプロダクトIDのレジスタ値をみると6121->6122->6131->6108の順に開発されようだ。

MAC二つにPhyを接続して、もう一つのMACをSOCにつないでいるものと思われます。
DDDがわからない～設計っていうのは～

# 大事なこと
ドメイン駆動設計は、システムを開発するための手順書ではありません、小さなテクニックの集合体にしかすぎません。その小さなテクニックがなぜ必要なのか？何の役に立つのか？を理解することが大事です。

# 考えるべきこと
考えるべきは今作ろうとしているシステムであり、それに関わる人たちです。
みんながお互いにお互いのことを理解して納得して開発を進めればそれでOKなんです。

# 設計に縛られず、設計を利用する
開発中のシステムを良くしようと考えるときに、
**「あ～、ドメイン駆動設計に書いてあったアレがよさそうだから利用してやろう。」**
こんな軽いノリで使うくらいが丁度いいんです。

**それではみなさん、来年も良い設計ライフを、メリークリスマス！そして、良いお年を！**
Chromeでページが正しく表示されない（ページキャッシュを消去する手順）

# 目的
時々、開いているページが正しく表示されない場合があります。F5キーを押下しても改善されない場合はそのサイトのキャッシュを消去することで回復する場合があります。

# 手順
1.Chromeでページを開く 
1. F12キーを押下して開発者ツールを開く<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/2d258d56-e972-f446-b7f8-aa43d4903f00.png)
1. URL左のページの再読込アイコンを右クリックして「キャッシュの消去とハード再読み込み」を選択する<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/55d87ce6-7aab-81e4-33b4-527926d01141.png)
1. F12キーを押下して開発者ツールを閉じる

以上
deviseを用いた「ユーザー管理機能」の実装フロー

Gemのひとつである「devise」を使用することで、「ユーザー管理機能」を実装することができる。

# deviseの実装フロー

1. Gemのインストール
2. 設定ファイルを作成
3. モデルを作成
4. テーブルを作成
5. ビューを作成


## 1. Gemのインストール
-Gemfileを編集する
```ruby:gemfile
# 中略
gem 'devise'
```
-コマンドを実行
```ruby:ターミナル
%  bundle install
```
:::note info
Gemfileに追加したいGemの名前やバージョンを記述してbundle installを実行することで、
指定したGemをアプリケーションにインストールができる
:::
-サーバーを再起動
```ruby:ターミナル
%  rails s
```
:::note warn
下記を変更した際は、ローカルサーバーを再起動する
■Rubyバージョン
■テーブル・カラム情報
■Gemの導入状況
:::

## 2.設定ファイルの作成
```ruby:ターミナル
%  rails g install:devise
```
:::note info
deviseの設定関連に使用するファイルの生成に成功！
:::

## 3.モデルを作成　*モデル名をuserとする
```ruby:ターミナル
%  rails g devise user
```
:::note info
モデルに加え、マイグレーションファイルも同時に生成される
:::

## 4.テーブルを作成
-3.で生成されたマイグレーションファイルを編集
-マイグレーションを実行
```ruby:ターミナル
%  rails gb:migrate
```
-サーバーを再起動
```ruby:ターミナル
%  rails s
```
:::note warn
下記を変更した際は、ローカルサーバーを再起動する
■Rubyバージョン
■テーブル・カラム情報
■Gemの導入状況
:::

## 5.ビューを作成
deviseでログイン機能を実装すると、サインアップ/ログイン画面が自動的に生成されるが、
ビューファイルとしては生成されないため、編集する際には別途ビューを作成する。
```ruby:ターミナル
%  rails g devise:view
```
:::note note
app/viewsの配下に編集可能なビューファイルが生成された。
サインアップ画面👉app/views/devise/registrations/new.html.erb
ログイン画面👉app/views/devise/sessions/new.html.erb　
:::
Chromeでシークレットウインドウをデフォルトにする

# 目的
セキュリティを強化するためにデフォルトでシークレットウインドウでChromeを立ち上げたい。

# 手順
## MS Windows
1. Chromeを起動する
1. Chromeのアイコンを右クリックして、「Google Chrome」-「プロパティ」を選択<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/abb8eab4-d304-5306-458e-a09c94d29cbf.png)
1. リンク先に「--incognito」を追加する<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/c1bba2a6-6627-ce68-e90c-fb50748763e9.png)

## Ubuntu
1. ファイル「/usr/share/applications/chrome-browser.desktop」をディレクトリ「/home/＜ユーザ名＞/.local/share/applications/」にコピーする
1. テキストエディタでコピーしたファイルを開く
1. 「Exec=chrome-browser」を「Exec=chrome-browser --incognito」にして保存する

以上
OUPC J「Nickname」解説

# はじめに
Herring101君のNicknameの原案に対して「それ解けるよ！」と言ったりテストケース作ったりしたKowerKointです。
この問題はwriter/tester陣それぞれでいろんな解法が出ました。
# 解法1(Rolling Hashを使った解法)
人$i$に対して「名字を$a$文字目までニックネームに使ったとき、名前を$b$文字採用したときに他の人の候補に被らないような最小の$b$」を求めたいです。
この発想に立ったとき、名字をソートしておけば「名字の$a$文字目まで」が重なる名前はある区間になることが使えそうだとわかります。

すべての人を予め名字でソートしておき、名前の$1$〜$|T|$文字分の接頭辞全てのハッシュを計算して「ハッシュ→その接頭辞を持つ人の番号をリストにしたもの」という辞書を作っておきます。

人$i$に対して$a$を増加させながら問題を解きます。

$a$を増やしていくと区間は単調に小さくなっていきます。
区間を$[1,N]$で初期化しておき、$a$文字を見るときに$a$文字目を見ながら区間の両端を縮めます。
区間をの左端または右端を縮める回数は$i$ごとに合計$N$回以内です。

そして、$a$を増やしていくと$b$の最小値は単調に減少します。
$b$を減少させながら、前計算した「ハッシュ→人リスト」の辞書を見ます。
リスト内で名字の条件で縮めた範囲の該当数が $1$ であればその $b$ がニックネームの条件にあっていることになります。
これは二分探索をすればいいです。

このような探索を行って各$i$に対する問題を解いていきます。
文字列全体を見なくて済むようにうまく実装することで$O(N(|S|+|T|)\log{N})$時間で解くことができる。
# 解法2(動的計画法を使った解法)
# 解説

各部員 $x$ に対して独立に答えを求めます。

dp[$i$] = ニックネームとして苗字から $i$ 文字取った場合の、ニックネーム制約を満たすために必要な名前の長さ と定義します。 配列dpを求めることができれば、答えは $\min(i + dp[i])$ と表現することができます。

まずは各部員 $i$ の苗字について、部員 $x$ の苗字との最長共通接頭辞の長さ $F_i$ を求めます。最長共通接頭辞は、予め苗字をソートして、部員 $x$ の苗字の位置を $t_x$ とすると $1,2,3, ... , t_x - 1$ 番目の最長共通接頭辞の長さが単調非減少であることから求めることができます。この部分の時間計算量は $\mathrm{O} (N + |S_i|)$ です。 

次に、各部員の名前について、部員 $x$ の名前との最長共通接頭辞の長さ $X_i$ を求めます。この部分については先ほどと同様に求めることが可能です。

最後に配列dpの値を求めます。各部員 $i$ について、dp[$F_i$] = max(dp[$F_i$], $X_i$) としてテーブルを更新し、降順からdp[$i$] = max(dp[$i$],dp[$i+1$]) として最大値を更新していくことによって求めることができます。この部分の時間計算量は $\mathrm{O} (N + |S_i|)$ です。

各部員について答えを求める必要があるので、合計の時間計算量は $\mathrm{O} (N \times (N + |S_i|))$ となります。