OmniAICreator/Qiita-1.07M huggingface dataset:
【Twitcasting】気になるあの配信者の配信開始通知をdiscordに送信方法を考えて実装してみた。

# はじめに
趣味で推しの子がよくツイキャスするけど通知に気づけないからdiscordに投げるBotを作りました。
言語はPythonで書いてます。
記事の内容はほぼGitHubにあるものと同じです。メモ程度です。

実際の稼働してる様子はこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422677/431677b7-d048-f1d6-6c22-8c287106e785.png)
では，導入していきましょう。
# 実行環境
・Windows10
・Python 3.10
・

pytwitcastingを使用するのでインストール
```
pip install pytwitcasting
```

自動更新のためにscheduleを使うのでインストール
```
pip install schedule
```

# 入れ方
とりあえず，[GitHub](https://github.com/renit0424/TwitcasNoticeDiscord)にあげてあります。
ダウンロードしてきましょう。
# ツイキャスアプリケーション登録ページでAPIを発行
1.[アプリケーション登録ページ](https://twitcasting.tv/developer.php)で登録。
2.後で使うので`ClientID`,`ClientSecret`をメモしておくか設定のconfig.pyに記載しておく。


ダウンロード出来たら`confg.py`を編集して指定された値を入力します。
```
#twicas
client_id = '***'
client_secret = '***'
user_id = '***'
webhookurl = '***'
calltime = 10 #ループの時間(分)
```
最後に`main.py`を実行すれば…
たぶん動きます。

# 参考資料
・[APIv2ドキュメント](https://apiv2-doc.twitcasting.tv/#introduction)
・[ツイキャス-デペロッパー](https://twitcasting.tv/developer.php)
vdexファイルのデコンパイル

カスタムアンドロイドにてよくわからないAPIを調べるとき用。
要するに以下に無い場合は端末内にあるはず。という前提で
https://cs.android.com/

あらかじめstringsとgrepで当たりをつけておくと楽

# 流れ
vdex -> cdex -> dex -> jar(classファイル) -> jar(javaファイル) -> jar解凍

# vdex -> cdex

vdexExtractorを使う。
https://github.com/anestisb/vdexExtractor

READMEにはdependencyとかdisassembleとか書いてあるけど
とりあえずiとoを指定してやればcdexファイルが出来る
ヘルプに出てくる=(イコール）は不要

# cdex -> dex
cdexはcompact dexとか言うらしい。
https://github.com/anestisb/vdexExtractor/issues/23
の compact_dex_converter_linux.zip を落として解凍すればそのまま使える。
windowsからだとそれっぽいのが添付されているので
それで行けるんじゃないかな？（未確認）

なんとか.cdex.new というファイルが作成されるので
.dexにリネームする。

# dex -> jar
ここからは誰か書いてると思うけどdex2jarで

https://github.com/pxb1988/dex2jar

注意点としてはすでにあるもの叩いてもうまく動かず、
usageにある通りに自分でビルドしたものでないとダメっぽい。

# jar(.class) -> jar(.java)
ようやくjavaファイルが出てくる

fernflowerを使う

https://github.com/JetBrains/intellij-community
の
plugins/java-decompiler/engine/
が対象

以下に細かい手順書いてくれてる人がいます。m(__)m
https://troushoo.blog.fc2.com/blog-entry-372.html

jarが巨大ファイルだと重くて進まない可能性があるので
先に解凍してからclassファイルを個別にやった方が良い場合もある。

# 解凍
unzip なり jarなりで普通に解凍するだけ
Matplotlibで日本語を表示する一番楽な方法

#問題

Matplotlibでグラフを描画する際、タイトルや軸ラベルに日本語を指定すると、環境によっては次のように文字化けして表示されません。

![Unknown-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1940763/4392127d-9fd1-e39b-8cd1-115b04562f6c.png)


調べると解決法はたくさん出てきますが、フォントが存在しないだのエラーが出て、すぐにうまくいくものを見つけるのには苦労しました。ここでは、<b>Google ColaboratoryでMatplotlibを使う際</b>に、確実に成功する簡単な方法を一つ紹介します。

#解決法

①次のモジュールをインストールする

```
pip install japanize-matplotlib
```

②使用するコードに次の一行を書き加える 

```python
import japanize_matplotlib
```

####結果
日本語が文字化けしない！

##実行例

```Python
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib

x = np.random.rand(100)
y = np.random.rand(100)

plt.scatter(x, y)
plt.scatter(x, y)
plt.title("タイトル")
plt.xlabel("x 軸")
plt.ylabel("y 軸")
```

![Unknown-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1940763/e0c08d15-95dc-ad41-ba6c-bd8c720394b4.png)


##参考サイト
[Matplotlibの日本語文字化けを解消する(Mac編)](https://datumstudio.jp/blog/matplotlibの日本語文字化けを解消するwindows編/)
Python Seleniumでスクレイピングする時、エラーが爆発

selenium 4.1.0でスクレイピングした時、エラーが多数発生する。
from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(executable_path='C:/webdriver/chromedriver.exe')
driver.get('https://www.yahoo.co.jp/')
ホウレンソウの"ホウ" 〜進捗報告編〜

# 新人エンジニアの進捗報告あるある
私　「進捗どうですか？」
新人「えーっと、今は〜機能の実装中でJavaScriptを書いてます。」
　　「〜機能を実現するために◯◯ファンクションを作成して、□□しようとしているんですが」
　　「●●のせいでうまくいかなくて悩んでいます・・・」
　　　　（中略）
　　「・・・以上です！」
私　「・・・予定していた分の実装は終わりましたか？」
新人「それは終わってます！」
私　「じゃあ、今は少し巻いている状況ですか？」
新人「そうです！！」
私　「・・・」
# "ホウ"って
　世間でよく聞く「ホウレンソウができない」は、だいたい「報告」がうまくできてないことを指している気がしています。「報告」の中でもチームで開発するエンジニアにとって欠かせないのが、日々の進捗報告だと思います。毎年新人の方がチームに加わるたび、教えている簡単な進捗報告のテンプレがあるのでご紹介します。
# 進捗報告の目的
　テンプレをご紹介する前に、そもそも進捗報告の目的が何なのかを考えることから、進捗報告の適切な形を考えてみます。この目的を考えてない、もしくは違う解釈をしているために、適切な進捗報告ができてないひとが多いと思っています。

報告を受ける立場の目的は
（１）現在の状況を把握したい
　（計画に対して遅れているのか予定通りなのか）
（２）再計画したい
　（遅れているなら計画を修正して予定通りに戻したい、もしくはこれ以上遅れないようにしたい）
（３）遅れている原因を解決したい

進捗報告は報告を受ける立場の人が（１〜３）を判断実行できるように、情報を提供することが目的になります。この中で一番大事なのは（１）です。（２）（３）は進捗が遅れている場合（もしくは極端に巻いている場合）に発生することなので予定通りなら必要ないからです。また、複数人から報告を受けていたりすると、全員の情報を把握して整理しなければならないので、一個人の報告する内容は、なるべく簡潔で必要な情報だけに絞られていることが望ましいです。
# 進捗報告のテンプレ
（０）頭の中で（１）〜（５）を整理する
（１）現在の状況（遅れている or 予定通り or 巻いている）
（２）どれくらい計画と違うのかを％で伝える（ex.予定に対して８０％くらい）
（３）残りがどれくらいかかりそうなのか時間で伝える（ex.あと３時間ほどかかりそう）
（４）計画とずれている原因
（５）現在の状況、懸念点

（１）から順番に報告を受ける立場の人の反応を確認しながら話します。現在の状況が「予定通り」のときは、（１）だけで進捗報告の目的を達しているので（２）以降は不要なことが多いです。遅れている際も（３）まで報告し遅れが小さい場合などは（４）以降の報告が不要になることもあります。
# さいごに
簡単にですが進捗報告のテンプレをご紹介しました。
もっといいテンプレあるよなどご意見いただけると嬉しいです。
【Project Euler】Problem 53: 組み合わせ数

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 53. 組み合わせ数

原文 [Problem 53: Combinatoric selections](https://projecteuler.net/problem=53)

**問題の要約：$1 \le n \le 100$ で以下の組み合わせ数が$10^6$を超える数を求めよ**

```math 
 \begin{pmatrix} n \\ r \end{pmatrix}
```
組み合わせ数は**sympy**の**binomial**を、それに入力する$n,r$は**combinations_with_replacement**で生成します。

```python 
from sympy import  binomial 
from itertools import combinations_with_replacement as combr
n, N = 100, 10**6
print(f"Answer: {len([c for c in [binomial(n,r) for (r,n) in combr(range(1,n+1),2)] if c>N])}")
```

（開発環境：Google Colab）
【Project Euler】Problem 52: 並び替えの倍数

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 52. 並び替えの倍数

原文 [Problem 52: Permuted multiples](https://projecteuler.net/problem=52)

**問題の要約：ある数の2x,3x,4,x5,x6の数が全部並び替えると元の数と同じになる最小の数を求めよ**

並び替えて同じがどうかは「[Problem 49: 並び替え素数](https://qiita.com/masa0599/items/f85bf2601bc99faf2ab9)」で作った**isPermSame**を使います。

```python
def isPermSame(n1, n2):
  return ("".join(sorted(str(n1)))) == ("".join(sorted(str(n2))))

def isPermMulSame(n, m):
  for mul in range(2,m+1):
    if not isPermSame(n, n*mul):   # if not permutation same 
      return False
  return True

for n in range(100,167000+1):
  if isPermMulSame(n, 6):
    break

print(f"Answer: {n}")
```

（開発環境：Google Colab）
Project Euler】Problem 51: 数字の置き換え素数

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 51. 数字の置き換え素数

原文 [Problem 51: Prime digit replacements](https://projecteuler.net/problem=51)

**問題の要約：数字の部分を0,1,2,3,...,9で置き換えたときに8個が素数になるときその最小の素数を求めよ**

```math
5桁の例 \\
"56**3"の"*"を0,1,2,3, \dots 9で置き換える　\\
56003, 56113, 56333, 56443, 56663, 56773, 56993の7個が素数
```

問題51になって急に難しくなりましたね。以下のような順番に考える必要があると思われます。数字の桁数を**N**, **"\*"**の数を**M**とします。

１． **"\*"**以外の**N-M**桁の数字を生成する。あとで順列を取るのでここは「重複ありの組み合わせ」で**itertools**の**combinations_with_replacement**を使います。
２． １．で生成した数字に**M**個の"\*"を連結した文字列の「重複ありの順列」を生成します。このプログラムは意外に難しいのですが、幸いにも**more_itertools**の**distinct_permutations**というものを見つけたのでこれを使います。試してみると以下のように思ったように動きました。

```python
from more_itertools import distinct_permutations
for p in distinct_permutations('**2'):
    print(''.join(p))
# **2
# *2*
# 2**
```
３．生成した"\*"入りの文字列の"\*"を0,1,2,3で置き換えて素数の数を数える。これを**prmsDigRep**で行っています。例題の”5603”を入力すると7つの素数が出来ることが分かります。

```python
ps = prmsDigRep("56**3")
print(ps)
# [56003, 56113, 56333, 56443, 56663, 56773, 56993]
```
これらを組み合わせ出来たプログラムです。

```python
from more_itertools import distinct_permutations
from itertools import combinations_with_replacement
from sympy import isprime

digs = [str(d) for d in range(10)]   # "1","2",..."9"
def repask(num,d):  # replace "*"s of num with d
  ret = num.replace("*",d) 
  return "0" if ret[0] == "0" else ret  # if leading zero, return 0

def prmsDigRep(dps):   # List up all primes, when dsp's "*" are replaced all digits
  return [p for p in [int(repask(dps,d)) for d in digs] if isprime(p)]

def minPrimeDigRep(N, M, nPr):
  for nnn in combinations_with_replacement(digs, N - M):
    for dp in distinct_permutations(list("".join(nnn) + "*"*M)):
      prms = prmsDigRep(''.join(dp))
      if len(prms) >= nPr:
        return prms[0]
  return None

N, M, nPr = 5, 3, 8   # N: digits, Msk: num of masks, nPr: num of prime value
for N in range(6,10):
  ans = minPrimeDigRep(N, M, nPr)
  if ans != None:
    print(f"Answer: {ans}, N={N},M={3}")
    break
```
（開発環境：Google Colab）
Windows10にWSL2をセットアップする

## Ubuntu-20.04をインストール

Powershellを起動して、下記コマンドでインストーラをダウンロード&インストールします。

```powershell:powershell
# Ubuntu.appxというファイル名としてダウンロード
Invoke-WebRequest -Uri https://aka.ms/wslubuntu2004 -OutFile Ubuntu.appx -UseBasicParsing

# ダウンロードしたファイルを元にアプリインストール
Add-AppxPackage .\Ubuntu.appx

# Versionを1から2に変更する
wsl --set-version Ubuntu-20.04 2

# Versionを確認する
wsl -l -v
```
VERSIONが2になっていればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533960/f7ae0267-0e5c-6c0e-936f-13b6864a5de9.png)


### Ubuntu-20.04の設定

以下ユーザー名の入力を求められたら**何も入力せず、ウィンドウを閉じましょう**。
そうすることでrootで自動ログインできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533960/0129a878-e346-43e5-fbb6-1d54cd05135a.png)


以上
【Postgres】SQL文の実行速度を調査する方法

# 目的
業務でついにチューニングをさせてもらえることになり、

1. 実行しているSQL文のログを出力
2. 現状のSQL文の実行速度を計測
3. SQL文の修正

という流れを考えている。

そこでどのようにして実行速度を計測するのか調べた。


大量データの登録方法は「[【Postgres】SQLの勉強のために大量のテストデータを登録してみる」](https://qiita.com/yutoun/items/2033a62d62812da359ed)にて確認。

# 環境
PostgreSQL 14.1 (Ubuntu 14.1-1.pgdg18.04+1) on x86_64-pc-linux-gnu

# いざ、EXPLAIN文を実行
```
explain select * from customer;
                        QUERY PLAN
-----------------------------------------------------------
 Seq Scan on customer  (cost=0.00..2.00 rows=100 width=42)
```
なんだか情報が少ない気がする

# analyzeオプションをつける
analyzeオプションをつけることでより詳細な実行結果が表示される

```sql
$ explain analyze select * from customer;

Seq Scan on customer  (cost=0.00..2.00 rows=100 width=42) (actual time=0.007..0.012 rows=100 loops=1)
Planning Time: 0.029 ms
Execution Time: 0.110 ms
(3 rows)
```

actual time：処理時間
rows：実行した結果、戻ってきた行数
loops：ステップの実行回数
Planning time：解析されたクエリから実行計画を生成し、最適化するまでの時間
Execution time：実行時間

# formatオプションをつける

formatオプションをつけると「なんだか、見づらい」と思った人もフォーマットを指定して表示することができる。

```sql
explain (format json) select * from customer;
             QUERY PLAN
------------------------------------
 [                                 +
   {                               +
     "Plan": {                     +
       "Node Type": "Seq Scan",    +
       "Parallel Aware": false,    +
       "Async Capable": false,     +
       "Relation Name": "customer",+
       "Alias": "customer",        +
       "Startup Cost": 0.00,       +
       "Total Cost": 2.00,         +
       "Plan Rows": 100,           +
       "Plan Width": 42            +
     }                             +
   }                               +
 ]
(1 row)
```

# まとめ
これでSQLの実行時間がわかった。
あとはどれくらいの実行速度が早いのか遅いのかをもう少し調査しようと思う。
Vagrantでローカル開発環境を用意しよう

##概要

開発をしていると、サービスの動作確認をするためにチームメンバー全員に同じローカル開発環境を用意したいと思うことはないでしょうか。

この記事は、ローカル開発環境のベースとなる仮想サーバを簡単に用意できるVagrantというツールについて、メリットや利用方法をまとめたものです。

## この記事で伝えたいこと
- Vagrantを利用するメリット
- Vagrantの基本的な利用方法

## Vagrantとは

Vagrantとは簡単にいうと、端末内で仮想サーバーを管理することができるツールです。Vagrantfileというファイルに仮想サーバーの設定を記述して、コマンドによって設定した仮想サーバーを管理(起動・停止・破棄)します。
※ インストールの手順は以下の記事を参考にしてください。
[【設定方法】配布可能な環境を簡単に構築することができるVagrantをMacのHomebrewでサクッとインストールする手順 | とあるクリエイターのエンジニアブログ](https://t-cr.jp/memo/38179b6d3503b352)


## Vagrantのメリット

他にも仮想サーバを構築する方法はありますが、その上でVagrantを利用する理由は何でしょうか?

私が思うVagrantを利用する大きなメリットは以下の2つです。

1. 誰でも同じ仮想サーバーを簡単に用意できる
VagrantはVagrantfileに記述した設定を元に、コマンドを実行して仮想サーバーを起動します。言い換えれば、同じVagrantfileさえあれば誰でも同じ仮想サーバーを起動できます。

2. 複数台の仮想サーバーを一括で管理できる
また、Vagrantfileには複数台の仮想サーバーについて設定を記述することもできます。
例えば、APサーバーを3台、DBサーバーを1台立ち上げたいという場合にも、記述した設定をコマンドで一括で管理(起動・破棄など)できます。


## Vagrantによるローカル開発環境構築

以下では、実際にVagrantで仮想サーバーを起動するまでの手順を簡単に説明します。

### Vagrantfileの作成

以下の内容のファイルを、Vagrantfileという名前で作成します。
以下ファイルでは、ホスト名、box(OSのイメージ)、IPアドレスを設定しています。

```ruby
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

  config.vm.define "sample-ap" do |server|
    server.vm.box = "generic/ubuntu2004"
    server.vm.network "private_network", ip: "192.168.33.21"
  end

  config.vm.define "sample-db" do |server|
    server.vm.box = "generic/ubuntu2004"
    server.vm.network "private_network", ip: "192.168.33.22"
  end
end
```
チームで開発している場合は作成したファイルをgitで管理することで、チームメンバー全員が同様の環境を構築できます。


### 仮想サーバーの起動・疎通確認

Vagrantfileがあるディレクトリで`vagrant up`を実行すると、Vagrantfileに設定を記述した仮想サーバが一括で起動します。

仮想サーバー起動後はデフォルトで作成される`vagrant`ユーザーを利用して、`vagrant ssh ホスト名`で外部のサーバーと同様に接続して利用できます。

```console
# 仮想サーバーを起動
$ vagrant up 

# 仮想サーバーに接続
$ vagrant ssh sample-ap

```


## まとめ

ここまで、Vagrantのメリットと基本的な利用方法について説明しました。
改めて、自分が思うVagrantを利用するメリットは以下の通りです。

1. gitでVagrantfileを管理することで、チームメンバー全員が同じ仮想サーバーを簡単に用意できる
2. 設定ファイルを利用することで、複数台の仮想サーバーでもコマンドで一括管理できる

皆さんもVagrantを利用して開発環境を整えてみてはいかがでしょうか。


## 補足
- Vagrantでは開発環境のベースとなる仮想サーバーのみを作成します。そのため実際に動作確認に利用するには、Ansibleなどの構成管理ツールでツールのインストール、アプリのデプロイなどを行う必要があります。


## 参考
- [【設定方法】配布可能な環境を簡単に構築することができるVagrantをMacのHomebrewでサクッとインストールする手順 | とあるクリエイターのエンジニアブログ](https://t-cr.jp/memo/38179b6d3503b352)
WebCrypto APIがundefinedになることがあるのは仕様でした

WebCrypto API (window.crypto.subtle)が'undefined'になって悩んで色々調べたら
WebCrypto APIは「Secure Contexts」でないと使えないとのことだった。

##

#詳細
MDN:

https://developer.mozilla.org/ja/docs/Web/Security/Secure_Contexts/features_restricted_to_secure_contexts

WebCrypto APIが非安全なコンテキストで使用できないことを問題にする話は、
chromiumやらFireFoxのIssueに出てくるが
既にW3Cで決めていることらしいのでそこを変えない限りは各ブラウザは仕様通りということなので正常な動作。

このコメントみたいに社内システムで使おうとして、引っ掛かりました。

https://github.com/w3c/webcrypto/issues/28#issuecomment-622006127

MDNには上記の通り「安全なコンテキストに制限されている機能」のページはあるのだけど、
「WebCrypto API」のページには書いていないのではまり期間が長くなってしまった。

https://developer.mozilla.org/ja/docs/Web/API/Web_Crypto_API

【追記】
英語版のCrypto/subtleにはでかでかと書いてあるが、日本語版だと消えている。

https://developer.mozilla.org/en-US/docs/Web/API/Crypto/subtle

##Secure Contextsとは

https://developer.mozilla.org/ja/docs/Web/Security/Secure_Contexts

これを読めばいいけど雑に言うと、
「httpsかwssもしくはホストが自分自身(アドレスが127.0.0.1/8(ip6だと::1/128)かfile://」ならSecure Contexts。
localhost(127.0.0.1)で動くからって別サーバーに置いたとたんに動かなくなるとか起こる(起きた)。

#おまけ

これが原因だったかわからないが、こんなことが調べている最中に見つかったりした

https://github.com/vuejs/vue/issues/3230

おまけ２(2022/2/10追記)

MDN英語版だとCrypto.subtleページの先頭に"Secure contextじゃないと使えないぞ"って注意書きが出てきてくれる。

https://developer.mozilla.org/en-US/docs/Web/API/Crypto/subtle

残念ながら日本語版だと書いていない。

https://developer.mozilla.org/ja/docs/Web/API/Crypto/subtle
えっ！？マウスのホイールがタブ切り替えに固定されている！？

# こうしたら直った
一度右クリック＋ホイール操作を行いました。

Bluetootheマウスがタイトルの通りになり、接続し直しても戻らず、えっ地味に面倒臭い……って絶望しかけました。
パブリックDNSまとめ(ざっくり)

# パブリックDNSとは

- インターネットに接続していれば原則として誰でも、どこからでも利用可能なDNSサーバ(主にDNSキャッシュサーバ)
- 一般的にLAN内やISPが用意したDNSキャッシュサーバを使用したほうが応答速度やセキュリティは有利
- ただし、それらによって満足なパフォーマンスが得られない場合には選定の対象となる

# パブリックDNS一覧

※ 有名どころのみ

|サービス名|運営組織|優先/代替|IPv4|IPv6|ドメイン名|備考|
|:--|:--|:--|:--|:--|:--|:--|
|[Google Public DNS](https://developers.google.com/speed/public-dns)|Google|優先|8.8.8.8|2001:4860:4860::8888|google-public-dns-a.google.com|定番|
|||代替|8.8.4.4|2001:4860:4860::8844|google-public-dns-b.google.com|定番|
|[1.1.1.1](https://1.1.1.1/dns/)|Cloudflare/APNIC|優先|1.1.1.1|2606:4700:4700::1111|one.one.one.one<br>1dot1dot1dot1.cloudflare-dns.com|プライバシー優先、速い<br>DNSサービスアプリ「1.1.1.1」にてWARPと呼ばれるWireguardベースの高速なVPNも提供している|
|||代替|1.0.0.1|2606:4700:4700::1001|one.one.one.one<br>1dot1dot1dot1.cloudflare-dns.com|プライバシー優先、速い|
|[1.1.1.1 for Families](https://1.1.1.1/family/)|Cloudflare/APNIC|優先|1.1.1.2|2606:4700:4700::1112|security.cloudflare-dns.com|マルウェアのブロック機能付き|
|||代替|1.0.0.2|2606:4700:4700::1002|security.cloudflare-dns.com|マルウェアのブロック機能付き|
|[1.1.1.1 for Families](https://1.1.1.1/family/)|Cloudflare/APNIC|優先|1.1.1.3|2606:4700:4700::1113|family.cloudflare-dns.com|マルウェアとアダルトコンテンツのブロック機能付き|
|||代替|1.0.0.3|2606:4700:4700::1003|family.cloudflare-dns.com|マルウェアサイトとアダルトコンテンツのブロック機能付き|
|[OpenDNS Home](https://signup.opendns.com/homefree/)|Cisco|優先|208.67.222.222|2620:119:35::35|dns.opendns.com|2015年、CiscoはOpenDNSを買収した|
|||代替|208.67.220.220|2620:119:53::53|dns.opendns.com||
|[OpenDNS Family Shield](https://www.opendns.com/setupguide/#familyshield)|Cisco|優先|208.67.222.123|::ffff:d043:de7b|familyshield.opendns.com||
|||代替|208.67.220.123|::ffff:d043:dc7b|familyshield.opendns.com||
|[Quad9](https://www.quad9.net/service/service-addresses-and-features/)|CleanerDNS|優先|9.9.9.9|2620:fe::fe||CleanerDNSはIBMからのサポートを受けている|
|||代替|149.112.112.112|2620:fe::9|||
|[Quad9 Unsecured](https://www.quad9.net/service/service-addresses-and-features/)|CleanerDNS|優先|9.9.9.10|2620:fe::10|||
|||代替|149.112.112.10|2620:fe::fe:1|||
|[Quad9 Secured w/ECS](https://www.quad9.net/service/service-addresses-and-features/)|CleanerDNS|優先|9.9.9.11|2620:fe::11|||
|||代替|149.112.112.11|2620:fe::fe:11|||
|[Alternate DNS](https://alternate-dns.com/)|Alternate DNS|優先|76.76.19.19|2602:fcbc::ad||
|||代替|76.223.122.150|2602:fcbc:2::ad||

その他にも

- [AdGuard DNS](https://adguard-dns.com/ja/welcome.html)
- Verisign Public DNS ※ サービス終了済み(?)
- Norton ConnectSafe ※ サービス終了済み
- [CleanBrowsing](https://cleanbrowsing.org/)
- [OpenNIC Public Servers](https://servers.opennic.org/)
- [NextDNS](https://nextdns.io/)
- [RethinkDNS](https://www.rethinkdns.com/)
- [ControlD](https://controld.com/)

等、様々なサービスが存在する
記事一覧

記事一覧

◆システム開発、要求定義、要件定義等
---

[ロジカルコミュニケーション等メモ](https://qiita.com/xyz666/items/5f826c0dfbc740cc1e96 "テキスト")

[図解・図形表現メモ](https://qiita.com/xyz666/items/586c0900f805ec078366)

[要件定義や外部設計時の設計ツール](https://qiita.com/xyz666/items/c1ed9783dea9479c514b)

[ドキュメントレジュメ](https://qiita.com/xyz666/items/8b435a082c65242f9f16)

[ウォータフォールモデルのプロジェクト管理](https://qiita.com/xyz666/items/046350a0fca5eb500881)

[データベース理論のメモ](https://qiita.com/xyz666/items/b6a109e5ba982e31752b
)

[情報セキュリティ基本](https://qiita.com/xyz666/items/8a23a712ec650b768ce6)

[UML概要](https://qiita.com/xyz666/items/2c8c804f055fe7cfa0cd)

[ユースケース図](https://qiita.com/xyz666/items/a825d80ac0025ca4bd82)

◆LINUX
---
[システムアーキテクチャ](https://qiita.com/xyz666/items/be5b7e17e44b4a7511b4)

[RPMパッケージの管理](https://qiita.com/xyz666/items/b80988aecd7ec190a845)

[インストールとパッケージ管理](https://qiita.com/xyz666/items/466cd6c19a480bc77a76)

[コマンドラインの基本](https://qiita.com/xyz666/items/fc924f5cdf0a3dc45e62)

[ファイル操作コマンド](https://qiita.com/xyz666/items/9d21f5dab2fc5a6c82cc)

[パイプとリダイレクト](https://qiita.com/xyz666/items/b555be4dadd06d7a61e7)

[CentOS8でApache+PHP7+PostgreSQL12の環境構築](https://qiita.com/xyz666/items/866898f6804abbf5ccd8)

2.PostgreSQL

[PostgreSQL12.5でDB2台の非同期レプリケーションの設定](https://qiita.com/xyz666/items/f5c8389f4220b7e3396a)

[CentOS6.7にPostgreSQL9.5をインストールする](https://qiita.com/xyz666/items/7dd59821659b130b0393)

[PostgreSQL9.5 から 11.12 にアップグレードする](https://qiita.com/xyz666/items/4a8baab3e0a785f3fa4b)

◆Excel
---
[ショートカットキー覚書](https://qiita.com/xyz666/items/2892dc2c19691cbabbf3)

[VBAメモ](https://qiita.com/xyz666/items/a460f541b68d6ed01ea5)

[複数ブックのシートを1シートに集約する](https://qiita.com/xyz666/items/ee05ed5f6d9aa860ac9d)

[フィルタしてフィルタ値毎にファイル分割する](https://qiita.com/xyz666/items/e9e7b21d1ee7fc133de7)

◆その他
---
[VMwareでCentOS8のゲストOSを作成する](https://qiita.com/xyz666/items/77bb16e8d40b0d25d47f)

[RedPenをCentOSで動かす](https://qiita.com/xyz666/items/fff8fce249b604774018)

[RedPenをWindowsで動かす](https://qiita.com/xyz666/items/5c3de1d604d9809762b7)

[WindowsでJSP＆Servlet実行環境の作成](https://qiita.com/xyz666/items/b15eefcc98b4ef4eeba9)

[EclipseでJava開発環境作成 for Windows](https://qiita.com/xyz666/items/dd1a87d5696eeaa0acc7)

[Oracle　データ・ディクショナリのメモ](https://qiita.com/xyz666/items/0242143adb7acf349456)

[Tomcatのサーバ状態をPowerShellでテキスト取得する](https://qiita.com/xyz666/items/691415176c0300c60571)

[ブラウザメンテ用ＵＲＬ](https://qiita.com/xyz666/items/de0f12df60190ce35ea7)
トランザクション署名 とは

## 勉強前イメージ

署名？

## 調査

### トランザクション署名 とは

MITB攻撃を防ぐために効果的な、ワンタイムパスワードを使用した認証方法のことを指します。
それぞれ確認していきます。

### まず MITB攻撃 とは

Man In The Browser の略で、MITBと呼ばれますが、インターネットバイキングを対象とした攻撃で
金融機関の口座所有者を対象として、コンピュータをマルウェアに感染させて、インターネットバンキングの利用状況を監視します。
監視の後、ログイン情報やセッション情報を乗っ取り、金融詐欺を行います。
これがMITB攻撃と呼ばれるものです。

### 改めてトランザクション署名とは

`インターネットバンキングの乗っ取り、金融詐欺に効果的な` ワンタイムパスワードトークンを使用した認証方法になり、
インターネットバンキングで行った取引(トランザクション)が改ざんされていないかを認証してから取引できるような仕組みです。

流れとしては以下になります。

1. ユーザがブラウザでインターネットバンキングの取引情報を記入し、ワンタイムパスワードトークンで署名を作成します。
2. ユーザは取引情報と署名をインターネットバンキングに送信
3. インターネットバンキングはユーザ情報を署名検証サーバに送信
4. 署名検証サーバは署名を作成
5. ユーザからの署名と署名検証サーバからの署名を突き合わせる
6. 署名が一緒であれば取引を続行する

## 勉強後イメージ

なかなかMITBが難しい・・・からあまり理解できないかもしれないけど、
ワンタイムパスワードで取引(トランザクション)の署名を作るってことか。
特に金融機関ってお金に直結するから・・・

## 参考

- [MITB攻撃（Man-in-the-Browser）とは？仕組みや注意点、対策について徹底解説](https://cybersecurity-jp.com/column/39437)
PostGIS、PostgreSQLでよく使うコマンド（psql）

## はじめに
PostGISのデータベースを見るときにいろいろとコマンドを使います。メモをしているノートがちぎれてきたので、Qiitaにメモしておくことにします。適宜追加していければと思います。
（永遠に作業中・・・）

最初のうちは、PostGISのコマンドというよりPostgreSQLのコマンドが多いと思います。

## 環境
psql 10.15


## よく使うコマンド

### ログイン
```
psql -h hostname -p 5432 -U user -d database
```

### ログアウト
```
\q
```

### データベース切り替え
```
\C database
```

### ユーザー確認、データベース確認、テーブル確認、ビューの確認、スキーマの確認　等
```
\du　（ユーザーリスト確認）
\l　 （データベースリスト）
\dt　（テーブルリスト確認）
\dv　（ビューリスト確認）
\dn　（スキーマリスト確認）
\d schema_name.*　　（スキーマ中のテーブルやビューを確認。）
\dv schema_name.*　　（スキーマ中のテーブルやビューを確認。）
\dz　（アクセス権限確認）
```

### ビューやテーブルのコラム確認
```
SELECT column_name FROM information_schema.columns WHERE table_name='table_name';
SELECT column_name,data_type FROM information_schema.columns WHERE table_name='table_name'; （データタイプも確認できる）

```

### 数を数える
```
SELECT count(*) FROM table_or_view;
```

※小ネタ
テキストファイルで複数行のコマンドを書いておいて、コピペして実行すると楽。（もっと効率的なやり方がありそうですが・・・）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/d284dfee-a4b5-5a65-91dc-d74e7a9a8acc.png)



### コラムにある値をみる、値ごとの数を数える
```
SELECT column-name FROM table_or_view GROUP BY column-name;
SELECT column-name,count(*) FROM table_or_view GROUP BY column-name;
```

### ジオメトリを見たいとき
```
SELECT ST_AsGeoJSON(geom) FROM table_or_view;
SELECT ST_AsText(geom) FROM table_or_view;
```



### フォントの変更

```
chcp 1252　（437で戻る）
```

## おまけ：GDALでPostGISからGeoJSONに
```
ogr2ogr -f "GeoJSON" output.geojson PG:"host='hoge' port='5432' dbname='hoge' password='hoge'" -sql "SELECT * FROM table"
```

テキストシークエンスでみるとき↓。

```
ogr2ogr -f GeoJSONSeq -lco RS=YES /vsistdout/ PG:"host='hoge' port='5432' dbname='hoge' password='hoge'" -sql "SELECT * FROM table"
```


## 参考
2022/1/25主にITとかセキュリティの記事

「McAfee Enterprise」のWindows向けエージェントに複数の脆弱性
https://www.security-next.com/133548

「JVN iPedia」、2021年4Q登録は4676件 - 前期比1.4倍に
https://www.security-next.com/133522

若年層向けプログラミングコンテストのサイトで個人情報が流出
https://www.security-next.com/133536

Google Workspace、マルウェアやフィッシングを警告する機能(1/22)
https://k-tai.watch.impress.co.jp/docs/news/1382492.html

子どもデータ連携実証事業へ、「究極の個人情報、国民の意識に沿った検討が必要」(1/21)
https://xtech.nikkei.com/atcl/nxt/news/18/12064/

【続報】寄生サイトの営業は絶対に拒否すべし。グーグルも「全くお勧めしない」【SEO情報まとめ】(1/21)
https://webtan.impress.co.jp/e/2022/01/21/42216

Zoomのゼロデイ脆弱性、Google Project Zero研究者が詳細を公開(1/23)
https://gunosy.com/articles/aImSG

ランサムウェアの次のターゲットは組み込み機器か？(1/23)
https://jp.techcrunch.com/2022/01/23/2022-01-22-embedded-devices-ransomware/

サイバー攻撃対策、経営責任に
政府、重要インフラ強化(1/22)
https://nordot.app/857539263618154496?c=768367547562557440

ブルガリア、仮想通貨決済メカニズムの導入を検討中＝財務相(1/22)
https://jp.cointelegraph.com/news/bulgaria-s-finance-minister-says-country-is-exploring-crypto-payment-options-report

武生第六中の端末ウイルス感染　「継続的に対策強化」市教委が最終報告(1/23)
https://www.chunichi.co.jp/article/405328

米政府の仮想通貨政策はホワイトハウス主導へ、初の戦略来月公表か(1/22)
https://www.bloomberg.co.jp/news/articles/2022-01-22/R63PEKDWX2PT01

出前アプリの割引クーポンの不正使用で逮捕！？ 　モバプリの知っ得(1/23)
https://ryukyushimpo.jp/style/article/entry-1457949.html

データ保護規制、世界で強化　弁護士注目の法務トピック(1/22)
https://www.nikkei.com/article/DGXZQOUC126D80S2A110C2000000/

世界的な高級ブランドでクレジットカード情報の漏洩の可能性があり、クレジットカード会社から番号の変更を提案された件(1/22)
https://blogs.itmedia.co.jp/yoshimasa/2022/01/post_3976.html?ref=rss

WindowsとMac「どっちを買う？」論争、勝手に最終決着。スタイルで選ぶなら(1/23)
https://news.nifty.com/article/magazine/12193-1434929/

WhatsApp、米政府の命令で中国とマカオのユーザーを追跡(1/23)
https://www.zaikei.co.jp/article/20220123/657129.html

ライアットゲームズがメールでの多要素認証システムを導入―公式サイトやゲームクライアントのセキュリティ強化へ(1/22)
https://www.gamebusiness.jp/article/2022/01/22/19553.html

いつの間にか時代遅れに？買い替えを検討したいWi-Fi 4ルーター(1/21)
https://xtech.nikkei.com/atcl/nxt/column/18/01882/120800004/?i_cid=nbpnxt_ranking

「北京には自前のスマホ持ち込むな」と欧米五輪委、中国当局の監視に懸念？―海外メディア(1/23)
https://news.nicovideo.jp/watch/nw10437685
無料で取得したドメインをCloud Load BalancingのIPに紐づける

# はじめに

無料でドメインを取得して`Cloud Load Balancing`のIPに紐づける方法をメモする

参考

https://www.udemy.com/course/google-cloud-platform-gcp/

# やり方

# 無料ドメインを取得する

https://www.freenom.com/ja/index.html

## ①取得したいドメイン名を検索し、`チェックアウト`
![スクリーンショット 2022-01-25 3.27.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555632/7cd2bc0c-0b0f-dcbe-d935-b1aa9dfa0437.png)

## ②`Domain`をhikaeteoku
![スクリーンショット 2022-01-25 3.29.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555632/2f931120-497f-2752-c677-f1c6927c6338.png)

# `DNS`の`ゾーン`を作成する

## ①`Cloud DNS` > `ゾーン`を作成
![スクリーンショット 2022-01-25 3.23.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555632/afe122db-0370-55b1-42e2-7d033e9716ad.png)

## ②`DNS`名に先ほど取得したドメイン名を入力する

![スクリーンショット 2022-01-25 3.25.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555632/a3c10a20-eaa0-aa4f-b1de-f96052a1b2af.png)

# 作成した`DNS`のリソースレコードを確認
![スクリーンショット 2022-01-25 3.33.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555632/804cebce-8010-d486-b3f5-21a3a68b9082.png)

## `NS(ネームサーバー）`詳細からデータを`Nameserver`に入力
**2つまで入力する（残りは後半の手順で追加で登録します）**


### 入力完了後、`Continue`をクリックし注文を確定する

**「edomains.com.」 末尾の「.」（ドット）は省いたデータを入力する** 


![スクリーンショット 2022-01-25 3.35.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555632/27662269-335f-e71d-b303-b046a652c58b.png)

# 注文確定後、`My Domains`にアクセスする

https://my.freenom.com/clientarea.php?action=domains

![スクリーンショット 2022-01-25 3.43.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555632/4c15152a-f96d-0fbf-35d3-daa48ffb9c26.png)

## `Manage Domain`をクリック

![スクリーンショット 2022-01-25 3.46.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555632/3a63d05c-43eb-bca9-61a4-b2a8d3fa0459.png)

## `Manage Freenom DNS`をクリック

![スクリーンショット 2022-01-25 3.47.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555632/dbc7fdb8-36f8-e977-e57c-91f26771bd63.png)

## `Edit Baneservers`をクリック

![スクリーンショット 2022-01-25 3.47.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555632/3f41bdba-7218-f54e-8334-676e6c7c33c1.png)

## 残り2つの`NS`データを入力し`Change nameservers`する
![スクリーンショット 2022-01-25 3.48.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555632/5571cbca-98e4-dcb3-d299-a8ebd0e7967a.png)

# `ClouCloud Load Balancing`の`IPアドレス`を控える

![スクリーンショット 2022-01-25 3.51.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555632/fa24d7ba-4922-5f9a-4049-c1cee3deb204.png)

# `Cloud DNS`レコードセットを追加

![スクリーンショット 2022-01-25 3.55.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555632/a3adf262-54ee-77b8-bf05-9e5c53f60738.png)


# 最後に
読んでいただきありがとうございます。
いいねしていただけると記事執筆の励みになりますので、参考になったと思った方は是非よろしくお願いします！
curl 基本コマンド

## はじめに
　本記事は、プログラミング初学者が、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

## curl 基本コマンド

```:Terminal
#GETのAPIリクエスト
$ curl http://URL 

#'-s'で終了ステータスのみを表示
$ curl -s http://URL

#'-s'はerror情報も省略するが、'-Ss'はerror情報があれば表示。'-o'で出力先を指定。
$ curl -Ss -o 出力先PATH http://URL 

#'-v'でheader情報も表示
$ curl -v -s http://URL

#'-L'でリダイレクトがあったらリダイレクト先の情報を取る 
$ curl -L http://URL 

#'-X'でHTTPメソッドの指定（指定しなかったらGETになる）
$ curl -X PUT http://URL 

#'--data'でPOSTメソッドでデータを送ることができる
$ curl -X POST --data 'id=xx&name=example' http://URL

# '-I'でHTTPレスポンスヘッダーの取得
$ curl -I http://URL

#jqでjson表示を見やすく
$ curl https://xxx.xxx.com/api/ | jq . 

```
ESP32とのWiFi経由通信で遅延がひどかった話(Arduino)(Telnet)

ESP32にTelnetを実装しようとしていた時に引っかかったので記録します。

# 問題

ESP32上でTelnet経由で文字列を送っていた時に、文字の更新間隔にラグがあることに気づいた。

**何かが遅延している**と考えPingを打ってみると

```
ESP32 からの応答: バイト数 =32 時間 =44ms TTL=255
ESP32 からの応答: バイト数 =32 時間 =270ms TTL=255
ESP32 からの応答: バイト数 =32 時間 =87ms TTL=255
ESP32 からの応答: バイト数 =32 時間 =312ms TTL=255
```

やっぱり何かが遅延している

# 原因

**ESP32 ping slow**で検索

一番上のサイトに直行 

https://github.com/espressif/arduino-esp32/issues/1484

サイトのコードは所々スペルミスをしているので注意

調べてみた結果

原因はESP32が**WiFi省電力モードに入っているために起こる遅延**だったようです

# 対策

原因が**WiFi省電力モード**のため、そいつを**無効化**してやればいい

詳細はespサイトで説明してくれています。

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#esp32-wi-fi-power-saving-mode

省電力モードを無効化するためには、

```C++
#include "esp_wifi.h"

void setup(){
	WiFi.mode(WIFI_MODE_STA);
	WiFi.begin(ssid, password);
	
	esp_wifi_set_ps(WIFI_PS_NONE);
}
```

みたいな感じで`WiFi`の設定後に`esp_wifi_set_ps(WIFI_PS_NONE)`を呼び出せば良いみたい。
amazon linux(EC2)でlaravel+Dockerの環境を作りたい

最近インフラ周りの勉強を始めたのでdocker+laravelの環境をEC2上に実現したいと思い奮闘しています。
参考になった記事を貼っていきます。

#記事

【AWS 入門】EC2とDockerでHello Worldしよう

こちらの動画の27:30まで進めます。
この動画でEC2を立ち上げてSSHでEC2にアクセスをしてdockerをインストールしてdocekr infoで確認するところまでいけると思います。

https://www.youtube.com/watch?v=HvrIPQ77xRY

【シンプル解説】docker-composeを使ってLaravel,nginx,MySQL環境構築する
https://simablog.net/docker-laravel-nginx-mysql/

##SSH接続後

phpをインストールする
https://qiita.com/nagahama/items/2fdc820791bee5d564ca

composer　install
https://qiita.com/kawanet/items/30c1acd4bc90ee0e535d

composer installの際のエラー(/usr/local/bin/docker-compose: line 1: Not: command not found)
https://github.com/docker/compose/issues/6268


amazon linux内でcomposerのpathを通す(どこでもcomposerコマンドを使えるようにする)
https://qiita.com/miriwo/items/b25f9d4d74b7103f6ff6
jiraでチケットに期日を追加する

スクラムのプロジェクトを作成したときにチケットに期日を設定できなかったため、期日をチケットのフィールドに追加するまでの手順を記す。

# 手順
① プロジェクトから適当なチケットを選択して、<font color="Crimson">**右下の設定を選択**</font>。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/7853f973-86b5-b671-41b0-94463f4d30ee.png)

② 課題レイアウトの真ん中上の説明から<font color="Crimson">**Scrum Default Issue Screen**</font>のリンクを踏む。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/794fff7f-c461-f73f-e746-0f61e26f5abb.png)

③ タブを追加を押した後、下の画像のように期日のフィールドを追加する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/9c657640-baaf-f9c2-f2f4-2414903eb593.png)

④ [Optional]再び課題レイアウトに戻り期日をコンテキストフィールドに移動させる。
その後、下の`変更を保存`を押す。

⑤ チケットに戻り、期日が追加されているか確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/94e9a9d2-808f-647d-46f5-6734e4239e0f.png)
WAFのログ有効化＆ロギングフィルターで必要なログのみS3へ直接保存（Terraform）

# 前書き

- Cloud Watchなどにも直接いけます。
- Kinesis Data Firehose？？いやいやワイは直接S3にログをぶちこみたいんや！！ってお方向け。
- WebACLのリソースは作成済みのテイで進めます。

# やり方

## ◾️ おおまかな流れ

1. ログ保管用バケットつくる
2. ロギング構成用リソースを定義
3. ロギングとバケットを紐付け
4. ロギングフィルターを定義

## ◾️ 実・践

適当なバケットを作りましょう。

（※バケットポリシーはWAFのロギング時に自動でアタッチされるっぽいのでこちら用意しなくても良いっぽいです。細かい挙動はちょっとよくワカラナイ。。）

注意点として、bucket名は `aws-waf-logs-`のprefixで始まる必要があるらしいです。

[https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/logging-s3.html](https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/logging-s3.html)

s3.tf

```go
resource "aws_s3_bucket" "b" {
  bucket = "aws-waf-logs-hogehoge"
  acl    = "private"

  tags = {
    Name        = "My bucket"
    Environment = "Dev"
  }
}
```

次にロギング構成用のリソースを定義します。

waf.tf

```go
resource "aws_wafv2_web_acl_logging_configuration" "example" {
  log_destination_configs = [aws_s3_bucket.b.arn]
  resource_arn            = aws_wafv2_web_acl.example.arn // ここは作成済みのweb aclリソースを指定するのじゃ
}
```

リソースタイプながいっすね笑

これでひとまず、WebACLで定義したルールにマッチしたリクエストのログが流れていくと思います。

次にロギングフィルターです。

ロギングフィルターではどのアクセスのログを取るか捨てるかを精査できます。

ちなみにロギングに関してはWAFの追加コストはかからないらしいので、S3の保存料金が上乗せされていく感じみたいです。まあでも少しでもコスト削減できますし、不要なログが増えるの邪魔なんでフィルターしたらいいんじゃないかなと思います。

[https://aws.amazon.com/jp/about-aws/whats-new/2021/12/awf-waf-cloudwatch-log-s3-bucket/](https://aws.amazon.com/jp/about-aws/whats-new/2021/12/awf-waf-cloudwatch-log-s3-bucket/)

先ほどのwaf.tfに追記しましょう。

```go
resource "aws_wafv2_web_acl_logging_configuration" "example" {
  log_destination_configs = [aws_s3_bucket.b.arn]
  resource_arn            = aws_wafv2_web_acl.example.arn

	// 追加
	logging_filter {
    default_behavior = "KEEP"

    filter {
      behavior = "DROP"
      condition {
        action_condition {
          action = "ALLOW"
        }
      }
      requirement = "MEETS_ANY"
    }
  }
}
```

logging_filterブロックで、ログのフィルターを定義しています。
filterがログに適用するフィルター、conditionが条件です。
conditionで指定した条件にマッチしたものがbehaviorで定義されているDROPの挙動になります。（DROPなので、つまりログを保存しないという記述になります。）
また、action_conditionでactionをALLOWとしているので、WebACLで定義したルールのactionがallowのものが捨てられる対象となります。（例えばip制限のルール定義などを行なった場合などはallowを使ったりすると思いますが、その場合許可されたipからのリクエストのログを切り捨てるということになります。）
ちなみに、default_behaviorでデフォルトの挙動（KEEPなのでログを送信する）を定義しています。
あとはrequirementなのですが、これは「または」や「かつ」のような使い方に似ています。
正確には、requirementがMEETS_ALLの場合は全てのconditionに一致した場合のみフィルターが発動します。逆にMEETS_ANYの場合はどれか一つのconditionに一致すれば発動します。
なので、もうお分かりかと思いますが、conditionは一つのfilter内に複数書くことができます。

例）

```go
resource "aws_wafv2_web_acl_logging_configuration" "example" {
  log_destination_configs = [aws_s3_bucket.b.arn]
  resource_arn            = aws_wafv2_web_acl.example.arn

  logging_filter {
    default_behavior = "KEEP"

    filter {
      behavior = "DROP"
      condition {
        action_condition {
          action = "ALLOW"
        }
      }
      // 追加
      condition {
        label_name_condition {
          label_name = "awswaf:111122223333:rulegroup:testRules:LabelNameZ" // ルールのラベルで条件を指定することもできる
        }
      }
      requirement = "MEETS_ANY"
    }
  }
}

```

他にも様々な組み立て方でロギングフィルターのパターンが作れるのでぜひ試してみてください。

少し中途半端ですが今回は以上です！（眠くなったので！笑）
【Swift】知っておきたいKeyPathの基本と使い方

# この投稿は何？
Swiftにおける`KeyPath`について、基本から解説します。

## 実行環境

- macOS 12.1
- Xcode 13.2.1
- Swift 5.5

# KeyPathとは
要は、「あるデータ型に定義されたプロパティまでの参照（パス）」です。

## Swift3時代のString KeyPath
`KeyPath`は、Objective-Cの時代から利用されていました。
Swiftでもそれを受け継いでおり、クラスに`objcMembers'属性をマークすることで利用できました。

```swift:参照型データの場合
@objcMembers class Kid: NSObject {
    dynamic var nickname: String = ""
    dynamic var age: Double = 0.0
    dynamic var bestFriend: Kid? = nil
    dynamic var friends: [Kid] = []
    
    init(nickname: String, age: Double) {
        self.nickname = nickname
        self.age = age
    }
}

// ベン君
let ben = Kid(nickname: "Benji", age: 5.5)

// Kid型のnicknameプロパティへのキーパスを作成
let kidsNameKeyPath = #keyPath(Kid.nickname)    // String

// キーパスを使って取得した「ベン君のニックネーム」はAny型になってしまう
let name = ben.value(forKeyPath: kidsNameKeyPath)   // value(forKeyPath: String) -> Any
print(name as! String)    // Benji
```

この方法で取得したキーパスは、単純な`String`型として保持されます。
そして、`String KeyPath`を利用して取得したプロパティ値は、型情報が失われてしまう性質がありました。

## Swiftに最適化されたKeyPath
Swift4では、全く新しい方法で`KeyPath`を利用できるようになりました。

```swift:値型データの場合
struct BirthdayParty {
    let celebrant: Kid
    var theme: String
    var attending: [Kid]
}

var bensParty = BirthdayParty(celebrant: ben, theme: "Construction", attending: [])
let birthdayKid = bensParty[keyPath: \BirthdayParty.celebrant]
bensParty[keyPath: \BirthdayParty.theme] = "Ninja"

let birthdayKidsAgeKeyPath = \BirthdayParty.celebrant.age           // キーパスを作成
let birthdayboysAge = bensParty[keyPath: birthdayKidsAgeKeyPath]    // 5.5
```

値型データの`KeyPath`では型情報が維持され、よりシンプルに記述されます。
![Property.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70476/b0f02c17-8497-7b5d-cb36-23aed21fe8ef.png)

基点型が推論可能な場合、記述を省略できます。
![age = ben[keyPath Kid.age].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70476/f85ac4bc-5ed0-9b7c-638d-29ddeb5425c8.png)

`ben`は`Kid`型インスタンスなので、基点型は`Kid`であることが推論可能です。
従って、`Kid`を省略して以下のように記述できます。

```swift:
let age = ben[KeyPath: \.age]
```

同様に、`bensParty`は`BirthdayParty`型インスタンスなので、以下のコードも略記できます。

```swift:
bensParty[keyPath: \BirthdayParty.theme] = "Ninja"
bensParty[keyPath: \.theme] = "Ninja"    // 型推論による基点型の省略記法
```

この方法で取得したキーパスは、`ReferenceWritableKeyPath`型として保持されます。
そして、取得した値の型情報も維持されます。
![スクリーンショット 2022-01-23 15.55.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70476/4e0d19cf-1b8f-c1f6-75f2-cea6d5caa5df.png)

## クラスのキーパス
クラスでも同じようにして、キーパスを利用できます。

```swift:
class C {
    var p = ""
}
let c = C()

let cpKeyPaty = \C.p        // ReferenceWritableKeyPath<C, p>
let cp = c[keyPath: \C.p]   // String
```
WEB技術入門（用語の意味）

  
WEB技術入門、基礎用語の説明をいたします。

# リクエスト、レスポンス、プロトコル

WEBアプリケーションはクライアント _（WEBアプリケーション使用者）_ とサーバ _（WEBアプリケーション提供者）_ があることで成立します。
クライアントとサーバのやり取りはURLでサーバを指定し、**HTTPという通信プロトコル**でやり取りをします。
HTTPは大きく分けるとリクエスト、レスポンスというやり取りに使用されますね。

クライアントはサーバにWEBアプリケーションを見せてくれと要求をします。そして、サーバを要求を受けて、HTMLを渡します。
ここでクライアントの要求を**リクエスト**、サーバの渡しを**レスポンス**と言います。

## 通信プロトコル（HTTP）

HTTPだとWEBアドレスに書かれているあれですよね。馴染みのあるものですが、はっきり何か分かりにくいですね。
HTTPは**契約書**だと考えてください。
不動産を売買する時に契約書を書きますよね。
HTTPはクライアントとサーバの間のやり取りの契約です。この契約通りの項目を要請して、契約通りのものを渡してもらう。ということです。


## リクエスト

HTTPのリクエストは主に２つの方式があります。
GETメソッドとPOSTメソッドです。
下のように、私のQiitaに接続すると、リクエストが発生します。
URL（サーバ）にGETメソッドでリクエストを送りました。
Status Codeはレスポンスの結果を表すCODEですが、レスポンスの説明するとき説明します。



![スクリーンショット 2022-01-24 23.01.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/569e6e5e-77b8-4963-9242-aaabe1f7b54c.png)

#### GETメソッド
GETメソッドは簡単なデータをURLに入れるように設計された方式で、URLにやりとりするデータが書かれます。
URLに書いている情報をGETしてきて（READ)、見せるようなイメージです。

私が書いたQiitaの記事のURLを参考にしますと、
qiita.comサーバのparkon_hhsディレクトリの中の、itemsディレクトリの中のdf4a0f3197b5ff22a0abという記事を表します。
※https://qiita.com/parkon_hhs/items/df4a0f3197b5ff22a0ab

URLを入れることでその特定のページを出すことが可能なので、共有やブックマークのため主に使われます。
でもURLにデータが漏出されるので、機密情報のやりとりには向いてないです。

#### POSTメソッド
POSTメソッドはURLにデータが記載されないため、GETメソッドよりはセキュリティー性が比較的に高いです。
POSTメソッドは、主にあるデータをサーバに提出してデータの追加及び修正するため使用する方式です。
例えば、あるサイトにsign upをする際に、POSTメソッドで、入力した個人情報がサーバに伝われるというイメージです。

## レスポンス

リクエストに対して、サーバがクライアントに渡すことです。
何を渡すのでしょうか。
![スクリーンショット 2022-01-24 23.01.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/569e6e5e-77b8-4963-9242-aaabe1f7b54c.png)
上の図のStatus Code と、プログラミングコードを渡します。

#### Status Code 
リクエストに対し、レスポンスの結果のを表すものです。
Status Codeの詳細は下記のURLを参考してください。

https://digitalidentity.co.jp/blog/seo/seo-tech/howto-http-status-code.html

正しいレスポンスを受けることに成功したか失敗したか、失敗だったら、サーバとクライアントどっちから起因した失敗かなどをCodeで表すので状況把握に容易ですね。

# HTTPの特徴



### ステートフル
Twitterなどを利用する時、ログイン状態を維持する機能があって、常にログインされた状態で利用可能ですね。
これをステートフル（Stateful）だと言います。
ユーザーの状態が記憶されていて、ユーザーのことを覚えてくれる。
実はHTTPプロトコルでのやり取りはステートレス（Stateless）で、１分前にリクエストを送ったユーザーのことを覚えて無いのですが、
Twitterアプリケーションがクッキーとセッションというものを使ってステートフルを具現化したということです。

### ステートレス
HTTPはステートレス（Stateless）です。
Statelessの意味はステートフルの反対で、‘状態が無い’です。
ラーメン屋の食券販売機だと覚えばいいでしょうね。
食券販売機は私のことなんかは覚えていません、食券を買うたびに、豚骨ラーメンのボタンを押さないといけません。
HTTPも同じく、私なんかは覚えてません。リクエストを送るたびに、私だと証明書を見せないといけません。
（リクエストの送り際にこの証明書を見せることで、Twitterはステートフルを具現化）

### クッキーとセッション
ステートレスなHTTPプロトコルでステートフルを具現化するための証明書がクッキーの中のセッションIDです。
クッキーはクライアントが持っている証明書（セッションID）を入れる袋です。
HTTPプロトコルでリクエストを送る際に、証明書（セッションID）を入れた袋（クッキー）を一緒に送ります。
そしたらサーバ側では証明書（セッションID）を確認し、認証されることでクライアントはある権限を持つことになります。（TwitterでしたらTweetする権限）
セッションは一連の流れという意味で、一般的にログインからログアウトまでです。
Twitterだと、ログアウトボタンを押して無い限り、証明書があれば、ログインされている状態になります。


# その他

### ポート番号

一つのパソコンには複数のサーバがあることもあって、クライアントからリクエストが来た時にどっちのサーバに繋げるべきかパソコンが混乱してしまう。
こういった状況で異なるポート番号を各サーバに割り振ってあげることで解決する。

詳しくは下記のサイトを参考してください。

https://eng-entrance.com/network-port


以上です！
環境変数パスの通し方〜vueやadonis等のコマンドがcommond not foundになるを解消〜

#vueやadonisのコマンドが使えない
npmインストールしたcliのコマンドが```commond not found```になった。
###参考記事
https://gabekore.org/mac-path-environmental-variable
###解決方法
環境変数を確認する。
ターミナルで```env```を入力
そうすると色々な環境変数が出る。
vueやadonisのコマンドを使用する際に関係するものが
```$PATH```

```
PATH=/usr/local/opt/.........
```
上記のように記述されている。
この記述の場所を読み込む設定になっている。

この設定されているパスがvueやadonisの入っているパスと違うとコマンドが使えない
###各コマンドの場所を確認する(whichコマンド）

```which vue```
whichコマンドでそのコマンドがどこにあるかを確認できる。

```
which vue
/Users/username/.npm-global/bin/vue
```
となる。
そしてこのパスを使用したい場合

```
export PATH=$PATH:/Users/username/.npm-global/bin
```
とする事でPATHの内容を上記```/Users/username/.npm-global/bin```に変更出来る。

これでvueコマンドが使用可能になる。
###しかしこの方法は一時的なもの
後日同様にvueコマンドを入力してもcommand not foundになる事がある。
これを防ぐために固定したいパスは```.bash_profile```に記述をする必要がある。

```
/Users/username/.npm-global/bin
```
に設定したいときは


```
echo 'export PATH=/Users/username/.npm-global/bin:$PATH' >> .bash_profile
```
もしくはvimを使うか、finderで隠しファイルを表示させ、直接bash_profileに

```
export PATH=$PATH:/Users/username/.npm-global/bin:$PATH
```
と入力する。
これで、コマンドが固定で使用可能になる。
bitnami redmine file upload error permission denied

bitnami redmineにてファイルアップロードが権限にて拒否された時の対応です。

下記はエラーメッセージです。

Saving attachment '/opt/redmine-4.1.1-8/apps/redmine/htdocs/files/[ファイル名]' (30800 bytes)
Completed 500 Internal Server Error in 14ms (ActiveRecord: 10.7ms)
Errno::EACCES (Permission denied @ rb_sysopen - /opt/redmine-4.1.1-8/apps/redmine/htdocs/files/[ファイル名]):

app/models/attachment.rb:122:in `initialize'
app/models/attachment.rb:122:in `open'
app/models/attachment.rb:122:in `files_to_final_location'
app/controllers/attachments_controller.rb:108:in `upload'
lib/redmine/sudo_mode.rb:65:in `sudo_mode'


対応方法は下記のコマンドを実行することです。
所有者の変更とフォルダの権限変更が必要です。
=>

chown -R root:daemon /opt/redmine-4.1.1-8/apps/redmine/htdocs/files
chmod -R 775 /opt/redmine-4.1.1-8/apps/redmine/htdocs/files
AWS＋Ray Dashboardポートフォワーディング

# 概要
ローカルPCからWSLでAWS上にRay clusterを作成し、ポートフォワーディングでローカルPC上でRay Dashboardが見られるようにする。

# 環境
- Windows10 Home
- WSL Ubuntuディストリビューションをインストール済み
- Python3、pip3、Ray、botoをインストール済み
- ローカルPCの~/.awsディレクトリ配下のcredentialsにAccess key ID、Secret access keyを入力済み
- 踏み台用EC2を作成済み（EC2はUbuntu）
- 踏み台用EC2に割当てているセキュリティグループでSSHおよび8265番ポートを許可

# 手順
WSL Ubuntuを開き、下記コマンドを実行。

```bash
# 踏み台用EC2にSSH接続
$ ssh -i <踏み台サーバのpemファイル> ubuntu@<踏み台サーバのパブリックIP>

# 以下は踏み台用EC2で実行

# Ray cluster作成
$ ray up -n example-cluster --no-config-cache RayClusterConfig2.yaml

# Dashboard用のデフォルトポート8265番を踏み台用EC2の8265番ポートにフォワーディング
$ ray dashboard -p 8265 --remote-port 8265 RayClusterConfig2.yaml
```

別のWSL Ubuntuを開き、下記コマンドを実行。

```bash
# EC2の8265番ポートをローカルPCの8265番ポートにフォワーディング
$ ssh -i <踏み台サーバのpemファイル> ubuntu@<踏み台サーバのパブリックIP> -L 8265:localhost:8265
```

この状態でローカルPCのブラウザで`http://localhost:8265/`へアクセスするとRay dashboardが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619163/765045c3-50df-47d4-389a-941bd9eae972.png)
sphinx：`code-block`ディレクティブに指定できる言語

# 実行環境
* Python 3.12.1
* sphinx 7.3.7
* Pygments 2.18.0

# はじめに
sphinxのsphinxの`code-block`ディレクティブでは、以下のように`html`など言語を指定できます。


```
.. code-block:: html

    <img src="images/foo.png">
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37903/deebf7a4-85ab-b219-a3ed-a788c98fda07.png)


`code-block`ディレクティブで指定できる言語は、[Pygments](https://pygments.org/)ライブラリで提供しているlexerのエイリアスです。

>The directive’s alias name sourcecode works as well. This directive takes a language name as an argument. It can be any lexer alias supported by Pygments.

https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block

具体的にどのような言語を指定できるか調べました。

# Pygmentsのlexer alias
以下のドキュメントの`Short names`がlexer aliasに対応します。

https://pygments.org/docs/lexers/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37903/cd7b60d1-ffb7-a5ff-8f40-9cf6f53fc32e.png)


利用できるlexerの一覧は、以下のコードで取得できます。

```python
from pygments.lexers import get_all_lexers
# `i[1]`は (name, aliases, filetypes, mimetypes) のaliases を選ぶため
alias_list = [i[1] for i in get_all_lexers()]
# 空のリストが存在したので、それを除外する
alias_list = [e for e in alias_list if len(e) > 0]

print(len(alias_list))
# 585

print(alias_list[0:10])
#[('abap',),
# ('amdgpu',),
# ('apl',),
# ('abnf',),
# ('actionscript3', 'as3'),
# ('actionscript', 'as'),
# ('ada', 'ada95', 'ada2005'),
# ('adl',),
# ('agda',),
# ('aheui',)]
```


lexerのaliasは全部で585個ありました。


# lexar aliasで気になったこと
以下はPython関係のaliasです。

```python
  ('pypylog', 'pypy'),
  ('python2', 'py2'),
  ('py2tb',),
  ('pycon', 'python-console'),
  ('python', 'py', 'sage', 'python3', 'py3', 'bazel', 'starlark'),
  ('pytb', 'py3tb'),
  ('py+ul4',),
  ['ipython2', 'ipython'],
  ['ipython3'],
  ['ipythonconsole']]
```
`python-console`や`ipython3`などコンソール用のaliasも用意されていました。

また、mojoは火の絵文字でも指定していできるようです。

```
('mojo', '🔥'),
```


# lexar aliasの一覧

lexar aliasの一覧をgistに投稿しました。こちらを参照してください。

https://gist.github.com/yuji38kwmt/1776cf1e38b34805df0174d269575ac0
Laravelのバリデーションで自分以外の重複チェック laravel8

# 動作環境
- laravel8

# やりたいこと
emailの重複チェックの対象をログインユーザー以外に行いたい

# 結論
```php
class UserRequest extends FormRequest
{
     /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => ['required', 'string', 'max:255'],
            //'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'email' => ['required', 'string', 'email', 'max:25', Rule::unique('users')->ignore(Auth::id())],
        ];
    }
}

```

# 例えば
<img width="400" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346005/cfd73fd1-5d3f-8696-3215-458b2b12e129.png">

こんなようなフォームを作ってしまいまして、
パスワードだけを変更したいのにこのまま更新をすると
「emailかぶってるよ!!]
と怒られてしまいました。

「自分のemailなんだからそうだろうなっ!!」

と少し揉めましたが
このような形で自身の重複を外すことができました。

# 最後に
laravel勉強中でしてアウトプットとして投稿させていただきました。
ドキュメントを読んでるつもりでも作ってみてわかることは非常に多いですね。

[Laravelの取説にもちゃんとかいてありました。](https://readouble.com/laravel/8.x/ja/validation.html)←

おわり
Windowsで各OSとbitに沿って処理分岐する

キッティングや運用をやってると
OSとbit数によって違う処理と走らせたり、インストーラーが違ったり
毎回めんどくさかったので何かやりようがないかと思い調べて作ってみました。

#動作確認済
Windows10 (64bit) 20H2
   Windows Server 2012R2 (64bit)

#zipファイル
<p><a href="https://github.com/yyoshizu/Branch-processing-by-OS-judgment-bit_bat/releases/download/batch/Branch.processing.by.OS.judgment.bit_bat.zip"download="https://github.com/yyoshizu/Branch-processing-by-OS-judgment-bit_bat/releases/download/batch/Branch.processing.by.OS.judgment.bit_bat.zip">zipファイルをダウンロード</a></p>

#確認コマンド
以下のコマンドでversionとbit数を取得できる。

```ruby:version確認コマンド
ver
```
```ruby:bit数確認コマンド
wmic os get osarchitecture
```
#出力イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475419/3205ffc6-ce91-722b-6026-20d4c09bc46e.png)

#実際にやってみる

今回は一番わかりやすいということで
各OS\bitのフォルダを作成して該当フォルダを開くまでをゴールとしてみました。

OSフォルダ階層 　　　　　　bit数階層 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475419/73c96b9e-c63a-f16c-1b80-6c6506b4b5f6.png)　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475419/4e488b4f-3b95-54e5-3619-4e4c44ad7abd.png)

bat実行後にDesktop\判定\Win10\64bitフォルダが開きました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475419/e3ed280b-594c-e0b8-fdf6-863243f8bd8f.png)

ここからは各OSでの実行bat等をcallしたり、実処理を書き込んだりすれば比較的楽に色々できそうですね。
今回は以上です。
sphinx:デフォルトのコードブロックの言語は`default`で`python3`に近いもの

# 実行環境
* Python 3.9.7
* sphinx 4.4.0

# はじめに
[sphinx](https://www.sphinx-doc.org/ja/master/)でHTMLドキュメントを生成しています。

以下のような設定ファイルを使って、HTMLドキュメントを生成してみます。

```python:conf.py
project = "foo-bar"
```

```plain:index.rst
==================================================
test
==================================================

.. code-block::

   $ foo-bar list


.. code-block::

   usage: foo-bar list [-h] [--debug] [-o OUTPUT]


.. code-block::

   def foo(a: int, b: int) -> int:
      return a + b
```


```
$ ls
conf.py  index.rst

$ sphinx-build -b html  . _build 

$ ls
_build  conf.py  index.rst
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37903/e9811ac5-f84f-9aa8-f038-f0153c712aa9.png)

HTMLドキュメントが生成されました。
2つ目のコードブロックでは、`list`と`-`がハイライトされています。2つ目のコードブロックはコマンドのヘルプなので、このハイライトは期待したものではありません。なぜハイライトされるのでしょうか？


# ハイライトされる原因
`code-block`ディレクティブの言語が指定されていなければ、`highlight`ディレクティブの言語、または`highlight_language`の設定が使われます。

>This directive takes a language name as an argument. It can be any lexer alias supported by Pygments. If it is not given, the setting of highlight directive will be used. If not set, highlight_language will be used.

https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block

そして`highlight_language`のデフォルト値は`default`で、これは`python3`に近いものです。

>The default language to highlight source code in. The default is 'default'. It is similar to 'python3'; it is mostly a superset of 'python' but it fallbacks to 'none' without warning if failed. 'python3' and other languages will emit warning if failed.

https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-highlight_language

したがって、2つ目のコードブロックはpythonとみなされて、`list`と`-`がハイライトされるようです。


# 解決策
`code-block`ディレクティブの言語を`text`または`none`にすれば、ハイライトされなくなります。[^1]



```plaintext:index.rst
.. code-block:: text

   usage: foo-bar list [-h] [--debug] [-o OUTPUT]
```

ドキュメントで利用するコードブロックの言語が、ほとんどpythonでないのであれば、`conf.py`の`highlight_language`を変えるのがよいでしょう。

```python:conf.py
project = "foo-bar"
highlight_language = "text"
```



[^1]: `text`と`none`は両方ともPygmentsのTextLexerを指しています。https://ja.stackoverflow.com/questions/85909
VSCodeでPythonを書く時、formatOnSaveを使いつつインポート並べ替えのみ無効にする

VSCodeでPythonを書く時、formatOnSaveを使いつつインポート並べ替えのみ無効にしたいことがあったので、設定方法をメモ。

## これをどういうケースで使うか

import文より前に式があるPythonコードを書いていたら、フォーマッタによりimport文が全部最上部にまとまってしまい動作しなくなったので、無効にしたいことがあった。

```py
# このコードが
sys.path += [script_dirpath]
from mylib.allobj_deselect import allObjDeselect
```

```py
# このようにされ、動かなくなった。
from mylib.allobj_deselect import allObjDeselect
sys.path += [script_dirpath]
```

## 環境

- MacBook Pro (16-inch 2019)
- macOS Monterey 12.0.1

## 解決策

設定のJSONを開き(command + ctrl + p -> 「基本設定: 設定(JSON)を開く」)、Python関係の設定を以下のようにする。

```jsonc
{
  "[python]": {
    "editor.defaultFormatter": "ms-python.python",
    "editor.formatOnSave": true
  },
  "python.formatting.autopep8Args": ["--ignore","E402"],
}

```

以上