OmniAICreator/Qiita-1.07M huggingface dataset:
pythonanywhereのScheduled tasksでdjangoのカスタムコマンドを実行すると、インストールしたはずのモジュールが無いというエラーが発生する。

# 結論
仮想環境内にあるpythonでカスタムコマンドを実行する必要があるようです。タイトルのようなエラーが発生している場合はサーバーの大元のpythonを実行している可能性があります。

# 実際に起きたエラー
djangoのカスタムコマンドを作成、それをpythonanywhereのScheduled tasks機能を使って定期実行をしようとしていました。
最初、Scheduled tasksのコマンドの部分に以下のように記述して実行をしようとするとエラーが発生しました。

```
python /home/(ユーザー名)/(仮想環境名)/manage.py (カスタムコマンド名)
```

```error.log
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 259, in fetch_command
    app_name = commands[subcommand]
KeyError: 'update_channel_record'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/kabuto64425/kabuto64425.pythonanywhere.com/manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 440, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 266, in fetch_command
    settings.INSTALLED_APPS
  File "/usr/local/lib/python3.10/site-packages/django/conf/__init__.py", line 87, in __getattr__
    self._setup(name)
  File "/usr/local/lib/python3.10/site-packages/django/conf/__init__.py", line 74, in _setup
    self._wrapped = Settings(settings_module)
  File "/usr/local/lib/python3.10/site-packages/django/conf/__init__.py", line 183, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/local/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/home/kabuto64425/kabuto64425.pythonanywhere.com/config/settings.py", line 14, in <module>
    from dotenv import load_dotenv
ModuleNotFoundError: No module named 'dotenv'

2023-06-06 11:05:12 -- Completed task, took 6.57 seconds, return code was 1.
```

logを見る限り、dotenvがインストールされていないということなのですが、それ自体はインストールできていたはずなので疑問に思い調査をしました。

# 調査
以下の記事が参考になりました。

https://qiita.com/daidai_cabosu/items/bcfdcee66c2967b6d3c4

どうやらScheduled tasksのコマンドで単に「python」と入力して実行すると大元のpythonを実行するようです。そのため、仮想環境内にインストールしたモジュールは持っていないため、エラーになるということだそうです。そこで仮想環境内のpythonを実行できるようにファイルパスまで記述する必要がありました。

# 調査を踏まえての対策
仮想環境内のpythonを実行できるようにするため以下のようにコマンドを変更します。
```
/home/(ユーザー名)/.virtualenvs/(仮想環境名)/bin/python /home/(ユーザー名)/(仮想環境名)/manage.py (カスタムコマンド名)
```

これでエラーが発生することなく定期実行できます。

以上です。
WordPressレンタルサーバーの評判

WordPressに最適なレンタルサーバーの評判について解説しています。

その中で評判の高いConoHa WINGとその他サーバー比較について以下２記事でレビューしています。
詳細はチェックしてみてください。

https://tecchanblogs.com/conohawing-merit/

https://tecchanblogs.com/compare-rentalserver/
ロードバランサーにも種類がある話

いつもお世話になっているロードバランサーについて、ゆるい日本語でまとめる。

# そもそもロードバランサーとは
ユーザーからアプリケーションサーバの間に立ち、負荷分散をするための装置や機構のこと。

サーバを複数用意して冗長化した場合に、よしなに処理を分担させて、システム全体の平和を保ってくれる存在。
```mermaid
%%{init:{'theme':'base','themeVariables':{'primaryColor':'#20b2aa','primaryTextColor':'white','primaryBorderColor':'#20b2aa','lineColor':'gray','textColor':'#6A7FABCC','fontSize':'20px'}}}%%

graph LR;

subgraph A["こうではなく"]
    
    ua1(("ユーザ達")) --"アクセス"--> va1(["ロードバランサ"])
    
    va1 --"100%を分担"--> sa1(["サーバ"])
    va1 --"0%を分担"--> sa2(["サーバ"])
    va1 --"0%を分担"--> sa3(["サーバ"])
    va1 --"0%を分担"--> sa4(["サーバ"])
    va1 --"0%を分担"--> sa5(["サーバ"])
end

subgraph B["こうじゃ"]
    
    ub1(("ユーザ達")) --"アクセス"--> vb1(["ロードバランサ"])
    
    vb1 --"20%を分担"--> sb1(["サーバ"])
    vb1 --"20%を分担"--> sb2(["サーバ"])
    vb1 --"20%を分担"--> sb3(["サーバ"])
    vb1 --"20%を分担"--> sb4(["サーバ"])
    vb1 --"20%を分担"--> sb5(["サーバ"])
end

sa3 --> ub1
linkStyle 12 stroke-width:0px;

classDef SS fill:white,stroke:white;
class A,B SS
```
上記の図は一例で、どのようによしなに分担させるかにも色々ある。

# ロードバランサーの種類
## ハードウェアロードバランサとソフトウェアロードバランサ
バランシング専用の機器を用意して、そいつで負荷分散をするのがハードウェアロードバランサ。
それ専用に用意されている機器なので、パフォーマンスはよいがとてもお金がかかる。

対して専用機ではないマシンでバランシング機能をソフトウェアで実現するのがソフトウェアロードバランサ。
アプリケーションサーバと同じような通常のサーバや仮想サーバで実現できる。


## L4ロードバランサとL7ロードバランサ
ソフトウェアロードバランサの種類。
[通信レイヤ](https://qiita.com/masaozi3/items/5f779b06715c34f74d89#osi%E5%8F%82%E7%85%A7%E3%83%A2%E3%83%87%E3%83%AB)のどの層に設置されているのかで変わる。
それぞれできることが違うので、併用する場合もある。

### L4ロードバランサ
通信レイヤの第4層（トランスポート層）で負荷分散をするロードバランサ。
セッション単位で負荷分散をする。

トランスポート層はリクエストの転送先に通信を届けるのが使命の層で、
どのようなリクエスト内容だとかまでは知らないため、セッション単位での振り分けしかできない。
その分やることが簡単なので、処理は早い。

### L7ロードバランサ
通信レイヤの第7層（アプリケーション層）で負荷分散をするロードバランサ。
リクエスト単位で負荷分散をする。

この層ではURIやUAなど詳細なリクエスト内容を取り扱うので、それらに基づいた細かい負荷分散ができる。
このURIの場合だけあちらのサーバに渡す、このUAならばこちらに…みたいなこともできる。
高性能な分利用料が高くなったり、設定が複雑になることがある。

# 関連話：ロードバランサの機能あれこれ
## Persistence 接続維持
同じリクエスト元からの処理は同じサーバーに流したいよ〜という話。

L4はそもそもセッション単位の負荷分散を行なうので、リクエスト元のIPで判断させれば容易に実現できる。
L7の場合はCookieを使うなどして、複数のリクエスト同士の繋がりを示すための工夫が必要。

## ヘルスチェック
バランシングする対象のサーバ達が元気に生きているのかを管理する。

定期的に生きてる（アクティブ）か確認するアクティブヘルスチェックと、
リクエスト失敗という死を検知して切り離すだけのパッシブヘルスチェックがある。
ABC304 F Shift Table~負数の剰余~

# はじめに
ABC304のFを公式解説を見ながら実装したがWAを取れなかった.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773193/7e83a712-de9c-e5b3-661d-71656bb9d39b.png)


# 理由
答えが負の数になる場合, ```%=```では負の数が返ってくるため```MOD=998244353```を足す必要があった.
公式解説では```modint```を使用しており内部で処理されていたと考えられる.

[Qiita：【C++】負の数を正の数で割ったときの余りを求める](https://qiita.com/happyisland44/items/8e4feb6805eecee29f83)
[C++リファレンス：整数に対する除算と剰余算の丸め結果を規定C++11](https://cpprefjp.github.io/lang/cpp11/result_of_integer_division_and_modulo.html)
[C/C++で負の数の剰余は負になる](https://wonderhorn.net/programming/negativeremainder.html)


# 修正と結果
出力部分
```C++
cout << ans << endl;
```
を以下に変更.
```C++
MOD = 998244353;
cout << (ans + MOD) % MOD << endl;
```

結果AC!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773193/c9589a55-01d2-91d7-3995-7b2c5575b083.png)
ABC 305 備忘録

## 概要
　今回は、ABC305（2023年6月10日21:00~22:40）の実装、ポイント、および自分の実装について述べていこうと思う。
## A問題
https://atcoder.jp/contests/abc305/tasks/abc305_a
### ポイント
- 高橋くんの位置を5で割った余りが3以上かどうかで場合分け
- 2以下ならば、スタート地点に近い方で3以上ならばゴール地点に近い方の給水所
### 自分の実装
```Python:ABC_305_A.py
N = int(input())

if N%5 <= 2:
    print(N - N%5)
else:
    print(N + 5 - N%5)
```
## B問題
https://atcoder.jp/contests/abc305/tasks/abc305_b
### ポイント
- 各アルファベットと座標が対応するように、ASCII文字コードによる変換を行う
### 自分の実装
```Python:ABC_305_B.py
coordinates = [0, 3, 4, 8, 9, 14, 23]

p, q = map(str, input().split())

p_coords = ord(p) - 65
q_coords = ord(q) - 65

print(abs(coordinates[p_coords] - coordinates[q_coords]))

```
## C問題
https://atcoder.jp/contests/abc305/tasks/abc305_c
### ポイント
- 食べられたクッキーがあるのは長方形の周および内部の範囲
- '.', '#' であることを全探索し、当該座標自体が'.'でありかつ、調べている座標の周囲4マスのうち２つ以上が'#'である座標が答え
### 自分の実装
```Python:ABC_305_C.py
H, W = map(int, input().split())

S = [['.' for i in range(W+2)]]
for i in range(H):
    S_line = ['.'] + list(input()) + ['.']
    S.append(S_line)
S.append(['.' for i in range(W+2)])
grid_x = [-1, 0, 1, 0]
grid_y = [0, -1, 0, 1]

for i in range(1, H+1):
    for j in range(1, W+1):
        count_cookies = 0
        for k in range(4):
            x = i + grid_x[k]
            y = j + grid_y[k]
            if S[x][y] == '#' and S[i][j] == '.':
                count_cookies += 1
            if count_cookies >= 2:
                print(i, j)
                exit()
```
## D問題
https://atcoder.jp/contests/abc305/tasks/abc305_d
### ポイント
- 各クエリの開始・終了時間が睡眠記録のどの記録の間に位置しているかを2分探索で調べる
- 記録間の睡眠時間をいちいち計算 or `sum` で計算するのではなく、累積和で各区間の時間を計算（起きている区間は0となるように注意）
- 累積和同士の差、および開始。終了時間による差分を引いた上で答えを出力
### 自分の実装
```Python:ABC_305_D.py
from bisect import bisect_left

N = int(input())

A = list(map(int, input().split()))

sleep = [0]*N

# 就寝・起床時間時点で何時間寝たかの累積和
for i in range(1, N):
    if i % 2 == 0:
        sleep[i] = sleep[i-1] + A[i] - A[i-1]
    else:
        sleep[i] = sleep[i-1]

Q = int(input())

# 各クエリの処理
for i in range(Q):
    l, r = map(int, input().split())
    r_index = bisect_left(A, r)
    l_index = bisect_left(A, l)
    minute = 0
    minus = 0
    A_r, A_l = A[r_index], A[l_index]
    if A_r != r:
        r_index -= 1
    if A_l != l:
        l_index -= 1
    if l_index %2 == 1:
        minus += l - A[l_index]
    if r_index %2 == 1:
        minus -= r - A[r_index]
    minute = sleep[r_index] - sleep[l_index] - minus
    print(minute)
```
## 感想
　今回はC問題までは10分程度で解けたのはよかった。一方で、D問題で2分探索を使うことまでは考えられたが、累積和で睡眠時間を求めること、および開始・終了時間が時間軸の中で睡眠中なのか起床しているのかを場合分けするのに手間取り、時間内に解くことができなかった。全て頭の中で考えていたので、メモするなりしてもっと考えをまとめながらコーディングするべきだった。
Data Guard環境におけるGoldenGate運用の考慮事項

# はじめに
Oracle Data Guard 環境下にて、Oracle GoldenGate を運用する際に、Extractプロセスの`TRANLOGOPTIONS HANDLEDLFAILOVER`パラメータの必要性と使用時の運用考慮事項を紹介します。

# 環境
本記事は下記環境にて動作確認を行っています。
* Oracle Database 19c Enterprise Edition 19.16.0.0.0
* Oracle GoldenGate 19.1 19.1.0.0.210720

# TRANLOGOPTIONS HANDLEDLFAILOVERとは
TRANLOGOPTIONS HANDLEDLFAILOVERは、Extractプロセスに設定可能なパラメータです。本パラメータを有効化した場合、Extractプロセスは、Data Guardのスタンバイデータベースに適用済みのREDOデータのみを抽出する動作になります。本パラメータの必要性について、例を挙げて紹介します。

## システム構成例
* GoldenGateのPrimary Extract(いわゆるCaptureプロセス)はData Guardのプライマリデータベースから、REDOデータを抽出し、ターゲットシステムに転送します。
* Replicatプロセスがターゲットデータベースにトランザクションデータを適用します。
* Data GuardのREDO適用により、スタンバイデータベースは更新されます。
![20230611_01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330820/43371c8e-62e1-1be1-e806-beefe0c4c517.png)

## TRANLOGOPTIONS HANDLEDLFAILOVERを使用しない場合
Extractプロセスは、スタンバイデータベースのREDO適用状態を考慮しないため、スタンバイデータベースに未適用のREDOデータを抽出する可能性があります。その場合、一時的にターゲットデータベースに適用されたソースデータベースのSCNが、スタンバイデータベースのSCNよりも大きい(新しい)状態になります。
![20230611_03.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330820/253820c9-8d87-a242-5452-6ac36ad85813.png)

上記状態において、プライマリデータベースに障害が発生し、データロストを伴うData Guardのフェイルオーバを実行した場合、下記図の状態となります。
![20230611_04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330820/add70219-53e3-367e-dbf1-9dea713115f1.png)
* スタンバイデータベースは、`SCN90`の状態で新プライマリに昇格します。
未適用のREDO(SCN91以降)データはロストします。
* ターゲットデータベースは、`SCN100`まで適用されているため、新プライマリデータベースとデータ不整合が発生した状態となります。
* データ不整合が発生しているため、GoldenGateのレプリケーションはエラーが発生します。

GoldenGateのレプリケーションを再開するためには、初期データ移行をやり直すなど復旧に時間を要します。

## TRANLOGOPTIONS HANDLEDLFAILOVERを使用した場合
Extractプロセスによる抽出処理は、スタンバイデータベースに適用されたREDOデータのみを抽出するため、スタンバイデータベースのSCN(データベース断面)は、ターゲットデータベースよりも新しい状態である事が保証されます。先ほどの例と同様にデータロストを伴うフェイルオーバ後の状態を下記に示します。

* ソースシステムフェイルオーバ後
![20230611_05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330820/981d913b-f4ca-f266-5289-352b4af3c8e0.png)
* スタンバイデータベースは、`SCN100`の状態で新プライマリに昇格します。
未適用のREDO(SCN101以降)データはロストします。
* ターゲットデータベースは、`SCN90`まで適用されているため、新プライマリデータベースのSCN91以降のトランザクションから、GoldenGateのレプリケーションを再開できます。

# TRANLOGOPTIONS HANDLEDLFAILOVERの考慮事項
## Extract遅延事象
Data Guardの保護モードが、`最大パフォーマンスモード`の場合、Extractプロセスの抽出タイミングが、`60秒に1回程度`になる動作を筆者環境にて確認しました。

## 回避方法1
Extract処理が60秒に1回となる動作が許容できない場合は、データベース初期化パラメータの `_redo_transport_stream_writes` を `false` に設定する事で上記の待機動作を回避できますが、隠しパラメータのため、使用する際はSRにて、ご確認ください。

## 回避方法2
Data Guardの保護モードを`最大可用性モード`にする事で、上記待機事象は回避可能です。REDO転送モードは、Fast Sync(SYNC NOAFFIRM)、あるいは SYNC AFFIRM どちらでも大丈夫です。ただし、最大可用性モードに設定する事でプライマリデータベース側のトランザクション性能が低下する可能性がある点をご注意ください。

# 参考資料
[Oracle Data GuardとOracle GoldenGateによる透過的なロール移行](https://www.oracle.com/technetwork/jp/database/availability/ogg-adg-2422372-ja.pdf)
Qiita 記事の記述方法についてまとめ

# 概要
Qiitaを使うのが初めてで
記事の記法等が分からなかったので基礎的な記述方法をまとめます

# 目次
[・見出しの書き方](#見出しの書き方)
[・コードの載せ方](#コードの載せ方)
[・ページ内リンク](#ページ内リンク)
[・他記事のリンク](#他記事のリンク)

# 見出しの書き方
↑のような見出しを書くには下記のように記述します。

`` # 見出しの書き方 ``

# コードの載せ方
コードを本文に載せるには下記のように
バッククオート３つで載せたいコードを囲って記述します。


`` ``` ``
``let a = "コードの載せ方"; ``
`` ``` ``

・表示されるコード

````
let a = "コードの載せ方";
````

# ページ内リンク
下記の、目次へ遷移 をクリックすると
ページ内で遷移が行われますが、
下記のように記述すると実装できます。
``
[目次へ遷移](#目次)
``
※[ ]内の文言は任意で、()内の文言はリンク先の見出しを記述します


・ページ内リンク
[目次へ遷移](#目次)


# 他記事のリンク
リンク部分に他記事のリンクを記述します。
``
[他記事へ遷移](https://qiita.com/okanoQiita/items/e644f3e5be50efb0ed7e)
``
※[ ]内の文言は任意で、()内の文言はリンク先のURLを記述します

・他記事へのリンク
[他記事へ遷移](https://qiita.com/okanoQiita/items/e644f3e5be50efb0ed7e)
Laravelのスクレイピング神Goutteがdeprecatedになってた

久しぶりにスクレイピングが必要になって、「PHPでスクレイピングといえば」なGoutteを使おうとしたらDeprecatedになっていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31281/877c03f0-c900-70db-3697-a579419c190f.png)

今年、2023年4月1日にアーカイブ化されていたみたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31281/ff66ae53-e91d-b4f9-bf1c-eb6136ba2f47.png)

## 対応方法

知りたい方のために、先に対応方法だけ。READMEに書いてある通りです。

> WARNING: This library is deprecated. As of v4, Goutte became a simple proxy to the HttpBrowser class from the Symfony BrowserKit component. To migrate, replace Goutte\Client by Symfony\Component\BrowserKit\HttpBrowser in your code.

Google訳「v4 の時点で、Goutte は Symfony BrowserKit コンポーネントから HttpBrowser クラスへの単純なプロキシになりました。移行するには、コード内の Goutte\Client を Symfony\Component\BrowserKit\HttpBrowser に置き換えます。」

プロジェクト内で `Goutte\Client` というキーワードを `Symfony\Component\BrowserKit\HttpBrowser` に置換するだけでOKです。

### 新規プロジェクトの場合

上記は既存プロジェクトでGoutteを既に使っている場合なので、新規で使う場合はcomposerで必要なパッケージをインストールします。自分の場合は symfony/http-client, symfony/browser-kit の2つでいけました。

```bash
composer require symfony/http-client
composer require symfony/browser-kit
```

Goutteのcomposer.jsonが以下のrequireなので、足りないものがあれば追加でrequireしてください。

```composer.json
{
    "require": {
        "php": ">=7.1.3",
        "symfony/deprecation-contracts": "^2.1|^3",
        "symfony/browser-kit": "^4.4|^5.0|^6.0",
        "symfony/css-selector": "^4.4|^5.0|^6.0",
        "symfony/dom-crawler": "^4.4|^5.0|^6.0",
        "symfony/http-client": "^4.4|^5.0|^6.0",
        "symfony/mime": "^4.4|^5.0|^6.0"
    },
    "require-dev": {
        "symfony/phpunit-bridge": "^6.0"
    },
}
```

## メモ

### deprecated

https://github.com/FriendsOfPHP/Goutte/blob/master/Goutte/Client.php

Goutte/Client.phpを見ると、確かにtrigger_deprecationして、HttpBrowserのコンストラクタを呼んでいるだけ‥！

```Goutte/Client.php
class Client extends HttpBrowser
{
    public function __construct(HttpClientInterface $client = null, History $history = null, CookieJar $cookieJar = null)
    {
        trigger_deprecation('fabpot/goutte', '4.0', 'The "%s" class is deprecated, use "%s" instead.', __CLASS__, HttpBrowser::class);

        parent::__construct($client, $history, $cookieJar);
    }
}
```

### HttpClientへの切り替え

https://github.com/FriendsOfPHP/Goutte/commit/122aa37668ce7e9162cd0a616e8ba34e36698b2d

そもそも2019年12月にHttpClientへの切り替えが行われています。まったく知らずに使っていました。

## 感謝

PHPでスクレイピングするにあたって、Goutteには非常にお世話になりました。
感謝。
spdx-toolsでSPDX形式のJSONファイルを表示する

# はじめに

spdx-toolsを使うことでSPDX形式のJSONファイルを解析して表示することができます。
spdx-toolsの使い方に関する記事がQiitaになさそうだったので、本記事を執筆することに決めました。

# 環境情報

| コンポーネント | バージョン | 備考 |
|:-:|:-:|:-:|
| PC | M1 MacBook Pro  |   |
| OS | macOS Ventura 13.4  |   |
| Docker | 4.20.0 |   |
| Rocky Linux | 9.2  | |
| syft | v0.82.0 | |
| spdx-tools | 0.7.1 | python 3.7以降が必要 |

# SPDX形式のJSONファイルの準備

SPDX形式のJSONファイルの準備をします。
下記の記事に従って、Rocky Linux 9のDockerコンテナを作成し、syftを使ってRocky Linux 9のSPDX形式のJSONファイルを生成します。
[NTIA Conformance CheckerでSPDX形式のJSONファイルがNTIAのSBOMの最小要素を満たすか調べる](https://qiita.com/ykmchd/items/33d3267f1414e0baa6d9)
※Rocky Linux 9のDockerコンテナ環境はそのまま使うので残しておいてください
※今回はNTIA Conformance Checkerは使わないのでインストール不要です

# spdx-toolsのインストール

pipをインストールして、最新版に更新しておきます。
```shell
# dnf install python3-pip
# python3 -m pip install -U pip
```

spdx-toolsモジュールをインストールします。
```shell
# python3 -m pip install spdx-tools
```

バージョンを確認します。
```shell
# python3 -m pip freeze | grep spdx-tools
spdx-tools==0.7.1
```

# SPDX形式のJSONファイルを表示する

SPDX形式のJSONファイルの内容を表示してみます。
```
# pyspdxtools_parser --file rockylinux9_rpm.json 
(snip)
Package Name: openssl
Package Version: 1:3.0.7-6.el9_2
Package Download Location: NOASSERTION
Package Homepage: None
Package Attribution Text: None
Package verification code: None
Package excluded from verif: 
Package license concluded: NOASSERTION
Package license declared: LicenseRef-ASL-2.0
Package licenses from files:
Package Copyright text: NOASSERTION
Package summary: None
Package description: None
Package external references:
        Category: SECURITY
        Type: cpe23Type
        Locator: cpe:2.3:a:rockyenterprisesoftwarefoundation:openssl:1\:3.0.7-6.el9_2:*:*:*:*:*:*:*
        Category: SECURITY
        Type: cpe23Type
        Locator: cpe:2.3:a:openssl:openssl:1\:3.0.7-6.el9_2:*:*:*:*:*:*:*
        Category: PACKAGE-MANAGER
        Type: purl
        Locator: pkg:rpm/openssl@3.0.7-6.el9_2?arch=aarch64&epoch=1&upstream=openssl-3.0.7-6.el9_2.src.rpm
(snip)
```

spdx-toolsの機能ではないですが、SPDX形式のJSONファイルからパッケージ名を抽出することもできます。

```shell
# pyspdxtools_parser --file rockylinux9_rpm.json | grep "Package Name" | sed -e 's/Package Name: //g'
alternatives
audit-libs
basesystem
bash
binutils
binutils-gold
bzip2-libs
ca-certificates
coreutils-single
cracklib
(snip)
```

# 最後に

spdx-toolsを使うことで、SPDX形式のJSONファイルに対し簡単な操作であれば行うことができます。
今回は紹介しませんでしたが、[ライブラリ](https://github.com/spdx/tools-python#library-usage)として使えば、値を取り出したり、検証したり、ファイル出力することもできます。

# 参考情報

* spdx-tools
    * https://pypi.org/project/spdx-tools/
* tools-python
    * https://github.com/spdx/tools-python
* NTIA Conformance CheckerでSPDX形式のJSONファイルがNTIAのSBOMの最小要素を満たすか調べる
    * https://qiita.com/ykmchd/items/33d3267f1414e0baa6d9
Android スレッド内でUIの表示を変更する

```kotlin
package com.a.thread

import android.os.Bundle
import android.os.Handler
import android.util.Log
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import java.util.concurrent.atomic.AtomicInteger

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val handler = Handler(mainLooper)

        val myRunnable = object : Runnable {
            var count: AtomicInteger = AtomicInteger(0)

            override fun run() {
                handler.postDelayed(this, 1000)

                count.incrementAndGet()

                Log.d("count", "" + count)

                val textView = findViewById<TextView>(R.id.text_view)
                textView.text = count.toString()
            }
        }

        val startBtn = findViewById<Button>(R.id.button_start)
        val interruptBtn = findViewById<Button>(R.id.button_interrupt)

        startBtn.setOnClickListener {
            handler.post(myRunnable)
        }

        interruptBtn.setOnClickListener {
            handler.removeCallbacks(myRunnable)
        }
    }
}
```

https://www.vector.co.jp/soft/screen/win95/game/se394828.html
iPadでSSHしたい

iPadで動くターミナルエミュレータを3個試してみました。
一つ言えるのは、**物理キーボードがあった方が絶対にいい**です。

# WebSSH
[WebSSH](https://apps.apple.com/jp/app/webssh-sysadmin-tools/id497714887)はSSHクライアントに特化している印象です。
![IMG_0021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868844/849f0ae7-79b7-c685-f12b-c889b3ea13a7.png)

↓こんな感じで接続先の情報を保存できます。
![IMG_0022.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868844/c3ba9139-5fae-f0df-9914-8c19791a9449.png)
![IMG_0023.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868844/2f8bfd25-04e4-bc22-8c59-ae76fa00d265.png)

↓公開鍵認証もサポートされてました。便利！
![IMG_0024.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868844/f0a4bbbb-266d-b90d-4079-8b43d4dc8d51.png)

↓接続してみるとこんな感じです。
![IMG_0025.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868844/f32f4bd0-b109-0c90-a82a-56b3b305b68b.png)
↓縦画面＋キーボード出してみました。
![IMG_0026.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868844/aef62888-7a2d-9899-c2d5-1f1965d70eca.png)

複数の接続先を保存しようと思ったら、¥1,000でProへアップデートする必要があります。
**買い切り**なので、購入もいいと思います。

# a-Shell
[a-Shell](https://apps.apple.com/jp/app/a-shell/id1473805438)、[a-Shell mini](https://apps.apple.com/jp/app/a-shell-mini/id1543537943)は、iPadの環境で動くターミナルエミュレータのようです。
↓SSHしてみた画面はこんな感じです。
![IMG_0027.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868844/5651d4c5-ef70-25ca-e723-0258729f375c.png)
↓縦画面＋キーボード出してみました。
![IMG_0028.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868844/316e0770-3044-cc46-6fc9-9dd385d115c6.png)

Apple Storeのレビューによると、PythonやVimがネイティブで動くみたいです。
SSHだけでなく、ローカルでも自由に遊べるのはいいですな。

肝心のSSHは、PCのターミナルエミュレータと変わらない使用感ですが、設定ファイルなどの保存先は少し特殊です。
SSHのconfigについては、`$SSH_HOME/.ssh/config`で設定できます。

ただ、アプリのサイズが大きくてa-Shell miniでもインストールの時間は結構かかります。

# Termius
[Termius](https://apps.apple.com/jp/app/termius-terminal-ssh-client/id549039908)は、多機能なSSHクライアントアプリという印象です。
↓こんな画面です。
![IMG_0029.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868844/dac9a800-6732-9ab2-0b7e-101d095852fa.jpeg)

↓接続先の設定はこんな感じです。
![IMG_0030.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868844/088aad47-1137-ead7-2ec6-d634766ac16e.jpeg)
![IMG_0031.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868844/63766823-5bf8-7599-8c34-b2c85e2079bc.jpeg)

↓SSH接続画面です。
![IMG_0032.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868844/a4b5f327-0ace-2fd8-9d86-5d2f507343e6.png)
コマンドの補完機能あるの結構便利です。(Termiusすげぇな)

↓複数タブで複数の接続先指定できるよいです。
![IMG_0033.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868844/8d487391-f4eb-3fc3-bc91-dc8404f10990.png)

↓縦画面＋キーボード出してみました。
![IMG_0034.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1868844/9f14374f-68b8-fc93-041c-f271d96594a5.png)

これだけの高機能を無料で使わせてもらえるのありがたいです。

# まとめ
Termius強えぇ！
【abc305 D】1時間かけてもWAが解消できないレベルの酷いプログラムを捨てて、書き直したら５分でACした話

# はじめに

時間におわれて、切羽詰まった状態で回答している、AtCoder初心者です。
ABC305のD問題が、時間内に解けませんでした。

人のプログラムを見たときに、その人の頭の中がどれくらい整理されているかわかる。と常々おもっていました。
私の書いたABC305のDが、それを証明するかのような、混沌としたもので、WAを解消をあきらめるレベルでした。
頭の中を整理して、書き直してみたら、すんなりACとり頭の中を整理する事の大切さを再確認しました。

# 頭の中が整理できてないバージョン

こんな、イメージの処理方法をプログラムにしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/a5787d3f-c407-e242-1968-bb5550903760.png)


```Python
def solve(N,A,Q,lr):
    ss = []
    s = 0
    for i in range((N-1)//2):
        s = s + A[i*2+2] - A[i*2+1]
        ss.append(s)

    for [l,r] in lr:
        x = bisect(A,l)
        if x % 2 == 0:
            # 睡眠中
            offset = A[x] -l
            s = x //2
        else:
            offset = 0
            s = x //2
        y = bisect(A,r)
        if y % 2 == 0:
            # 睡眠中
            offset += r - A[y-1]
            e = (y-1) //2
        else:
            e = y //2
        ans = offset
        if s == 0:
            ans += ss[e-1]
        else:
            ans += ss[e-1] - ss[s-1]
            
        print(ans)
```
図に書いたような方法でもできると思いますが、次のような疑問点があります。

疑問点
- s,eの値の算出が、例題のテストケースではOKだが完全かわからない。
- r,lの値が、A[i]の値と一致した場合の扱いが正しいかわからない。
- 条件によって、`e = (y-1) //2` と`e = y //2`の場合分けがあるけどこれ何？
- bisectかbisect_leftどっちにするのか正しいかわかってない。

# 改良版

改良点
- 時刻0から時刻tまでの睡眠時間を求めるf(t)を作り、f(r)-f(l)を求める方法にする
- bの導入（b[i]は、iまでの睡眠時間の合計値）
- Aからbを算出する処理は明確。
- b[i]は、A[i]同じ長さNの配列。
- b[i]は、bisect()で調べた値をそのまま使える（2で割るとか境界をきにしなくてよい）
- r=l=0の場合の扱いを注意する

図にするとこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/247a974d-c112-7a15-db38-d8cb6489d3ce.png)

```Python
def solve(N,A,Q,lr):

    def f(t):
        x = bisect_left(A,t)
        if x == 0:
            return 0
        if x % 2 == 0:
            # 睡眠中
            return b[x-1] + t - A[x-1]
        else:
            return b[x]
    
    b = [0] * N
    for i in range(1,N):
        if i % 2 == 1:
            b[i] = b[i-1]
        else:
            b[i] = b[i-1] +(A[i]-A[i-1])

    for [l,r] in lr:
        print(f(r)-f(l))
```

# まとめ

- 算出方法を思いついてもすぐにコーディングしない。実装しやすい工夫をする。
- if文が多かったり、不明な+1や-1が各所にでてくる場合は、方針を考え直す。
- bisect_leftとbisect_rightの違いは理解しておくこと。
pythonで読み込まれるモジュールのパスを変えたい

Anacondaでモジュールがインストールされる場所とpythonのインタープリンタでモジュールが読み込まれる場所が違って困ったのでメモしておく。

解決策はpythonのインタープリンタで読み込むモジュールのパスを変更すること。
いくつか3つほど方法があるみたい。
1. 環境変数`PYTHONPATH`を設定する。
   この方法だとほかの仮想環境にも影響してしまう？
   しかも多分もっとも優先順位が高いパスになってしまう？
1. .pthファイルを作る。
   この方法だとほかの仮想環境にも影響してしまう？
1. `sys`モジュールの`sys.path.append()`を用いる。
   この方法だとインタープリンタを立ち上げる度にしてしなければいけない？

pythonやRのバージョン依存性はなかなか厄介だ...

参考：
- [nkmkさんのページ](https://note.nkmk.me/python-import-module-search-path/)
区切り文字を含むフィールドの値を縦持ちする(SPSS Modeler データ加工逆引き7-16)

# 区切り文字を含むフィールドの値を縦持ちする

![スクリーンショット 2023-06-11 13.44.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/04565f71-3429-2374-e673-8e37c7ffb6f1.png)

全く逆のプロセスを逆引き7-19で紹介しています。

## 1.想定される利用目的

・色やサイズで枝番を特殊なマスタの処理
・タグのような複数メンバーを持つフィールドのトランザクションへの復元

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/raw/main/delimiter.str

## 3.サンプルストリームの説明

![スクリーンショット 2023-06-11 13.44.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/0edfa48b-47ee-26ac-52f7-e54ff49b2aae.png)

a.入力するデータは以下の通りです。　区切り文字「｜」で複数のアイテムが一つのフィールドに記録されています。

![スクリーンショット 2023-06-11 13.45.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/77eb4770-7c1f-73d4-d83d-80c6a8bff3cf.png)

b.[フィールド作成]ノードを編集します。　区切り文字の数をカウントします。ここでは二つのフィールドが対象ですのでmax(A,B)で最大値を採用します。
![スクリーンショット 2023-06-11 13.46.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/30699c30-a9e0-0dd8-7e67-fda5198c7a2c.png)

[プレビュー]を実行します。
![スクリーンショット 2023-06-11 13.46.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/2e187c7c-7967-9712-3c5c-c9970c3616aa.png)

c.もう一つの入力はシンプルなインデックスです。縦持ち変換に差し込む空のレコードです。
![スクリーンショット 2023-06-11 13.47.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/0b11dd01-5464-5ec6-3407-854116fccc87.png)

d.[レコード結合]ノードを編集します。区切り文字が1でメンバーがふたつ、２レコードが必要になるためcからそれを要求します。
![スクリーンショット 2023-06-11 13.48.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/9ff77627-5fc4-cd12-d104-cc0ff0e6d7ce.png)

[プレビュー]を実行します。レコード数が整いました。
![スクリーンショット 2023-06-11 13.48.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/a12b1fe9-9936-a2a0-2093-1af35013cdb7.png)

e.[置換]ノードを編集します。indexを区切り文字の位置指定に利用します。
![スクリーンショット 2023-06-11 13.49.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/b5fc78bb-4a5f-7394-8521-1ae1fc7f0d97.png)

[テーブル]を実行します。
![スクリーンショット 2023-06-11 13.50.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/824303b1-d036-3584-5d2e-59b50d811c46.png)

#### 注意事項

今回のテーブルでは２つのフィールドの区切り文字数は同じですが、異なる場合には考慮が必要です。また最大アイテム数を5として設計していますが、想定されるよりも大きなマスタ(c)が必要です。

## 4.参考情報

#### 横持ちを縦持ち/トランザクション形式へ復元する

https://qiita.com/416nishimaki/items/a05765431cc477a6846d

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
StableDiffusionのimage-to-imageの効き具合を検証

## 画像を元に画像を変更する
StableDiffusionには言語から画像を生成するほかに、元画像に対して言葉をいれて、元画像を変更するモードがある。軽く触ったところ、どれくらいプロンプトを優先させるかのstrengthパラメータを調節していかないと狙った画像にならなさそうなので、image-to-imageのstrengthパラメータを変えて確認したい

## 検証
元画像に0.1~1.0までパラメータを変更して変換する
|  strength  |  画像  |
| ---- | ---- |
|  元画像  |![sweets_french_cruller_chocolate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473989/4e0e0c05-2440-71be-99f6-c32cb649c6d8.png)|
|  0.1  |  ![img_to_img_picaso_999.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473989/22a5eb21-0b0f-a31f-bca5-2423a1bf01d7.png)|
|  0.3  |![img_to_img_picaso_0.3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473989/53a50c4c-c55a-9e0d-0320-a9c790d90b77.png)|
|  0.5  |![img_to_img_picaso_0.5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473989/1c6a174c-578a-c2dc-96e1-cf2fc90361d6.png)|
|  0.7  |![img_to_img_picaso_0.7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473989/7ee8a5b6-7510-767d-a58f-af9adbf0a185.png)|
|  1.0  |  ![img_to_img_picaso_111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3473989/c8ee9c76-3f75-1cdc-2fcf-37ae30d614cf.png)|

## おわりに
0.5くらいから明確に変わり、1.0だとほぼ別物に見える結果になった。好みとしては0.5くらいだが、これは使用したいシチュエーションによるだろうなと思う。今回は単純な画像だったので0.5くらいかなと感じたが元画像によっては高くも低くもなることが予想できる。
また、生成ごとに結構印象の違う画像がでるので人間の目で見て良いという判断が最後には必要になるところに人間の入る隙間があるように感じた
Spring Boot 有償サポートについての調査結果

# はじめに

Spring Boot 2.7.5のOSSサポートの終了が2023年11月18日に迫る中、VMware社が提供する有償サポートとはどんなものなのかを調査してみた結果のお話ですが、期待はしないでください。決定的に有用な情報は得られていません。私個人の備忘録のようなもの。

# 有償サポート提供ベンダー

[VMware Tanzu - VMware Spring Runtime](https://tanzu.vmware.com/jp/spring-runtime)

[Microsoft - Azure Spring Apps](https://azure.microsoft.com/ja-jp/products/spring-apps/)

# VMware Spring Runtime

[Spring Boot日本語サイトのサポート期間](https://spring.pleiades.io/projects/spring-boot#support)の[有償サポートについて (*)]の但し書きみたいなところからVMware社が提供する有償サポートの日本語紹介ページへジャンプできます。

VMware社のTanzu製品・サービスは正直認識がありませんでした。Kubernetesはdockerの管理ツールといった程度。

https://frontier.networld.co.jp/knowhow-vmwaretanzu/tanzu-intro3-overview/

上記サイトからの引用
>Tanzuは、VMwareが提供するKubernetes関連製品群の総称で、Kubernetesに対応したソフトウエアの開発を支援するための一連のソフトウエアやサービスなどを含んでいます。

VMware Spring Runtimeサイトのよくある質問（FAQ)からの引用
>他のTanzu製品やサブスクリプションを購入せずに、VMware Spring Runtimeだけを購入することはできますか？
はい。VMware Spring Runtimeはあらゆる企業でご利用いただけます。

Spring Boot 有償サポートだけを別契約できそうということがわかっただけです。

下記はBingのCoPilotに問い合わせしてみた結果です。（「Spring Boot 有償サポート 価格例」 ）
>Spring Boot の提供元は、VMware です。VMware は Spring Boot および Spring Framework に対してサポートを提供しています。Spring Boot には、無料のコミュニティサポートと有償のプレミアムサポートがあります。有償サポートの価格は公式サイトに掲載されていませんが、お問い合わせフォームから問い合わせることができます。

価格を知るには問い合わせフォームからお問い合わせする必要がありそうです。

# Microsoft Azure Spring Apps

こちらはMicrosoft Azure上で利用することが前提そうです。（VMware Tanzu をAzureに乗っけたイメージ？）Azureの価格シミュレータで、想定スペック上の月額利用費などは見積もりできそう。「Microsoft と VMware のフル マネージド サービス」とありますので、実際のサポート提供主体はVMwareのようです。

https://azure.microsoft.com/ja-jp/pricing/calculator/?service=spring-apps


参考値ですが、下記の条件の仮想マシンスペックで下記のような結果がでました。
Azure Spring Apps
リージョン 東日本
Standard レベル、6 vCPU、12 GB メモリ、730 時間
複製削除
前払い: $0.00
月払い: $613.78

これに加えて、（上記のサポートオプションは[無償]）

サポート 標準
$100.00

サポートオプションが無償の場合はどのようなサポートなのかはちょっと調べきれませんでした。
標準サポートのご説明
>Standard サポートは、Azure の利用がビジネス上最低限必要な小規模または中規模の企業を対象としています。

# おわりに

あくまで参考情報です。有益な情報をご存じの方はコメント欄にてご教授いただければ幸いです。
プログラミング入門コース　2週目


<h2>1週間の振り返り</h2>

先週に比べて毎日とはいかないが少しの時間を確保しきりのいいところまで事前勉強の時間に充てることができた。ただ、やっぱりその日の体調などもあって毎日の習慣化にすることはまだ時間がかかりそうだなーと感じた。先週よりも少し難易度が上がっているため少し余裕をもって勉強に取り組めたと思う。

<h2>1週間で学んだこと</h2>
2週目は、以下の言語の基礎分法の説明および簡単な練習を行いました。
元々javascriptは現在働いている会社の研修で基礎は学んでいたのでそこまで躓くこともなく
こういうのあったなーと感覚で復習をしている感じでした。
ただ、研修で学んだ時はjqueryの具体的な使用方法とかあんまりイメージがつかなかったですが
今回の学習でどのようにjqueryを使用しよりシンプルにコードを記載してくのかが分かりました。

<h5>【学んだ言語】</h5>

- java script
- jquery
- Fetch

以下はそれぞれの言語で覚えておきたいコードを記載していく。

- java script

Webページの開発者ツールを使用しコンソールで確認したいときに使用

```prac.html
console.log('Hello World!')

```

リスト型で変数を作成するとき
```prac.html
let a = ['りんご', 'なし', 'かき', 'みかん']

```
ディクショナリー型で変数を作成するとき

```prac.html
let b = {"name" : "太郎","age" : 30}
```

繰り返し各要素を取り出したいとき
```prac.html
let fruits = ['りんご','なし','かき','みかん']
fruits.forEach((a) => {
	console.log(a)
})
```

条件分岐を使用したいとき
```prac.html
let age = 24

if (age > 20) {
	console.log('成人です')
} else {
	console.log('未成年です')
}
```

<b>条件分岐でよく使用する理論演算子一覧</b>

| 意味| 記号 |
|:-----------|:------------:|
| より大きい| >  |
|より大きいか等しい| >= |
|より小さい| < |
|より小さいか等しい| <= |
|等しい| == |
|等しくない| != |
|AND| && |
|OR| ｜｜ |
|NOT| ! |

<font color="Red">※ORの記号表示上の都合で全角になっていますが、実際は半角で使用します。</font>

- jquery
　あらかじめ作成されているjavascriptのコードのことを指す。
　javascriptのコードだけだと複雑になるためより直観的にコードを記載できるが、
　使用する際にはインポートを行う必要があるので注意。

インポート方法は、`<head>と</head>`の間に以下の通り挿入すれば使用可能

```prac.html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
```

`.append()`を使用すると各要素から1つずつ取り出した文字に変更しHTML上に表示させることが可能
すでにコードとして記載されている文字を初期化する際には`.empty()`を使用する
```prac.html
function checkResult() {
	let fruits = ['りんご','なし','かき','みかん','すいか']
	$('#q1').empty()
	fruits.forEach((a)=>{
		let temp_html = `<p>${a}</p>`
		$('#q1').append(temp_html)
	})
}
```

- Fetch

javascriptで使用できる関数の1つで外部からデータを取得するときに使用する。

　・`Fetch("")`:ダブルクォーテーションの間に取得したいデータのURLを
　　　　　　　　記載することで指定したページに通信リクエストを送信できる
　
　・`res ⇒ res.json() `:通信リクエストで受け取ったデータを
　　　　　　　　　　　　　「res」という名前を付けJSON形式にする


基本形の形
```prac2.html
fetch("ここにURLを入力").then(res => res.json()).then(data => {
		console.log(data)
})
```

- 注意点
　通信リクエストのURLがhttpの場合、GitHub側で配布した際にセキュリティの関係で正常に表示できないケースがある。その場合は、以下のコードを`<head>`内に入れることで解決できる。

```prac2.html
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />
```

<h2>後半で作成するWebサイトのアイデア出し</h2>
作りたいWebサイトは特に思いつかないが、特定のページで変更をかけて保存したデータを
反映できるような在庫管理サイトとか作成したら面白そうかなーと思っています。
管理画面とかで平均どの程度の在庫をもっていたらいいのかみたいなデータとかも表示出来たら便利そう。

<h2>今週の課題提出</h2>

[今週の課題](https://github.com/Yukisuprta/mypage/blob/main/index.html)

<h2>来週の目標</h2>
引き続き毎日少しの時間でもいいから勉強に取り組むことができるように頑張っていこうと思う。今週も復習に充てる時間がなかったので、来週は復習もできるように調整を頑張っていきたいです。
Edgeのプロファイルの自動切換え（Automatic profile switching）がグレーアウトしてオフにできない件

画像のようにグレーアウトしていて切り替えられない。おそらく自動サインインを有効にしないと操作できない。しかし自動サインインを有効にした途端、Officeのログイン情報でサインインされて全部紐づけられるのでしたくない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656367/921c2511-f879-2fe6-f549-f003b77588f9.png)

## Group policyまたはレジストリで無効にする

グループポリシーではGuidedSwitchEnabled（ガイド付きスイッチが有効）に相当する。
https://learn.microsoft.com/ja-jp/deployedge/microsoft-edge-policies#guidedswitchenabled

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656367/bbd0e448-1c0b-7fd5-d0c9-8716cba94f6a.png)

無効に構成すればオフになるはず。レジストリでは以下。

コンピューター\HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge
GuidedSwitchEnabledを0に設定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656367/2e5c791b-742f-3c8f-3498-2e1711f3e71c.png)

プロファイルの自動切換えをグレーアウトのままオフにできた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656367/e0f0a959-8da3-e85b-65a7-cb883a9d78af.png)

以上
TerraformでEC2を作成する時キーペアってどうするの？

TerraformでEC2インスタンスを作成する際のSSH鍵の取り扱い方法についてまとめていきます。

# 自己紹介
- 都内のDevOps系の企業でエンジニアをやっています。
- 主にAWSとTerraformを扱っております。
- フルリモートで勤務しております。
- 大阪在住、年齢は27歳、趣味は古着屋巡りと映画鑑賞です。

# 本記事の内容
- 手順１
    - マネジメントコンソール上でキーペアを作成し、それを使用する方法
- 手順２
    - ローカルで公開鍵と秘密鍵を生成し、それを使用する方法


# VPC

VPCの設定は以下を使用していきます。

![スクリーンショット 2023-06-07 22.54.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626370/14030144-bf71-f0b9-f1d3-b651cef87738.png)



# キーペアの作成[手順1]

マネジメントコンソールから[EC2]>[キーペア]>[キーペアを生成する]を押下してキーペア作成ページに遷移します。

![スクリーンショット 2023-06-07 22.50.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626370/71479b66-042b-9123-92bc-c8e922b4a99a.png)

[キーペアを生成]を押すと自動的にローカルへの保存画面が表示されるので適切な場所に保存します。
※ `~/.ssh`ディレクトリに保存するのが一般的です。

# EC2インスタンスの作成

```
main.tf

# --------------------------------
# EC2の作成
# --------------------------------
resource "aws_instance" "ssh-key-test-ec2" {
  ami                         = "ami-03dceaabddff8067e" #amazon linux2
  instance_type               = "t2.micro"
  subnet_id                   = aws_subnet.public-subnet-01.id
  vpc_security_group_ids      = [aws_security_group.vpc-01-ec2-sg.id]
  associate_public_ip_address = true
  key_name                    = "terraform_keypair"
  tags = {
    "Name" = "ssh-key-test-ec2"
  }
}
```

`terraform apply`します。

接続確認してみます。

![スクリーンショット 2023-06-11 11.34.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626370/7ec985d8-d38a-148f-58f6-d0a5e76329d7.png)

成功しました。

こちらは簡単でしたね。

流れとしては
- マネジメントコンソールでキーペアを作成
- ローカルに秘密鍵を保存
- そのキーでアクセス
でした。


# SSH鍵の生成[手順２]
https://kenzo0107.github.io/2017/03/26/2017-03-27-create-keypair-by-terraform/

上記の記事を参考に実際にやっていきます。

ターミナルでコマンドでSSH鍵を作成

![スクリーンショット 2023-06-11 11.47.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626370/f54fd324-875f-1b94-0dcb-4c17774438a7.png)

公開鍵と秘密鍵が生成されたことが確認できました。

```
main.tf

# --------------------------------
# キーペアの作成
# --------------------------------
resource "aws_key_pair" "keypair" {
  key_name   = var.key_name # キー名
  public_key = var.public_key_path # ローカル上のキーペアのファイルパス
}
# --------------------------------
# EC2の作成
# --------------------------------
resource "aws_instance" "ssh-key-test-ec2" {
  ami                         = "ami-03dceaabddff8067e"
  instance_type               = "t2.micro"
  subnet_id                   = aws_subnet.public-subnet-01.id
  vpc_security_group_ids      = [aws_security_group.vpc-01-ec2-sg.id]
  associate_public_ip_address = true
  key_name                    = var.key_name
  tags = {
    "Name" = "ssh-key-test-ec2"
  }
}
```

キーペアのリソースを別途作成する必要あります。

`terraform apply`します。

接続確認できました。

![スクリーンショット 2023-06-11 12.40.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626370/32ab476c-29cd-fb4c-803a-d644fec5a3a4.png)


ちゃんとキーペアの作成も確認できました。
![スクリーンショット 2023-06-11 12.39.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626370/9f5d2b61-7ee3-5a7a-19f7-5eb7d5304b55.png)

SSH鍵をを使用する方法難しいと思いましたがこちらもそこまで難しくありませんでした。

今日はここまで。
PS4Controller.h備忘録

ESP32 Dev ModuleのVer 1.0.6で動作確認済み
https://github.com/404background/PS4-esp32
こちらのページにあるライブラリをダウンロードするとライブラリを書き換えずにそのまま使える。

cp2102のドライバが必要(ボードによる)
https://jp.silabs.com/developers/usb-to-uart-bridge-vcp-drivers
↑のページでドライバがダウンロードできる

https://sixaxispairtool.software.informer.com/download/
このソフトを使ってPS4のコントローラの接続先macアドレス(ESP32のmacアドレス)を書き換える
ESP32のmacアドレスは
```c++
void setup(void) {
  Serial.begin(115200);
  Serial.println("-----------------");
  uint8_t macBT[6];
  esp_read_mac(macBT, ESP_MAC_BT);
  Serial.printf("%02X:%02X:%02X:%02X:%02X:%02X\r\n", macBT[0], macBT[1], macBT[2], macBT[3], macBT[4], macBT[5]);
}

void loop() {
  delay(1000);
}
```
で取得する。
【ChatGPT無】文字数数えさせたらダメだった


　どうも、カーブミラーです。

　今回は、
　　ChatGPTの鬼門？
　　　数字の話です。

　結論から、
　　先に言いますね。

　**文字列の数字、関連、ダメです。
　　（ChatGPT無料版の話）**

　以前から、
　　ChatGPTさんに、
　　　簡単な計算問題を
　　　　やってもらっていました。
　　　　　もちろん、実験として。

　ふつうに、
　　式を書いて、回答を得る。ダメ。

　ChatGPTさんに
　　計算を命じる方法があるか、
　　　と質問して、得た方法。ダメ。

　ちなみに、
　　「**計算[123×123]**」という感じ。

　まぁ、その時点で諦めていました。
***
　そうして、
　　先日、
　　　ちょっと文字列操作を
　　　　お願いしたところ、
　　　　　うまくいかないことが発覚！

　で、いろいろと、
　　実験を繰り返した結果がこちら。

　**文字列の文字数が定まらない**。

　例えば、
　　「ありがとうございます」
　　　の文字数を教えてもらうと、
　　　　本当なら10文字なのに、
　　　　　9とか11とかになる。
　　ほかの文章も
　　　やはり、
　　　　正答を返さない。

　しかも、
　　DeepLで英語にして、も。
　　　同じ発言を何度も繰り返しても
　　　　同じ回答には、
　　　　　なったりならなかったり。

　ですが、
　　プログラムコードを
　　　出してもらうと、正しい。

　これが、
　　文字数が固定されている、
　　　というならば、
　　　　わからないでもない。

　例えば、
　　英語に翻訳して、
　　　数えたとか、なら。

　でも、定まらない。

　英文の文字列を
　　数えてもらったが、ダメでした。

　例題と答えを用意して、
　　教え込んで、
　　　なんとか、正答するように。

　でも、
　　NewChatにしたら、
　　　教え込んだことが無駄になる。

　いちいち教え込んでも、
　　確実とも言えません。


　最終的に、
　　**文字列操作を
　　　やろうとするならば、
　　　　ChatGPTには、
　　　　　プログラムを作ってもらう、
　　　　　　それが一番、と
　　　　　　　結論付けました。**
Microsoft ExcelからDatabricksに接続する [実践編]

Delta Sharingを使ったアプローチもありますが、これはODBC経由でデータにアクセスします。

https://qiita.com/taka_yayoi/items/df99ace34b8e2b8c13f5

こちらを見ながら設定します。今回はWindowsを使います。

https://qiita.com/taka_yayoi/items/8b21b3527d11571948ed

# Databricks側での準備

1. アクセスするDatabricks環境でクラスターを起動し、以下の情報をメモしておきます。
    - サーバーのホスト名
    - ポート
    - HTTPパス
    ![Screenshot 2023-06-11 at 12.20.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/bd417f04-0d5f-1c9d-44b4-e4f2bcf5c785.png)

1. [パーソナルアクセストークン](https://qiita.com/taka_yayoi/items/712170ba2f2c2bdf5d24)を作成してメモしておきます。

# ローカルマシンでのODBC設定

以下のサイトからODBCドライバーをダウンロードしてインストールします。

https://www.databricks.com/spark/odbc-drivers-download

ODBCのデータソース名を作成します。ODBCデータソースアドミニストレーターを使います。

https://learn.microsoft.com/ja-jp/sql/database-engine/configure-windows/open-the-odbc-data-source-administrator?view=sql-server-ver16

ユーザーDSNを追加します。

1. Simba Spark ODBC Driverを選択します。
![excel1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/df40c0d3-4d4e-1376-e530-c6f1e5778b6e.png)
1. Host(s)に[上のステップ](#databricks側での準備)でメモした**サーバーのホスト名**、Portには**ポート**を入力します。
1. AuthenticationではMechanismに**User Name and Password**、User Nameには`token`、Passwordにはパーソナルアクセストークンを入力するのですが、後のExcelのステップで再度聞かれました。
![excel2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/6234ccc8-09d9-a74a-7bff-eb65c38e452c.png)
1. **HTTP Options...** をクリックして、HTTPパスを入力します。
![ecvel3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/3603dbfd-3b26-38a3-62cd-48133d6520e2.png)
1. **SSL Options...** をクリックして、**Enable SSL**にチェックをつけます。
![excel5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/48944dcc-8284-b0cc-647e-5e0ca9de316a.png)
1. **Test**をクリックして、**Success**と表示されることを確認します。
1. **OK**をクリックします。

# Excelへのデータの読み込み

1. Excelを起動します。
1. **データ**リボン、**データの取得 > その他のデータソースから > ODBCから**を選択します。
![excel9.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/2828bc61-a527-cbf0-f64f-b906150dee85.png)
1. [上のステップ](#ローカルマシンでのodbc設定)で作成したデータソース名を選択します。
![excel6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/efb992f9-a040-7c8d-a9b5-d4a3709bf49b.png)
1. ユーザー名に`token`、パスワードにはパーソナルアクセストークンを入力します。
![excel7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/70100d43-0225-3fba-60af-ff98b8bd1f38.png)
1. Databricksのカタログ、データベースが表示されます。
![excel8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/70ea22c4-fff4-cb82-f063-423d02f75008.png)
1. テーブルを選択するとプレビューが表示されます。**読み込み**をクリックします。
![excel10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a789bd0a-4bab-37e7-cf5a-241cf471cbba.png)
1. Excelにデータが読み込まれました！
![excel11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/01e6f700-2879-7348-a346-37ea678bbbf1.png)

Excelで作業した方が効率的なシーンも存在しますので、適材適所で使い分けてください！

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
FlowiseAIを触ってみた

なんか記事書く練習したいなぁと思ってたら、
こんなツイートを見かけたので、やってみました。

https://twitter.com/matchaman11/status/1665783979113431043

なになに。。
Flowiseaiだって？

https://flowiseai.com/

blueprintみたいにできるのね。

# 最初に感想

embeddingとかvector storageみたいなやつ(BabyAGIの時にAPIを使ったのを覚えてるくらい)が分からないとできないので、一般エンドユーザの私にはさっぱりでした。
でも、これでLLMのアプリの仕組みとかを示してくれたら分かりやすい気もしたので、わかる方に応用を託します。（他力本願）

# 使ってみる
githubはここ

https://github.com/FlowiseAI/Flowise

起動してみたら
![home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193625/42522a8f-2553-86fc-1051-ab63c3236af0.png)
Add Newを押して、+ボタンを押したら、Unreal Engineでいうブループリントみたいなやり方で組むことができます。
![Addnodes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193625/520e4766-f50c-62c1-2ec8-0c5d9865905d.png)

chatGPTのAPIだけ入れてAgentsはMRKL Agent for LLMs（なにこれ・・・）を使って、
![使い方.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193625/e06cc369-b280-d96e-1403-26139136bfe6.png)

ノードが一つだからなのか会話内容はたどたどしいですね。

ホームページではこんな感じのことやってました
![example.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193625/07f4e75c-63e5-ccba-f979-7148b18c6ff7.png)

私はここまでのことはまだ試せていません。。

# まとめ
アプリのデプロイは早くできるなと思う反面、これだけだと細かいUI設定ができないので、これはテスト用なのかなとも思いました。

あと、ChatOpenAIノードのTemperatureを直接値を入れるのではなく、スピンボックスのアップダウンボタンで操作すると無限にカウントアップダウンしたりするバグがありました。

色々なツールが出ていて色々触って面白そうなのをAIのミーハー目線で紹介していきたいと思います。最初に添付したツイートには他のにも有用なツールの紹介がされいるのでやってみようかなって思ったり思わなかったりしてます。
（最近embeddingっていうのが何なのか知った）
Docker 基本コマンド一覧

## 初めに
Dockerの基本コマンド一覧を備忘録として残します。

## コマンド一覧
| コマンド    | 効果 |
|-----------|------------|
| __docker-compose ps__ | コンテナを一覧表示、確認 |
| __docker-compose logs__ | コンテナからの出力を表示 |
| __docker-compose up__ | コンテナの作成と開始 |
| __docker-compose up -d__ | バックグラウンドでコンテナ作成と開始（そのためログがターミナルに出力されない） |
| __docker-compose stop__ | サービスの停止（デスクトップアプリでも実行可能） |
| __docker-compose start__ | サービスの開始（デスクトップアプリでも実行可能） |
| __docker-compose restart__ | コンテナの再起動（デスクトップアプリでも実行可能） |
| __docker-compose exec (service名) /bin/bash__ | 起動しているコンテナにコマンドを実行するためのターミナルに入る |

__MySQLの操作__
docker上のMySQLコンテナに入る
 ```:ターミナル
    $ docker-compose exec {サービス名} /bin/bash
 ```

 ```:サービス内のターミナル
    $ mysql -u root -h 127.0.0.1 --port ポート番号
    $ Enter password: パスワード
 ```


## 参考資料
__公式ドキュメント__

https://docs.docker.jp/engine/reference/commandline/compose_exec.html

__オプションについて__

https://docs.docker.jp/compose/reference/up.html

## 最後に
最後まで閲覧いただきありがとうございました。
ご意見、ご指摘ありましたら、コメントお願いいたします。
Python3エンジニア基礎試験_公式問題集の復習①

# はじめに
「徹底攻略Python 3 エンジニア認定［基礎試験］問題集」の復習として記載しています。

https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Python-3-%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E8%AA%8D%E5%AE%9A%EF%BC%BB%E5%9F%BA%E7%A4%8E%E8%A9%A6%E9%A8%93%EF%BC%BD%E5%95%8F%E9%A1%8C%E9%9B%86-%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE%E3%83%93%E3%83%BC%E3%83%97%E3%83%A9%E3%82%A6%E3%83%89/dp/4295016055

# リストの操作

```list.py
data = [1, 2, 3, 4]
print(data[:2], data[3:])
# [1, 2] [4]
```

● 解説
リストのスライスに関する問題。
リストのスライス範囲は、<font color="Red">**「開始位置:終了位置」**</font>のように記述します。
開始位置を省略すると先頭からになり、終了位置を省略すると末尾までになります。

最初の引数の data[:2]は、インデックス0から1の要素（2未満）が取得されます。
結果として [1, 2] が表示されます。
2つ目の引数の data[3:]は、リスト data のインデックス3から最後の要素までを
スライスしています。コロンの後に何も指定しない場合、スライスはリストの末尾まで続きます。
インデックス3から最後の要素までが取得されます。結果として、 [4] が表示されます。

```list.py
data = [1, 2]
data.append(3)
print(data)
# [1, 2, 3]
```

● 解説
リストの末尾に値を追加するには、<font color="Red">**append()メソッド**</font>を使います。
このようにドット「.」を使って書く関数を<font color="Red">**メソッド**</font>といいます。

<font color="Black">**書式 リストに要素を追加する①**</font>
リスト名.append(値)

<font color="Black">**書式 リストに要素を追加する②**</font>
リスト名 += 「値」

```list.py
下記の記述は正しいか
[[1, 2, 3, 4]]の長さは4である
# 誤り。長さは1である。
```

● 解説
リストの入れ子に関する問題です。
リストの要素として「別のリスト」を持つことを<font color="Red">**入れ子**</font>にするといいます。
リストの入れ子は<font color="Red">**ネスト**</font>と呼ばれることもあります。

[例]ネストの作成①
[[1, 2], [3, 4]]

[例]ネストの作成②
[[1, 2, 3, 4]]


```list.py
stack = [1, 2, 3, 4]
data = []
while stack:
    data.append(stack.pop())
print(data)
# [4, 3, 2, 1]
```

● 解説
リストをスタックとして使う方法についての問題です。
<font color="Red">**スタック**</font>は、複数の値を扱えるデータ構造の一つです。リストと異なるのは、
「要素を挿入すると末尾に追加され、取り出すときも末尾から削除される」という点です。

stack.pop()はstackの最後の要素を削除し、data.append()はその要素をdataに追加します。

```list.py
data = [1, 2]
data.append(3)
data.pop(0)
print(data)
# [2, 3]
```

● 解説
リストをキューとして使う方法についての問題です。
<font color="Red">**キュー**</font>は、複数の値を扱えるデータ構造の一つです。リストと異なるのは、
「要素を挿入すると末尾に追加され、取り出すときは先頭から削除される」という点です。

リストをキューとして扱うには、append()とpop()の2つを使用します。
append(要素)で末尾に要素を追加し、pop(0)で先頭を削除します。

```list.py
data = []
for i in [1, 2, 3]:
    for j in [1, 2]:
        if i != j:
            data.append((i, j))
print(data)
# [(1, 2), (2, 1), (3, 1), (3, 2)]
```

● 処理の流れ
1. 最初に、空のリスト data が作成されます。

2. 次に、外側の for ループが i の値を [1, 2, 3] の順に取ります。
   内側の for ループが j の値を [1, 2] の順に取ります。

3. 内側のループ内で、if 文が実行されます。
   この条件式は、i と j が等しくない場合に True となります。
   つまり、i と j が異なる値の組み合わせの場合に True となります。

4. 条件が満たされると、(i, j) というタプルが作成され、
   data リストに append() メソッドを使用して追加されます。

5. 最後に、print(data) 文が実行され、data リストが表示されます。

したがって、このコードは、1 から 3 までの数値と 1 から 2 までの数値の組み合わせを生成し、
それぞれの組み合わせを data リストに追加します。
ただし、i と j の値が等しくない組み合わせのみが追加されます。

※リスト内包表記だと下記のようになる

```list.py
print([(i, j) for i in [1, 2, 3] for j in [1, 2] if i != j])
# [(1, 2), (2, 1), (3, 1), (3, 2)]
```
XAMLでカレントディレクトリを取得

XAMLでカレントディレクトリを取得を取得しようと思ったら わからなかったので、メモ



```xml:上に書くネームスペース
		xmlns:sys="clr-namespace:System;assembly=mscorlib"
```


```xml:本体
				<DockPanel>
					<TextBlock Text="カレントディレクトリ"/>
					<TextBox VerticalAlignment="Center" Text="{x:Static sys:Environment.CurrentDirectory}" IsReadOnly="True"/>
				</DockPanel>
```

### 参考
https://www.c-sharpcorner.com/UploadFile/raj1979/how-to-get-system-environment-information-in-wpf/
VisualStudio でファイルスコープ名前空間を優先に設定する

VisualStudio でファイルを追加したとき、規定だと**従来型の namespace**で生成されます。
```cs
namespace MyNamespace
{
    internal sealed class MyClass
    {
    }
}
```
C# 10 から **ファイルスコープ 名前空間** が導入されました。
```cs
namespace MyNamespace;

internal sealed class MyClass
{
}
```

これ、個人的に大好き。

https://qiita.com/higege-amdeker/items/dfbaa0e931d698c546b6

設定を変更して積極的に使っていきましょう。

# 手順

1. [ツール] > [オプション] > [テキストエディタ―] > [C#] > [コードスタイル] > [全般]
1. [コードブロックの優先順位] > [名前空間の宣言]
1. [範囲指定されたファイル] を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/aed0187a-aa34-489d-ed8c-4f63fe7f5307.png)

ここに限ったことではないのですが、ちょいちょい日本語ローカライズに違和感を感じます・・・笑

:::note warn
.editorconfig を使用している場合はそっちで上書きされるので、そちらの設定も必要です。
:::
PowerAutomate: Microsoft(SharePoint) Lists のユーザー列の設定が簡単になりました by Resolve person Action

# 背景
Microsoft Lists の User 列を設定するとき、以前までは該当サイト用の User ID に変換をする必要があってかなり面倒だったんだけど、新しい Action で簡単になってたので紹介まで

Graph API に使える Actions がいくつかあるけど、以下のように少しずつ制限が広がりそうだし、面倒ってのもあるし、そもそも Low Code なんだから簡単に使える Action が出てくるのはありがたいですよね :laughing: 

::: note warn
[HTTP Action](https://learn.microsoft.com/ja-jp/connectors/office365groups/#actions) の Scope が狭くなる？　V1 to V2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/c93740c7-d760-6974-9be8-0c3b5ff6ab06.png)
:::

# 新旧比較
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/a71b56e4-fe7d-01ab-0859-0084c6e07d01.png)

## 今までのやり方
1. Graph API で Site User 一覧を取得
1. 一覧から取得したい User を取得
1. Lists で使う Site UserID 取得

## Resolve Person のやり方
以下アクション一個で取得出来る
- [人を解決する（日本語訳）](https://learn.microsoft.com/ja-jp/connectors/sharepointonline/#%E4%BA%BA%E3%82%92%E8%A7%A3%E6%B1%BA%E3%81%99%E3%82%8B)
- [Resolve person](https://learn.microsoft.com/en-us/connectors/sharepointonline/#resolve-person)



# 参考
Site User ID を利用した例

https://qiita.com/baku2san/items/c5b56ce21c5a880a9d3f#%E9%81%B8%E6%8A%9E%E3%81%97%E3%81%9Fteam%E3%81%AE%E3%83%A1%E3%83%B3%E3%83%90%E3%83%BC%E5%8F%96%E5%BE%97