OmniAICreator/Qiita-1.07M huggingface dataset:
Google Cloud に関連するアカウントを整理してみる

こんにちは、京セラコミュニケーションシステム 石関 (@kccs_daisuke-ishizeki）です。

[前回の記事](https://qiita.com/kccs_daisuke-ishizeki/items/171b637aa4b52a5626d1)を書いた後に

- 「なんとかアカウントがたくさんあってよくわからない」

と質問？をいただきました。

探した限り、一部の用語の意味するところは文脈によって変わるようなので、わたしの中での使い分けを記事にします。

似たようなことを疑問に思う人もいるかと思いますので、参考になれば幸いです。

## 「なんとかアカウントがたくさんあってよくわからない」とは

[前回の記事](https://qiita.com/kccs_daisuke-ishizeki/items/171b637aa4b52a5626d1)の中では"Google アカウント"しか出てきていないはずなので、何がわからないのか深掘りしたところ
**「Google Cloud に関連するなんとかアカウントって、いろんな種類があって指しているものや関係性がわからなくて混乱している」**
と言う事でした。

~~そこか。~~

確かにややこしいポイントだと思います。

ちなみに「いろんな種類」とは、↓あたりを指しているようです。

- Google Workspace アカウント
- Cloud Identity アカウント
- Google Cloud(GCP) アカウント
- 請求先アカウント
- サービスアカウント
- Google アカウント

前者 3 つがイメージしにくい、または文脈によって指しているものが変わっていることが多い気します。

あと Google Cloud(GCP) の世界と Google Workspace の世界がごっちゃになっていそうです。

## 全体像

関係性をイメージしやすいように図にしてみました。全体像としてはこんな感じでしょうか。

![全体イメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728315/af92ebb9-094e-adc3-a14d-bacfe077f919.png)
Cloud Identity は、Google Workspace の ID サービスをスダンドアロン型のサービスとして提供されたものですので、ここでは右側の Google Workspace と同じハコを指しているものとしてください。

### Google Workspace アカウント

オレンジ色で囲った部分を指します。
![GoogleWorkspaceアカウント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728315/59665b50-d6c2-5d60-407c-c97a62beb744.png)

人によっては黄色部分の Google アカウントを指して会話している気がしますが、そちらは"Google アカウント"もしくは"Google Workspace のユーザーアカウント"と分けて使っています。

裏づけとして Google Workspace の管理コンソールである、Google 管理コンソール（[admin.google.com](https://admin.google.com])）を確認すると、以下のような画面が確認できます。名前には Google Workspace で利用しているドメインが入り、ユニークな顧客IDが割り振られています。

![顧客ID.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728315/0bd805cc-256a-f076-8014-8c7b459ef3ea.png)


### Google Cloud(GCP) アカウント

これが厄介です。。。

わたしの認識では"Google Cloud(GCP) アカウント"が指す意味として、概ね以下の**どれか**を指して使われています。

1. （Google Cloud(GCP) のリソースを操作できる）Google アカウント
2. 請求先アカウント
3. Cloud-level[^1]のドメインのハコ

:::note warn
誤解を与えるケースがありそうなので、図はイメージです。
:::
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728315/19fb0f72-3e19-9e00-7e68-af0a9d8c2b7f.png)

表記ゆれの一種なのか、用語の定義がない？ためなのか、相手や文脈によって指しているものが変わるため、わかりにくいなーと感じています。

**そのため自分からは"Google Cloud(GCP) アカウント"と表現せず、1 や 2 の用語を使うようにしています。使うとしたら消去法で 3 かなと思っています。**

ちなみに公式ドキュメントを検索したところ以下の状況（2022年9月現在）でした。

- "Google Cloud アカウント"の表現はあまりない[^2] [^3]
- あったとしても請求先アカウントを指している事が多い（わたしの印象では8割以上）


このモヤモヤはわたしだけなのかなー。~~気にしすぎ~~


## まとめ

わたしなりの使い分けをご紹介しました。ご参考まで。


[^1]: [公式のドキュメントで Resource Hierarchy のイメージに表現されています。](https://cloud.google.com/billing/docs/concepts#gcp_resource_hierarchy_overview)

[^2]: [検索ワード: "Google Cloud account" 約2800件(2022/9/29現在)](https://www.google.com/search?q=%22Google+Cloud+account%22+site%3Acloud.google.com)

[^3]: [検索ワード: "Google Cloud アカウント" 約872件(2022/9/29現在)](https://www.google.com/search?q=%22Google+Cloud+%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%22+site%3Acloud.google.com)
エラー文(uninitialized constant)の内容

# はじめに
エラー文でよく見る「uninitialized constant」の意味が翻訳結果とはほど遠いので、記録に残す。

## uninitialized constantについて
「uninitialized constant」のエラー文は、
直訳すると「初期化されていない定数のエラー」という意味だが、
Rubyでは「ファイル名やクラス名が正しくない場合」に表示されるエラー。
Django Adminの詳細画面でfieldsの項目を動的に変更する

# 概要
詳細画面で表示される項目をモデルの状態に合わせて変えたい。
そこで、get_fields()を改造することにした。

##### 前提
- Django 3.2

# 経緯

こんなデフォだとこんな感じのfields設定
```
class SomeAdmin(admin.ModelAdmin):

    fields = (
        'some_field_A',
        ('some_field_B1','some_field_B2'),
        ('some_field_C1','some_field_C2'),
        'some_field_D',
        'some_field_E'
    )

```
B1とB2, C1とC2を並べて表示している。

しかし、B2がない時、C2がない時にはB1, C1だけを表示したい。

# 方法
get_fields()を上書きする。

```
class SomeAdmin(admin.ModelAdmin):
    
    def get_fields(self, request, obj=None):
        B_field = ('some_field_B1','some_field_B2') if obj.some_field_B2 else 'some_field_B1'
        C_field = ('some_field_C1','some_field_C2') if obj.some_field_C2 else 'some_field_C1'
        
        custom_fields = (
            'some_field_A',
            B_field,
            C_field,
            'some_field_D',
            'some_field_E'
        )
        
        return custom_fields            
``` 

こんな感じ。
AWS SAA 合格体験記

こんにちは、[Kuni](https://qiita.com/kuniengineer)です。2022年8月28日にAWS SAAに合格したので記録を残しておきます。

# 前提

AWSは3か月間研修で利用したことがあるだけでした。また、その他のクラウドは利用したことが全くありません。




# 使用した資料

1.[AWS認定資格試験テキスト-AWS認定-ソリューションアーキテクト-アソシエイト](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/479739739X)

2.[【SAA-C03版】これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座](https://www.udemy.com/course/aws-associate/)

3.[【C03版へと更新中】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/)




# 勉強期間

大体1ヶ月半くらいかけてやりました。大体1日平均30分-60分くらいの学習時間であったと思います。




# 勉強方法
最初にUdemyの試験突破講座を1周しました。ハンズオンを行う過程でテキストも進めました。知らない単語が試験突破講座を行うことで少なくなったので、その理解を定着させる目的で理解を深めました。
その後問題集の基本問題と高難易度の②③を2-3周しました。




# 試験当日

受験はテストセンター(パソコン教室みたいなところ)で受けました。

今回私はバウチャーで受験できたので受験における実費は0でした。

本人確認書類として免許証と保険証を出した気がします。

当日は試験開始前に行っても席が空いていたため、開始時間前から始めることができました。

当時の状況としては問題集の基本問題は8.5割、高難易度は7割くらい取れている状態でした。

見直しの時間を含め、時間ギリギリに終わりました。1周目が解き終わった段階では3割くらい微妙なものがありました。。




# 結果と反省

結果は735点でギリギリ受かりました。

反省や感想がいくつかあるので以下で挙げます。




##### ・模擬試験集の高難易度問題はやる必要が全く無かった点

→高難易度問題ではそれまで知らなかったサービスが新たに出てきて、その点を覚えたりしていましたが、そのサービスらは全くと言っていいほど出てこなかったためです。ただ2022/9から試験範囲が変わっているそうなので、もしかしたら現在では有効であるかもしれません。




##### ・模擬試験集の基本問題は有効であった点

→基本問題は定番のサービスの理解が深められる問題ばかりであったので、非常に有効であったと個人的には思いました。




##### ・試験突破講座は試験突破することにおいては必要無かった点

→ハンズオン形式でやるので、AWSの操作の理解を深めるには役に立ったと思いますが、何せ長すぎる(45時間分)ので試験突破のことだけを考えるとやる必要はない気がします。




##### ・基本的なところももっと詰めておけば良かった点

→Auto ScalingやALBが問題として数多く出てきた印象です。こういった基本的な問題をちゃんと解けていればもっと楽に合格できていたと思います。ちなみに、〇〇という技術を知っていたら即答できるみたいな問題はせいぜい10問くらいでした。




# 終わりに

ギリギリでも受かったのでひとまず良かったです。

次は11/15からAWSSAPの問題が改定されるとのことで、11月中に試験範囲変更前に1度チャレンジしてみたいと思います。

受験される方の参考になれば嬉しいです！！
heroku と　環境変数

herokuとsendgridを使ってメール機能があるアプリを作りました。
環境変数を使い、メールの送信先をしましたが、メールを送信することができませんでした。

heroku logs -t をしたところ、
```
heroku ArgumentError (SMTP To address may not be blank: [] 
```
このようなログがありました。
address　が　blankになっていました。
環境変数を指定するファイル（ .env ）を .gignoreに入れていたため、
heroku上では環境変数の中身がないため、
メールを送信することができませんでした。

送信するためには、
Heroku上の環境変数をセットします。heroku config:setコマンドを使用することで、Heokuの環境変数を設定することができます。
（例）
```
heroku config:set ADDRESS=aaa@aaa.com
```
上記のようにすることで、環境変数を設定する事ができ、
結果的にメールの送受信をする事ができました。
メールが機能しない（herokuとsendgridを使用）

herokuとsendgridをを用いてメール機能のあるアプリを作りました。
自分のメールボックス宛にメールを送りましたが、以下のようなエラーになりました。
![スクリーンショット 2022-10-12 12.02.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2881857/8d3f07be-d3b1-a290-7639-fbd68fc81554.png)

heroku logs -tail　で調べたところ、
```
Error: Couldn't find that app.

Error ID: not_found
```
上記のような記載がありました。
これを見てもエラーの内容が分かりませんでした。
heroku logs　で調べたところ、
```
[2022-10-08T02:40:38.228942 #4] FATAL -- : [c68a1a18-b33a-4ab0-8d88-8e306a43142e]
2022-10-08T02:40:38.228972+00:00 app[web.1]: [c68a1a18-b33a-4ab0-8d88-8e306a43142e] Net::SMTPFatalError (550 The from address does not match a verified Sender Identity. Mail cannot be sent until this error is resolved. Visit https://sendgrid.com/docs/for-developers/sending-email/sender-identity/ to see the Sender Identity requirements
```
以上のようなエラーログが出ました。

このエラーログをもとに検索したところ、

参考記事

https://qiita.com/ryo_kh/items/9af6cee58223845c66b3

上記のような記事が出てきたため、記事の通り改善を行いました。
具体的な内容は、Single Sender Verificationの「VERIFIED」カラムに「×」マークが表示されており、まだ差出人情報の認証が完了していませんでした。そのため認証メールを再送してもらい、認証を完了させました。
その後、もう一度アプリに戻り、情報を登録したところ、エラーなく、メールがメールボックスに送られるようになっていました。
deadline batch run mayabatch python

```batch
"C:\Program Files\Autodesk\Maya2020\bin\mayabatch.exe" -command "python(\"import sys;sys.path.append('J:/vd2/work/project_tools/python/submit_qube/ex_maya_ass');import separate_asset_and_build_ass_lts;reload(separate_asset_and_build_ass_lts);separate_asset_and_build_ass_lts.run_json()\")" %*
```
【SQL】PHPで範囲検索のSQL文をシンプルに書く方法

# 範囲検索のSQL文をどう書く？

このような日付の範囲検索画面を作る場合のSQL文について学習したので記録しておきます。


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703404/34733a1d-8941-c9fd-c06a-6dd1d1c2a01d.png" width=70%>



### 記述例１

```ruby:test.php

$SQL= "";
$SQL .=" select * ";
$SQL .=" from URIAGE_T";
$SQL .=" where (CD = 1200)";

	//条件：売上日
	if((!empty($Inq_DATE_F))and(!empty($Inq_DATE_T))){
		$SQL .=" and (URIDATE between '".$Inq_DATE_F."'and'".$Inq_DATE_T."')";
	}elseif((!empty($Inq_DATE_F))and(empty($Inq_DATE_T))){
		$SQL .=" and (URIDATE >= '".$Inq_DATE_F."')";
	}elseif((empty($Inq_DATE_F))and(!empty($Inq_DATE_T))){
		$SQL .=" and (URIDATE <= '".$Inq_DATE_T."')";
	}else{
		//何も行わない
	}
```



### 記述例２

```ruby:test.php

$SQL= "";
$SQL .=" select * ";
$SQL .=" from URIAGE_T";
$SQL .=" where (CD = 1200)";

	//条件：売上日
	if ($Inq_DATE_F != ""){
		$SQL .=" and (URIDATE >= '".$Inq_DATE_F."')";
	}
	if ($Inq_DATE_T != ""){
		$SQL .=" and (URIDATE <= '".$Inq_DATE_T."')";
	}
```



:::note info
記述例２の方がシンプルでGood。
:::

:::note warn

記述例１でも検索には問題ないが、「between」を使用している。
betweenは、桁数が可変だと抽出は機能しないので、使用する場合には注意が必要。
:::
Rails form_withについて

app/views/blogs/new.html.erb
```
<%= form_with(model: @blog, local: true) do |form| %>
  <div class="blog_title">
    <%= form.label :title %>
    <%= form.text_field :title %>
  </div>
  <div class="blog_title">
    <%= form.label :content %>
    <%= form.text_field :content %>
  </div>
  <%= form.submit %>
<% end %>
```
app/controllers/blogs_controller.rb
```
class BlogsController < ApplicationController
  def index
  end

  def new
    @blog = Blog.new
  end

  def create
    Blog.create(title: params[:blog][:title], content: params[:blog][:content])
    # 追記する
    redirect_to "/blogs/new"
  end
end
```
app/views/blogs/new.html.erbファイルはビューファイルです。
create blog ボタンを最後に押すと、自動的にcreateアクションに行きます。
これはなぜだろうと思いました。
form_with(model:（Blog.newで作ったインスタンス変数が入っている）、インスタンス変数が空の場合。newアクションの後、createアクションに行くようになっているとのことです。

参考情報

https://qiita.com/kajikaji/items/5b5687fbb8ad287560fc

https://qiita.com/snskOgata/items/44d32a06045e6a52d11c
文字コード関係

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめA～M](https://qiita.com/Keiji_otsubo/items/f3ddedee6793bf1576f8)

# 改行コード

|OS|コード表記|16進表記|10進表記|
|:---|:---|:---|:---|
|UNIX|LF|0A|10|
|Windows|CRLF|0D 0A|13 10|
|Macintosh|CR|0D|13|


+ [ICU ロケール形式の有効化の準備](https://qiita.com/Keiji_otsubo/items/6eef4378ba18b54c3804)

+ [フローで改行する](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000K1nQ3)
+ [アイデアみたい](https://ideas.salesforce.com/s/idea/a0B8W00000GdbiIUAR)
BR() が使えるとか言っているけど... 
+ [ASCII characters from 33 to 126](https://www.ibm.com/docs/en/sdse/6.4.0?topic=configuration-ascii-characters-from-33-126)


# 文字化け

+ [文字化けの対応](https://qiita.com/Keiji_otsubo/items/75a133c95410303607fe)

# 全角半角の制御

+ [画面フロー上の入力項目の日本語入力(半角/全角)について](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V000077itHv)
顔認証システムを作りたい#1 Face Recognitionのdlibのインストールが苦戦した話

# どうしてこうなった。
顔認証のアプリを作って**数少ない友達**に**イキる**ために。
Face Recognitionという誰でも簡単にpythonで顔認証ができるモジュールをインストールして
コードを書いたらこうなった。
~~~
ModuleNotFoundError: No module named 'dlib'
~~~

dlibがないらしい
## Cmakeを入れる
dlibをインストールするにはCmakeが必要らしいのでCmakeをインストールした。


そのあとにdlibをインストールした。それで実行し直したら。

~~~
ModuleNotFoundError: No module named 'dlib'
~~~

**なんでだよインストールしたじゃん**

この**dlib**のインストールに多くの人が苦戦しているらしい

なぜインストールできないのか、いろいろググったりして**3日間**という時間を無駄にした。

いろんな方法でインストールしても変わらなかった。
# 解決法

某エンジニア質問サイトで同じようなことに遭遇している人がいた

回答を見てみると**python -m pip install**を使って同一環境にインストールしたらいいらしい。

**それだ！**

VSコードのターミナルでやってみた。
~~~
python -m pip install dlib
~~~


そしたらあっさりといけてしまった。

**泣きたかった**

アナコンダ使ったりbrewコマンドでインストールしようとした自分が愚かに思えてきた。

俺の3日間はなんだったのかと思った。

## 調べた時に見たおすすめなサイト
https://qiita.com/pranetaorion/items/10152cae24dd5728af50

https://stackoverflow.com/questions/52829483/importerror-no-module-named-dlib

https://qiita.com/mix_dvd/items/d38b322bab99b237943a
## 某質問サイトのやつ


https://teratail.com/questions/dgthsy388g6cnr#reply-nfl0g7yqgyw5iv
Knowledge REST API



+ [【元の質問】ケースとナレッジを紐付ける方法について](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000IR03G)
+ [Knowledge REST APIで外部サービスからナレッジを使おう](https://base.terrasky.co.jp/articles/wjoDf)

-----------------------------------------

+ [【元の質問】ナレッジコンポーネント追加時の推奨記事の設定について](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Je6FcSAJ)
+ [Search Suggested Article Title Matches](https://developer.salesforce.com/docs/atlas.ja-jp.238.0.knowledge_dev.meta/knowledge_dev/resources_search_suggest_title_matches.htm)
+ [Suggest Salesforce Knowledge Articles](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_forcecom_kb_suggestions.htm)
+ [Knowledge Article Suggestions: behavior differs between Classic and Lightning](https://salesforce.stackexchange.com/questions/242331/knowledge-article-suggestions-behavior-differs-between-classic-and-lightning)
+ [How can I modify the layout of Suggested Articles on Cases in Service Cloud Console](https://salesforce.stackexchange.com/questions/159880/how-can-i-modify-the-layout-of-suggested-articles-on-cases-in-service-cloud-cons)
ServiceNow開発者インスタンスのヘッダーカラーを変更する方法

# ServiceNow開発者インスタンスのヘッダーカラーを変更する方法
こちらはServiceNow初心者の自分の作業ログです。

##### ServiceNowの開発者インスタンスのヘッダーカラーを好きな色に変更します。(2022年10月、Sandiegoで実施) 

### Next Exprience UI
#### カスタムUXスタイルの作成
1. ServiceNow PDIにログインします。
1. フィルターナビゲーターに[sys_ux_style.list]と入力して、UX Stylesを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2911551/53596e5b-a454-f44e-7060-00deb609d1c4.png)
1. [New]ボタンをクリックし、新しいUXスタイルレコードを作成します。Nameは任意、Styleは以下で指定できます。ColorはRGBで指定します。
"--now-unified-nav_header-color": ヘッダーの文字色
"--now-unified-nav_header--background-color":ヘッダーの色
    ```
    {
        "properties": {
            "--now-unified-nav_header-color": "255,255,255",
            "--now-unified-nav_header--background-color": "114,210,219"
        }
    } 
    ```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2911551/4487a778-3a92-1932-b338-037c304bdd06.png)
4.  [Submit]をクリックします。新しいUX スタイルが作成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2911551/dd4841c3-7896-f945-86b4-4429d18e4bdd.png)

#### カスタムUXテーマスタイルの作成（作成したUXスタイルをテーマに適用）
1. ナビゲーターフィルターに[m2m_theme_style.list]を入力し、UX Theme Stylesを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2911551/65478ee8-88e9-dfd6-f18d-a3a2f77033db.png)
1. [New]ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2911551/6d8adea0-1234-99eb-92e4-e3a47be99a31.png)
1. 画像のように入力します。Styleは作成したカスタムUXスタイル名です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2911551/a641da68-332c-4603-baf4-28da58b9a02f.png)
1. [Submit]ボタンをクリックします。新しいUXテーマスタイルが作成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2911551/6448363d-5ac5-b5e8-d542-a1124d10bf38.png)

#### 確認
1．再ログインします。指定したカラーが適用されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2911551/e6afde41-d566-7909-eee9-3c3a50fd45e3.png)


### Portal(ESC)
#### Theme Colorの変更
1. ServiceNow PDIにログインします。
1. フィルターナビゲーターに[Service Portal Configration]と入力して、Service Portal Configrationを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2911551/35c48a55-01b1-766d-584b-c7a03d487143.png)
1. [Branding Editor]を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2911551/b3d7d985-7848-613c-1f74-672897e624fe.png)
1. [Employee Center]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2911551/44eff4a3-0cd0-674d-fb64-03be8ed6dd7c.png)
1. [Theme Colors]タブを選択し、[Navbar background]で任意のカラーコードを指定します。変更はすぐに適用されて画面で確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2911551/0d61d8b5-f7ec-aea6-02f6-c3f0c4792316.png)

以上です。
ControlTowerで集約したCloudTrailのログをAthenaで検索したときにエラーが出た

### サマリ
- ControlTowerでログアーカイブアカウントに保管しているCloudTrailを検索しようとしたらエラーが出た
- テーブル設計はドキュメント通りで問題無くクエリ可能なはず
- IAM側の権限は必要十分だった


### 本文

Athenaを使ってAWSが生成するログを検索する場合のテーブル定義については以下にまとまっているのでこれを使ってサクッとテーブルを作る
AWS のサービス ログのクエリ
https://docs.aws.amazon.com/ja_jp/athena/latest/ug/querying-aws-service-logs.html

クエリを投げるとオブジェクトに対しての権限が足りない旨が表示されている。
この権限が足りないってのがハマったポイントでした。実際にオブジェクトを見に行ったら権限エラーが出たんですが、詳細を呼んでみると復号化が出来ていないみたいだったのでピンと来ました。

他のアカウントのユーザーに KMS キーの使用を許可する
https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/key-policy-modifying-external-accounts.html

ドキュメントを参考にControlTowerの管理アカウントのKMSにポリシを追加する。
```
 {
            "Sid": "Allow a LOG ACCOUNT to use this KMS key",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::ACCOUNT_ID:root"
            },
            "Action": [
                "kms:GenerateDataKey",
                "kms:Decrypt"
            ],
            "Resource": "*"
        }
```

手元の検証用なのでロール単位ではなく、アカウントレベルで今回は許可を与えた。


### 結論
ControlTowerででKMSの暗号化を有効化していて、KMSのキーポリシに許可を書いていないだけだった。
パラメータとparamsについて

パラメータとは
railsアプリケーションは、フォームに記述した内容を送信した時、Parametersという名のハッシュ値に変換します。そしてRailsアプリケーション内部へと送り込みます。

rails sの画面で
```
Processing by BlogsController#create as HTML
  Parameters: {"utf8"=>"✓",
   "authenticity_token"=>"TTwmgIC9+5Z+/
   TvIwMOGYiJv05QhpSEgp6oh9Kkbd8Fyu8JD2hp5Ds1E3P7no
   jFyqAoWW1FXEnJww1BdmbZlcg==",
   "blog"=>{"title"=>"hoge", "content"=>"fuga"},
    "commit"=>"Create Blog"}
```
上記のような感じになります。
Parametersという名のハッシュ値ができていることが確認できます。
この送られてきたパラメータ（Parameter）は、Railsがデフォルトで常備しているparamsメソッドを使用することで取得できます。

```
def　create
    Blog.create(title: params[:blog][:title], content: params[:blog][:content])
end
```
上記はcreateアクションを作り、paramsメソッドを利用してparameterを取得しています。

parameterは詳細に見ると、{"blog"=>{"title"=>"hoge", "content"=>"fuga"}}　のようになっています。

上記のようなハッシュの中にある、ハッシュ要素を抜き出すためには、
params[:blog][:title]　 params[:blog][:content]
このような形で抜き出すことができます。

また、シンボルを使って、ハッシュを抜き出す事ができる理由も、railsガイドに以下の記載がありました。

（引用）『　paramsハッシュはハッシュのように振る舞いますが、キー名にシンボルと文字列のどちらでも指定できる点がハッシュと異なります。　』
https://railsguides.jp/action_controller_overview.html#ハッシュと配列のパラメータ
【初心者向け】Railsに出てくるsessionとは？？

## 書いた理由
Railsの学習をしていて、sessionの使い方が分からなかったため記事にまとめてみました。
プログラミング初学者のため、間違えていることがあるかもしれません。ご容赦ください🙇

## 環境
mac m1
Ruby 3.0.1
Ruby on Rails 6.0.3

## sessionとは？
sessionとは主にログイン機能に使用されるもので、ログイン状態を維持させるものです。つまり、ステートフルな通信を実現させるための仕組みとなります。

## sessionを使ってみよう！
1. sessionに値を保存する
セッションはハッシュと同じようにキーとバリューの組み合わせで値を保存します。

    ```
    session[:user_id] = user.id
    ```

1. sessionの値を削除
デリートメソッドの引数にキーを与えて、該当する要素を削除します。

    ```
    session.delete(:user_id)
    ```
結果的にsessionの中身はnilとなります。

## 注意！
sessionは基本的に小さいデータを扱う前提で使用する必要がありそうです。大きいデータ（cookie🍪の場合は4KBまで）は非推奨となっています。

## まとめ
sessionは大きな箱のようなもので、ユーザーのブラウザ内にデータを保存し、その情報を複数ページ間で共有できる仕組みということを理解することができました。
yarn での parse エラー解決方法


yarn を使ってビルドしていたら、原因不明の parse エラーに悩まされました。

結論としては、ビルド時のキャッシュがおかしくなったっぽく、キャッシュや node_module ディレクトリを削除してビルドし直せば治ります。

キャッシュを削除するって初歩的なところでしたね😅


## エラーの例

例えば [storybook](https://storybook.js.org/) を使ってプロジェクトを作っていて、いきなり以下のようなエラーに悩まされました。

ローカルでは全く問題なくビルドできていたのです。

```
[ssh@example.com]$ NODE_OPTIONS=--max_old_space_size=4096 yarn build-storybook:coding
yarn run v1.22.19
$ BASE_PATH=/storybook build-storybook -o dist/storybook
info @storybook/vue3 v6.5.10
info 
info => Cleaning outputDir: /var/www/html/dist/storybook
info => Loading presets
info => Compiling manager..
ERR! => Failed to build the manager
ERR! Cannot parse records: Unexpected end of JSON input while parsing near ''
ERR! TypeError: previewBuilder.bail is not a function
ERR!     at /var/www/html/node_modules/@storybook/core-server/dist/cjs/build-static.js:219:26
ERR!     at processTicksAndRejections (node:internal/process/task_queues:96:5)
ERR!     at async Promise.all (index 0)
ERR!     at async buildStaticStandalone (/var/www/html/node_modules/@storybook/core-server/dist/cjs/build-static.js:218:28)
ERR!     at async buildStatic (/var/www/html/node_modules/@storybook/core-server/dist/cjs/build-static.js:254:5)
ERR!  TypeError: previewBuilder.bail is not a function
ERR!     at /var/www/html/node_modules/@storybook/core-server/dist/cjs/build-static.js:219:26
ERR!     at processTicksAndRejections (node:internal/process/task_queues:96:5)
ERR!     at async Promise.all (index 0)
ERR!     at async buildStaticStandalone (/var/www/html/node_modules/@storybook/core-server/dist/cjs/build-static.js:218:28)
ERR!     at async buildStatic (/var/www/html/node_modules/@storybook/core-server/dist/cjs/build-static.js:254:5)
info => Loading presets
error Command failed with exit code 1.
```

具体的なエラーの目印は

```
ERR! Cannot parse records: Unexpected end of JSON input while parsing near ''
```

ですね。

## 対策1: キャッシュを削除

とりあえず、キャッシュ削除してみましょう。

```
npm cache clean –force
```

参考
https://www.danroo.com/web/post-666/



## 対策2: `node_modules/.cache` ディレクトリを削除

それでも改善しなかったら、物理的に削除してみましょう。

参考
https://github.com/storybookjs/storybook/issues/4034#issuecomment-780694848


## 対策3: `node_modules` ディレクトリを削除

もしかしてバージョン変更で変な状態になっているかもしれないので、`node_modules` ディレクトリも削除しましょう。


## 対策4: インストールされている node, npm などのバージョンを確認

ローカルとサーバー、パートナーで使っているバージョンが古かったりするので、アップデートしてもらいましょう。

アップデートした後は、対策1~3を繰り返して試してみます。

以上
[OCI]最新版：Autonomous Databaseでsysdate、systimestampが日本時間を返すようにする方法

# はじめに
Autonomous DatabaaseでSYSDATE_AT_DBTIMEZONEがALTER SYSTEMで設定できるようになったということで、早速試してみました。

従来はALTER SESSIONのみの対応だったため、sysdate、systimestampが日本時間を返すようにするにはログオントリガーによるALTER SESSION文の実行等が必要でしたが、今回のアップデートにより、トリガーの作成等が不要になりました。

# 1. 事前確認

dateコマンドで現在時刻を確認します。
```
[opc@tools ~]$ date
Wed Oct 12 11:01:13 JST 2022
[opc@tools ~]$
```

SQL*PlusやDatabase Actions等のクライアントからadminユーザとしてAutonomous Databaseに接続します。
```
[opc@tools ~]$ sqlplus admin/adminユーザのパスワード@adb_medium

SQL*Plus: Release 19.0.0.0.0 - Production on 水 10月 12 11:02:15 2022
Version 19.16.0.0.0

Copyright (c) 1982, 2022, Oracle.  All rights reserved.



Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.17.0.1.0
に接続されました。
SQL> 
```

sysdateとsystimestampの戻り値を確認します。
```
SQL> SELECT systimestamp FROM dual;

SYSTIMESTAMP
---------------------------------------------------------------------------
22-10-12 02:02:38.812911 +00:00

SQL> SELECT TO_CHAR(sysdate,'YYYY/MM/DD HH24:MI:SS') FROM dual;

TO_CHAR(SYSDATE,'YY
-------------------
2022/10/12 02:03:42

SQL> 
```
プロビジョニング後のデフォルトの状態のAutonomous Databaseでは、sysdate、systimestampの戻り値がUTCになっています。


# 2. sysdate、systimestampが日本時間を返すようにするための設定
ALTER DATABASE SET TIME_ZONE文で、Autonomous Databaseのタイムゾーンを日本のタイムゾーン（+9:00）に設定します。
```
SQL> ALTER DATABASE SET TIME_ZONE='+09:00';

データベースが変更されました。

SQL> 
```

ALTER SYSTEM SET SYSDATE_AT_DBTIMEZONE文でSYSDATE_AT_DBTIMEZONEパラメータをTRUEに設定します。
この設定により、Autonomous Databaseがsysdateとsystimestampをデータベースのタイムゾーンで返すようになります。
```
SQL> ALTER SYSTEM SET SYSDATE_AT_DBTIMEZONE=TRUE;

システムが変更されました。

SQL> 
```

SQL*Plusを終了します。
```
SQL> exit
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.17.0.1.0との接続が切断されました。
[opc@tools ~]$ 
```

設定を反映するために、Autonomous Databaseを再起動します。


# 3. 動作確認
再度、現在時刻を確認します。

```
[opc@tools ~]$ date
Wed Oct 12 11:07:37 JST 2022
[opc@tools ~]$ 
```

SQL*PlusやDatabase Actions等のクライアントからAutonomous Databaseに接続します。
```
[opc@tools ~]$ sqlplus admin/adminユーザのパスワード@adb_medium

SQL*Plus: Release 19.0.0.0.0 - Production on 水 10月 12 11:07:41 2022
Version 19.16.0.0.0

Copyright (c) 1982, 2022, Oracle.  All rights reserved.

最終正常ログイン時間: 水 10月 12 2022 11:07:01 +09:00


Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.17.0.1.0
に接続されました。
SQL> 
```

改めて、sysdateとsystimestampの戻り値を確認します。
```
SQL> SELECT systimestamp FROM dual;

SYSTIMESTAMP
---------------------------------------------------------------------------
22-10-12 11:07:48.582872 +09:00

SQL> SELECT TO_CHAR(sysdate,'YYYY/MM/DD HH24:MI:SS') FROM dual;

TO_CHAR(SYSDATE,'YY
-------------------
2022/10/12 11:07:53

SQL>
```
sysdate、systimestampの戻り値が日本時間になっていることが確認できました。
ActiveRecord  命名規則

rails c を行い、コンソールでモデル名.createでテーブルに保存がされていました。

```
2.3.0 :001> Blog.create(title: 'タイトルA', content: '内容A')
   (0.2ms)BEGIN
SQL (0.8ms)INSERTINTO "blogs" ("title", "content", "created_at", "updated_at")VALUES ($1, $2, $3, $4) RETURNING "id"  [["title", "タイトルA"], ["content", "内容A"], ["created_at", "2017-07-17 05:44:06.209381"], ["updated_at", "2017-07-17 05:44:06.209381"]]
   (3.0ms)COMMIT
=>#<Blog id: 1, title: "タイトルA", content: "内容A", created_at: "2017-07-17 05:44:06", updated_at: "2017-07-17 05:44:06">
```
Blog.create(title: 'タイトルA', content: '内容A')をすると、
上記を見ると自動的に事前に作った、blogsテーブルに保存がされています。
モデル名（Blog）とテーブル名（blogs）が微妙に違うのになぜ保存されるのだろうと思いました。
調べたところ、railsの命名規則に基づいて、テーブル名等を作ることによって、
railsが保存先を判断してくれるそうです。
命名規則の理由がわかりました。
SQLのデータ抽出 GROUP BY

GROUP BYの意味がわからなかったです。（以下のコマンド）
```
SELECT divisions.division_name,COUNT(*) FROM divisions 
JOIN members ON divisions.division_id = members.division_id 
GROUP BY divisions.division_name,divisions.division_id 
ORDER BY divisions.division_id ASC;
```
自分には以下の疑問が出ました。
①GROUP BY divisions.division_name,divisions.division_id でなぜ二つ指定するんだろう？
②SELECTにdivisions.division_id がなくてもGROUP BY にdivisions.division_id を指定していいのか？
③SELECTにdivisions.division_id がなくてもORDER BY にdivisions.division_id を指定していいのか？

自分の理解では以下のようになっています。

①について、ORDER BY divisions.division_id ASC;の並びにするためにはGROUP BYでdivisions.division_idの指定が必要。

②について、SELECTになくても、GROUP BY にdivisions.division_id を指定してOK。
二つ指定することによって、二つの値を持つ、一つの組み合わせができるイメージ。（詳細は後述します。）
　
③について、SELECTになくても、ORDER BY にdivision_id を指定してOK。GROUP BY にdivisions.division_id を指定しているため、使用することができる。

②の後述
division.csv
```
101 ,営業部
102 ,人事部
103 ,システム部
104 ,総務部
104 ,人事部
```
上記ファイルを GROUP BY division_id,division_nameで指定すると
結果は以下のようになります。

#実行したコマンドです。
```
SELECT division_name,COUNT(*) FROM divisions GROUP BY division_id,division_name ORDER BY division_id ASC;
```
```
 division_name | count 
---------------+-------
 営業部        |     1
 人事部        |     1
 システム部    |     1
 人事部        |     1
 総務部        |     1
(5 rows)
```
102 ,人事部　と　104 ,人事部の組み合わせがGROUP BYで登録してあるため、
項目として人事部が二つあります。
人事部としてまとめて表示されそうですが、これは102 ,人事部と　104 ,人事部という
組み合わせが一つずつ登録されているため上記のようになります。

逆にGROUP BY にdivisions.division_id を指定していないと、以下のようになります。
```
#実行したコマンドです。
SELECT division_name,COUNT(*) FROM divisions GROUP BY division_name;
```
```
division_name | count 
---------------+-------
 総務部        |     1
 人事部        |     2
 システム部    |     1
 営業部        |     1
(4 rows)
```
人事部が２になり、division_nameごとに集計されています。

以上で説明を終わります。
Python最適化モデルでコスパの良いクリスマスデートをシミュレートしてみよう

---
Python最適化モデルでコスパの良いクリスマスデートをシミュレートする
---
#### Pythonで最適化モデルを作成して安近短なデートプランをシミュレートしてみよう。

##### 目的  
あまりお金と時間をかけずに楽しいデートにしたい。
##### 条件 
予算：月末で給料前なので５０００円まで。
所要時間：平日で翌日も朝早いので７時待合わせなら１２時まで。
コース：出来れば自宅マンションでクッキングデートが安近短で良い。
##### 参考データ
##### [政府統計e-Stat](https://www.e-stat.go.jp/stat-search/file-download?statInfId=000031654490&fileKind=0) 曜日,男女,ライフステージ,一緒にいた人,時刻区分別行動者率
この統計データから人気のコースを集約し、さらに経験則から時間当たりのコストや所要時間を加えて以下の表をCSV形式で作ってみた。
ninki 月２～３回はするという女性の人数（単位千）
jikan、cost　普通にかかる所要時間と予算（￥/ｈ）を経験則で付加
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348536/ea4108d7-9f4d-ee09-ef85-c648e23a48a2.png)
これをpandasでDataFrameとして取得し最適化モデルに組込む。
尚、ninkiについては数値として多少を計るよりも特徴量としてbinningしてカテゴリ変数として扱った。

```python
import pandas as pd
from pulp import LpVariable,LpStatus,value
from ortoolpy import model_min

syuko = pd.read_csv('C:\StaticData\syuko.csv',index_col='estat')
ninki = []
syumi = []
for i in syuko.columns:
    ninki.append(syuko.iloc[0][i])
# binning
bin=pd.cut(ninki,3,labels=False,precision=0,duplicates='drop')+1
syumi=list(syuko.columns)
dic = dict(zip(syumi,bin))
```
さて最適化モデルの作成に入ろう。
変数x,y,zをそれぞれ映画、カラオケ、クッキングをした場合の予定時間とする。
クッキングをメインにしたいので変数Zを多めにしてみよう。

```python
# 最小化モデル定義
mod = model_min()

# 変数設定
x=LpVariable('x',lowBound=0)
y=LpVariable('y',lowBound=0)
z=LpVariable('z',lowBound=0)

# 目的関数設定
mod += syuko.iloc[2][0]*x + syuko.iloc[2][1]*y + syuko.iloc[2][2]*z

# 制約条件
mod += x + y <= 3
mod += y + z >= 3.5
mod += z + x >= 4
mod += x + y + z <= 5

# ソルバー実行
mod.solve()
mst = mod.status
st = LpStatus[mst]
```
制約条件を色々変えてみてLpStatusからOptimalが返されたら最適解が得られたという事だ。なのでシミュレータとして使ってみても面白い。
因みに
Infensible　が返されれば実行不可能
Unbounded　なら非有界（無制限で最適解を良く出来る）
Optimal　なら最適解のコストと所要時間の組合せを出力する。

```python
# 最適解出力
if st=='Optimal' and value(mod.objective) < 5000:
    print("最適予算 " + str(value(mod.objective))+" 円")
    plist=[]
    con=0
    for k,v in dic.items():
        print(k,"お薦め度",v," 効率的所要時間",value(mod.variables()[con]),"h")
        con += 1
```
***出力結果***

:::note info
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348536/de4812be-ad6e-b9a1-0cd7-e2dfc5d5cec1.png)
:::
やった、クッキングなら自宅マンションで４時間、３,３２０円で済みそうだ！
（そんな上手くいくか。。）
ffmpegを極めてみる

授業の資料に使う、ショート動画の切り抜きにffmpegを使ってみた

今回の要求の内容としては、
* フォルダ内の動画をまとめて変換
* 冒頭n秒をカットする
* 画面の上下n pxをクロップ

といった内容。

画面録画でUnityの作業動画動画を作ってもらったのだが、
メニューバーや、録画スタートのアニメーションがポイントで入ってしまっており、
それらを除去するためにffmpegを使った次第。

しかし、ひとつのファイルを処理するのではなく、フォルダ内の全てのファイルに処理をかけるということで、forの知識が必要に。
ここが一番手こずったという…

ひとまず参考にした記事は以下の内容。

【各要件参考記事】
カット
https://nico-lab.net/cutting_ffmpeg/

クロップ参考記事
https://w.atwiki.jp/kobapan/pages/173.html

## 冒頭n秒をカットする
録画スタートのアニメーションをカットするために、
冒頭から数秒をカットして書き出すという処理を最初に手をつけた。
これは、アニメーションをカットしてから作業を始めているという前提があったので、
一括で処理できた＆助かった。

```zsh
for var in `ls *.mp4`
do
 ffmpeg -ss 00:00:06.50 -i $var -c copy re$var
done
```


時間の指定は、整数を渡してもいいのですが、6.5秒的な書き方はできないので、
小数点を使って秒指定をしたければ、`hh:mm:ss`で書いてしまうのがベストかなと。


## 画面の上下n pxをクロップ
作成してもらった動画の上下に、メニューやヘッダーの情報が出てしまっていたので、それらをカットするために以下の処理を施しました。

```zsh
for var in `ls *.mp4`
do
 ffmpeg -i $var -vf crop=1280:645:0:36 re$var
done
```


書き方としては、左上から36px下がった位置から、1280:645のサイズで切り出してくれという指示になります。
元の画像は1280:720になりますので、ヘッダー分39pxは切り捨てた形になります。

## 作業時のコツ
指定位置をおおよそ決めてしまい、微調整を作業戻して繰り返すというのが手早かったです。
当たりをつけるためにおおよその数値で繰り返してもいいのですが、結構予想を反する数値になっているので、小さいところから細かく指定していくのが自分にはあってました。
あとは、まとめて複数ファイルでテストしていると時間がかかるので、必ずひとつのファイルでテストするようには気をつけたいところです(開始30分後で気づいた)
TerraformからECSへDockerイメージをデプロイする

---
#### TerraformからAWS CodePipelineでECSへDockerイメージをデプロイする。
---
```python
variable "github_token" {}

resource "aws_codepipeline" "example" {
  name     = "example"
  role_arn = module.codepipeline_role.iam_role_arn

  stage {
    name = "Source"

    action {
      name             = "Source"
      category         = "Source"
      owner            = "ThirdParty"
      provider         = "GitHub"
      version          = 1
      output_artifacts = ["Source"]

      configuration = {
        Owner                = "your-github-name"
        Repo                 = "your-repository"
        Branch               = "master"
        PollForSourceChanges = false
        OAuthToken           = var.github_token
      }
    }
  }

  stage {
    name = "Build"

    action {
      name             = "Build"
      category         = "Build"
      owner            = "AWS"
      provider         = "CodeBuild"
      version          = 1
      input_artifacts  = ["Source"]
      output_artifacts = ["Build"]

      configuration = {
        ProjectName = aws_codebuild_project.example.id
      }
    }
  }

  stage {
    name = "Deploy"

    action {
      name            = "Deploy"
      category        = "Deploy"
      owner           = "AWS"
      provider        = "ECS"
      version         = 1
      input_artifacts = ["Build"]

      configuration = {
        ClusterName = aws_ecs_cluster.example.name
        ServiceName = aws_ecs_service.example.name
        FileName    = "imagedefinitions.json"
      }
    }
  }

  artifact_store {
    location = aws_s3_bucket.artifact.id
    type     = "S3"
  }
}
```
配列の値　入れ替える

配列の値を入れ替える式が理解できませんでした。
```
numbers[indexMin], numbers[i] = numbers[i], numbers[indexMin]
```
この式はnumbers[indexMin]とnumbers[i]を入れ替えています。
値を入れ替える方法は
```
x = numbers[indexMin]
numbers[indexMin] = numbers[i]
numbers[i] = x
```
上記のような形しか思いつきませんでしたが、
このような方法があると初めて知りました。
サイコロをpythonで作ろう！（python初心者向けシリーズ①）

python初心者向けシリーズ①
｜サイコロを作ってみよう｜
ーーーーーーーーーーーーー

サイコロを作るには何が必要でしょう？

１〜６（通常サイコロ）の数字と、サイコロを振ること。

数を用意するのは簡単なので…サイコロを振るのをこれで出しましょう。

import random

a = random.randint(1,6)←ここの数を変えるとサイコロの目を変えられます
aは英数字ならなにを入れても構いません。
これを関数と言います。

サイコロだけではなくおみくじを作ったり、ランダムが必要であればランダム関数を使えます。

<h4>まとめ</h4>

```python3
import random
dise = random.randint(1,6)
print("サイコロ")
```

random,randinはそれ以外にも
random.random() ：0から1までのランダムな数値を出力する。（小数点だからね？？）
random.randint(a, b) ：aからbまでの間のランダムな整数を出力する
という種類があります。



それではまた別の記事でお会いしましょう。
【SQL】テーブル結合 JOIN の条件絞り込み

SQLのテーブル結合で考え違いをしていたことが発覚したので、記録しておきます。

###### 前提１：下記のような２つのテーブルＡ、Ｂを結合して全ての売り上げデータを表示させたい、とします。

###### 前提２：両テーブルの　flgカラム が  0（有効)のデータだけに絞り込みたい、とします。

【テーブル名：Ａ（売上トランザクション）】
|`flg` |`date`    |`code`|`suryo`|
|---------|-----------|----------|------|
|1        |2022/02/01 |A001      |5     |
|0        |2022/02/01 |A001      |6     |
|0        |2022/02/05 |A003      |3     |
|0　      |2022/02/10 |A003      |4     ||
<br>

【テーブル名：Ｂ（商品マスター）】
|`flg` |`code`|`name`|`price`|
|-----------|---------|--------|-----|
|0          |A001     |りんご  |150  |
|0          |A002　   |みかん  |60   |
|0          |A003     |ぶどう  |300  |
|1　        |A003     |ぶどう  |350  ||


**誤）**
Ｂテーブルを flg='0'で絞った後にＡテーブルと連結したい、思ってこんな記述をしていた。
```ruby:test.sql
select * from A 
left join B 
on (A.code = B.code) and (B.flg = '0')
where A.flg = 0
```
:::note alert
両テーブルの主キーはcodeとflg。そこを認識していなかった。
:::
　↓　↓　↓　↓　↓　↓　↓　↓　↓
<br>

**正）**
```ruby:test.sql
select * from A 
left join B 
on (A.flg = B.flg) and (A.code = B.code)
where A.flg = 0
```


###### ＜結果＞
|`A.flg` |`A.date`|`A.code`|`A.suryo`|`B.flg`|`B.code`|`B.name`|`B.price`|
|-----------|---------|--------|-----|-----|-----|-----|-----|
|0        |2022/02/01 |A001      |6     |0|A001|りんご|150|
|0        |2022/02/05 |A003      |3     |0|A003|ぶどう|300|
|0　      |2022/02/10 |A003      |4     |0|A003|ぶどう|300||



#### ＜ポイント＞

:::note info
on句には、<font color="#1e90ff">**レコードを一意に特定する主キー**</font>　を設定する。
:::
:::note info
<font color="#1e90ff">**結合してから**</font>　where句で　A.flg = 0　とすればいい。
:::


<br>


# 結合前にレコードを絞りたい場合は

<font color="red">Join (select* from Table where XX=AA) as TB</font>
と言うように、Select文をもう１つ記載して結合する方がわかりやすい。

```ruby:test.sql
select * from A 
left join (select * from B where price = 150) as B2 
on (A.flg = B2.flg) and (A.code = B2.code)
where A.flg = 0
```
サブディレクトリからサブドメインに301リダイレクト

初めてQiitaに記事を書きます。
Qiitaはプログラムなど理系の話題が中心のブログ。

バリバリ文系の私が書けるのは、自分の経験した内容くらい。
なのでサイトの操作やSEOに関する覚え書きを書こうと思います。

今回は301リダイレクトについて。

サブディレクトリで運用していたカテゴリをサブドメインに変更しました。


旧：https://kyoka-ok.com/marriage-visa/


新：https://marriage.kyoka-ok.com/


Qiitaの仕様上、URLは自動的にリンクされるようです。
見本用に書いたURLは先頭部分の「ｈ」を外しました。


大元のドメインは建設業関連です。
サブディレクトリで運用していたサイトは配偶者ビザ。

最近のSEOはサブディレクトリが良いと聞いており、配偶者ビザのサイトをディレクトリで運用。
考えてみると、建設業関係のサイトに在留資格はないだろうと思いました。

そこで配偶者ビザのサイトをサブドメインに移動させました。

ちなみに私が使用するCMSはSIRIUS2と言う静的サイトを作成するものです。
Wordpressの場合とは勝手が違うかもです。
（Wordpressだと下記のコードでログイン出来なくなったとあった）

SIRIUS2では、上手くいけました。


サブディレクトリからサブドメインに変更した時に使ったコードを書き残します。

```ruby:qiita.rb
'Redirect permanent /元のディレクトリ/ https://新しいサイト.com/'

実際に使ったコードは以下のような物になります。

'Redirect permanent /marriage-visa/ https://marriage.kyoka-ok.com/'

```

リダイレクトとは、新しいドメインに変更した際に旧ドメインから新ドメインに転送する為に使うものです。

リダイレクトを使用すると以前のURLの評価を引き継ぐことが可能です。

リダイレクトにも種類があり、301と呼ばれる物は永久にサイトを変更する時に使用します。

一時的なURLの変更（メンテナンスなど）は302リダイレクトを使います。

やり方は複数ある様ですが、
一般的にはサイトを格納するサーバー（ロリポップなど）内に特定のコードを入力するやり方になります。

サーバー内に「htaccess」と言うテキストファイルを作成して、その中にコードを入力します。

SIRIUS2の場合は、ツール内に「htaccess」の記述欄があります。
そこに記入してFTPでアップロードしました。

リダイレクトの経過やSEO上の変化については、データが揃ってから投稿しようと思います。
PostgreSQLの情報スキーマ、システムカタログ

# 要点
|情報スキーマ|システムカタログ|
|-|-|
|スキーマのこと|pg_catalogスキーマに含まれるテーブルのこと|
|誰でも参照可能（権限不要）|誰でも参照可能（権限不要）|
|簡単な情報を格納する|詳細な情報を格納する|
|初期のDBユーザに所有される||
|SQL標準規格に当てはまるので移植性が高い|PostgreSQL特有のものなので移植性が低い|
|主なテーブルはtables|主なテーブルは5つ（そのうち3つがＤＢクラスタ全体の情報を格納している）|

※実際は、両者それぞれinformation_schema, pg_catalogスキーマに含まれる**テーブル**を用いる
※おそらく、誰でもテーブルの内容を参照、更新することができる

# 情報スキーマ
- データベースオブジェクトに関する定義情報を含む**スキーマ**。
- 主なテーブルとして、tablesを持つ。
- 取得される情報は、システムカタログよりも簡単なもの

|特徴|
|-|
|スキーマ名は、information_schema|
|SQLの標準規格に当てはまるので、移植性が高い|
|ビュー(SQL文のSELECT結果を基にして定義する仮想のテーブル)とテーブルのグループである|
|データベースクラスタの作成時に作られたスーパーユーザに所有される|
|参照に特別な設定や権限は不要である|


|【information_schemaの主なテーブル】|説明|
|-|-|
| tables|publicスキーマ内を含む、全てのテーブルとビューの一覧を格納している。|

```:実行例
testdb=# SELECT * FROM information_schema.tables;

-- publicスキーマ内を含む、全てのテーブルとビューの一覧が表示される --
```

# システムカタログ
- データベースの内部情報を格納したPostgreSQL固有の**テーブル**。(スキーマではない)
- システムカタログは、pg_catalogというスキーマ内に格納されている。

|特徴|
|-|
|スキーマの名称は「pg_catalog」である （暗黙的に必ず検索パスに含まれるため、スキーマの指定は省略することができる） |
|SQLの標準規格には当てはまらないので、移植性が低い|
|情報スキーマより詳細な情報を確認する際に使用する|
|データベースクラスタの管理に関する情報を含む|

|【PostgreSQLの主なシステムカタログ】|説明|
|-|-|
|pg_tables|接続しているDB内のテーブルに関する情報を格納している|
|pg_indexes|接続指定しているDB内のインデックスに関する情報を格納している|
|pg_database|DBクラスタ全体のDBに関する情報を格納している|
|pg_user|DBクラスタ全体のユーザに関する情報を格納している|
|pg_authid|DBクラスタ全体のロールに関するパスワードなども含めた情報を格納している|

※**pg_database, pg_user, pg_authid**の3つは、DBクラスタ全体の情報を格納している


```:実行例
testdb=# SELECT * FROM pg_tables;

-- 接続中のDB(testdb)に含まれるテーブルの一覧が表示される --
```
TerraformからECSへDockerイメージをデプロイする

---
###TerraformからAWS CodePipelineでECSへDockerイメージをデプロイする。
---
```python
variable "github_token" {}

resource "aws_codepipeline" "example" {
  name     = "example"
  role_arn = module.codepipeline_role.iam_role_arn

  stage {
    name = "Source"

    action {
      name             = "Source"
      category         = "Source"
      owner            = "ThirdParty"
      provider         = "GitHub"
      version          = 1
      output_artifacts = ["Source"]

      configuration = {
        Owner                = "your-github-name"
        Repo                 = "your-repository"
        Branch               = "master"
        PollForSourceChanges = false
        OAuthToken           = var.github_token
      }
    }
  }

  stage {
    name = "Build"

    action {
      name             = "Build"
      category         = "Build"
      owner            = "AWS"
      provider         = "CodeBuild"
      version          = 1
      input_artifacts  = ["Source"]
      output_artifacts = ["Build"]

      configuration = {
        ProjectName = aws_codebuild_project.example.id
      }
    }
  }

  stage {
    name = "Deploy"

    action {
      name            = "Deploy"
      category        = "Deploy"
      owner           = "AWS"
      provider        = "ECS"
      version         = 1
      input_artifacts = ["Build"]

      configuration = {
        ClusterName = aws_ecs_cluster.example.name
        ServiceName = aws_ecs_service.example.name
        FileName    = "imagedefinitions.json"
      }
    }
  }

  artifact_store {
    location = aws_s3_bucket.artifact.id
    type     = "S3"
  }
}
```python
MS「ごめん、CS1963って何？」

# CS1963 "An expression tree may not contain a dynamic operation"

## 式ツリーに動的な動作を含めることはできません

ぼく「今日も楽しくASP.NET Core！」  
ぼく「**"式ツリーに動的な動作を含めることはできません"** って怒られてコンパイル通らないけど」  
ぼく「どんなエラーなんだろう？日本語がふにゃふにゃでよくわからないし、MSに聞くか」  
ぼく「Visual Studioなら、エラーを[クリックして飛べる](https://msdn.microsoft.com/query/roslyn.query?appId=roslyn&k=k(CS1963))から楽ちん！」

MS「**Sorry, we don't have specifics on this C# error**」  
MS「うちのフォーラムで聞いて💛」
MS「stack overflowでもいいよ💛」

ぼく「？？？？？？？？？？？？？？？？？？」

## 導入終わり

当然のようにMSのフォーラムではなにも出てこなかったので、
なぜこのようなエラーが発生したのか、どうすれば回避できるのかを調べてみました。  
間違い、勘違いなどありましたらコメントで指摘をお願いします🙇

※コメント欄で指摘がありました。そもそもViewBagの使い方を勘違いしているよとのことです。
やっぱり勘違いしているじゃないか！
本題のエラー周りは違わないので変更はしていませんが、このコードみたいなViewBagの使い方は
やめましょう。。。

## 発生原因

**式ツリーの中で動的な何かを使用した場合**に発生するエラーです。
式ツリーとは、C#では主にラムダ式などで用いられている、Func型のことです（違うかも）。
以下の私が書いたコードでは、MVCのView部でエラーを吐いています。

``` HTML
@model IEnumerable<HogeProject.Models.Person>

@foreach (var item in ViewBag.SearchResult) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.name) <!-- item.nameでエラーを吐く -->
        </td>
        <!-- 以下ほかのデータが続く -->
    </tr>
}
```

ここでViewBag.SearchResultは、controllerがmodelをよしなに処理したデータが入っています。
modelから検索条件に一致したデータのみを抽出し、抽出したデータを配列に処理しています。
modelにはnameが含まれているので、私はitem.nameでmodelから該当データのnameを取得できることを期待していました。

ですが、ここでのViewBag.SearchResultはコンパイル時点では型が分かりません。
実際に処理が行われ、controllerから実体が渡されることで初めて型が分かります。
そういう型を、C#ではdynamic型としてコンパイルします。
さらに、元データViewBag.SearchResultがdynamicなので、**varで宣言した**itemの型もわかりません。
TModelという、**何らかのmodelである**という情報のみを持つクラスになってしまいます。
そして、このTModelは**動的な型**です。

ここで当初のエラー文を思い出してみてください。
**式ツリーに動的な動作を含めることはできません**
ラムダ式という**式ツリー**の中で、TModelという動的な型を使用しようとしました。
DisplayForの期待する式ツリーは、``Func<TModel, TResult>``で、この``TResult``は``TModel``を式ツリーの記述に沿って展開したものであることが期待されています。
Html.DisplayForの**書き方をミスっている**ため、``TModel``が``IEnumerable<HogeProject.Models.Person>``だと勘違いされているので、変換がうまく決まりません。
そのため、最後までitemの型がよくわからないままに、コンパイラが解析に失敗します。
式ツリーは動的な型を元に作成できないというルールがあるので、はじめのエラーが返ってきます。

## 解決方法

このエラーに対する解決法は、varをやめて、型を明示的に宣言してしまうことです。

``` HTML
@model IEnumerable<HogeProject.Models.Person>

@foreach (Person item in ViewBag.SearchResult) { <!-- ここでPersonと宣言 -->
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.name)
        </td>
        <!-- 以下ほかのデータが続く -->
    </tr>
}
```

すると、itemの型が動的に変更されなくなるので、このエラーは消えます。

このコードに関していえば、以下のように修正することもできます。

``` HTML
@model HogeProject.Models.Person <!-- ここで正しい型を宣言 -->

@foreach (var item in ViewBag.SearchResult) { <!-- ここはvarのまま -->
    <tr>
        <td>
            @Html.DisplayFor(item => item.name) <!-- item => item.nameに変更 -->
        </td>
        <!-- 以下ほかのデータが続く -->
    </tr>
}
```

DisplayFor内のラムダ式の左辺は、``@model``で宣言した型を参照します。
そのため、**itemもその型であることが期待**されます。
結果として、静的な型扱いをされます。

## まとめ

いかがでしたか（テンプレ）？
MSのサイトに行ってもエラー解説がないこと、まれによくあることみたいですね。
今回は、Qiitaでこの件に関する記事がなかったので投稿してみました。
誰かの助けになれればうれしいです。
WindowsのVScodeでCoqを使う（初心者向け）

## 実行時期
2022年10月11日

## 環境
Windows11
VSCodeインストール済み

## 導入手順

1. 下記にアクセス
https://github.com/coq/platform/releases/tag/2022.04.1

2. 以下のような画面でWindows(64bit)を選択してインストーラ（Coq-Platform-release-2022.04.1-version_8.15_2022.04-arch-x86_64_signed　みたいな感じの名前のexeファイル）をダウンロード。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/881013/597ca08f-9185-5e49-5816-43e6b5f59bb4.png)

3. ダウンロードしたインストーラを起動し、インストールを行う。（設定等はデフォルトでOK）

4. 3.でインストールしたフォルダ（Coq-platform-...）にアクセス

5. 「bin」フォルダを右クリック→「パスのコピー」をして、メモ帳など適当なテキストエディタに貼り付けておく。

6. Windowsキーを押して出てくる検索ボックスに、「システム環境変数の編集」と入力して出てきた結果を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/881013/e494cb17-c9fe-cd8b-672a-84a269b6df06.png)

7. 右下の「環境変数」を選択。

8. 「システム環境変数」の「変数」が"Path"となっている行を選択し、「編集」を選択

9. 「新規」を選択し、5.で貼り付けておいたパスをコピーする。（両端のダブルクォーテーションは不要）
    デフォルトでは　C:\Coq-Platform~8.15~2022.04\bin　のような感じ（数字部分はバージョンにより変化）

10. 「OK」→「OK」→「適用」を順に選択してウィンドウを閉じる。

11. PCを再起動する

12. VScodeを起動する

13. 左側のメニュー（またはCtrl+Shift+X）で拡張機能を開く。

14. 検索ボックスに「vscoq」と入力し、vscoqをインストール。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/881013/c5b4cd84-9f95-1c34-766b-49afc8a1cd55.png)

## 使用方法

|操作内容|操作方法|
|---|---|
|１つ進む|Alt+↓|
|１つ戻る|Alt+↑|
|カーソルまで動く|Alt+→|
|最後まで進む|Alt+End|
|最初まで戻る|Alt+Home|
Pythonの基礎知識（第一回の授業で自分が書いたノート）

# 関数
Pythonにはさまざまな関数が存在する。
例）
print()　⇨()内に入れたものをターミナルに出力する関数
len()　⇨()内に入れたものの文字数や要素数を数える関数
関数＝便利なプログラム

# print()について
printは、出力と改行の意味を持つ
## 改行を消したい場合...
⇨endに『空文字("")』を入れる
```Python
print("ハローワールド",end="")
```
AppStoreのios証明書の更新について

# 概要
iOS Distribution Certificate証明書は一年に一度更新する必要がある。
更新しなければ、新しいアプリケーションやアップデート版を App Store に提出することはできなくなる。

# 対応方法
以下のリンクを参考にしました
[【iOS】 Certificate証明書の更新 (現在ご利用のiOS Distribution証明書の有効期限まであと30日になりました。](https://marumaro7.hatenablog.com/entry/certificateupdate)

[[iOS] Appストアに公開したアプリの証明書の有効期限が切れたらどうなるか](https://b.0218.jp/20160905143643.html)
CHIRIMEN + Raspberry Pi 4B の環境構築の覚書

# はじめに
最近、chirimenというJavaScriptでRPiを使う機会があるので、chirimen + α の私なりの追加環境設定についての覚書です。

chirimen用のmicroSD制作とNode-REDインストールは[こちら](https://qiita.com/airpocket/items/d9b996238a14a800ecf4)に先にまとめてます。
使用するchirimenのimgは2021-08-12版です。

OSなどのバージョンはこんな感じ。
デフォルトのユーザー、パスワードは懐かしの[pi][raspberry]です。
```shell
pi@raspberrypi:~ $ lsb_release -a
No LSB modules are available.
Distributor ID:	Raspbian
Description:	Raspbian GNU/Linux 10 (buster)
Release:	10
Codename:	buster
pi@raspberrypi:~ $ node -v
v14.17.5
pi@raspberrypi:~ $ python --version
Python 2.7.16
pi@raspberrypi:~ $ python3 --version
Python 3.7.3
```
raspbianはbusterなので、pythonは2と3が両方入っているのに要注意。Node.jsはV14です。

# Raspberry Pi の設定

左上のRaspberry Piアイコンからメニューを開き、「設定」⇒「Raspberry Pi の設定」 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496179/ab8ce05b-f93a-2f1e-a775-aabfade8aef4.png)

画面の全周に黒枠が入っている場合は、「ディスプレイ」タブ⇒「オーバースキャン」を「無効」に。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496179/aa026ef6-b81a-b598-5546-4dbc9914e79a.png)

今後の操作はVNCとSSHを基本とするので、「インターフェイス」タブ⇒「SSH」「VNC」を「有効」に。他機能も必要に応じて有効にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496179/823ed750-3099-8204-2083-f7d6c633a292.png)

デフォルトユーザー「pi」とパス「raspberry」の使用は推奨されていませんが、外部に公開するつもりもない開発環境なので当面このまま進めます。

# OpenCV

RasPiを使うとき、pythonとopencv環境を作るのは
この環境では、不足するライブラリのインストールとnumpyのアップグレードが必要でした。
numpyのアップグレードは10分くらいかかったので気長に待ちましょう。

```shell
sudo pip3 install opencv-python
sudo apt-get install libatlas-base-dev
sudo pip3 install numpy --upgrade
```

以上の作業ができたら、[こちらのサイト](https://qiita.com/kakinaguru_zo/items/eda129635816ad871e9d)からコードをお借りしてUSBカメラを使ったテストをしてみます。
USBカメラをRaspberry Piにつないで、次のコードを実行してみましょう。カメラで撮影した画像（キャプチャ動画）がウィンドウに表示されれば成功です。

```python
import cv2

capture = cv2.VideoCapture(0)
if capture.isOpened() is False:
  raise IOError

while(True):
  try:
    ret, frame = capture.read()
    if ret is False:
      raise IOError
    cv2.imshow('frame',frame)
    cv2.waitKey(1)
  except KeyboardInterrupt:
    # 終わるときは CTRL + C を押す
    break

capture.release()
cv2.destroyAllWindows()
```

実行するには、上のコードを「cameraTest.py」などのファイル名で保存し、ターミナルを使って「python3 cameraTest.py」として実行します。

#まとめ
この記事は、開発中に新たな設定やモジュールのインストールが必要になった際に随時加筆修正します。
EC2の終了忘れを防ぐ起動スクリプト

# これは

「あ、EC2消し忘れた。。」
「むしろ、ちゃんと止めたことない。。」
「お金が。。」
「高額インスタンスで。。。」

EC2を一定時間でシャットダウンする方法です。

`EC2` の `ユーザデータ` という機能を使います。

## 参考

- [起動時に Linux インスタンスでコマンドを実行する - Amazon Elastic Compute Cloud](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/user-data.html)
- [【Ubuntu】シャットダウン、再起動コマンド | PostgresWeb - ポスグレウェブ](https://postgresweb.com/ubuntu-shutdown-reboot-command)

## 作業の流れ

1. EC2インスタンスを停止する
1. ユーザーデータを設定する
1. EC2を起動する
1. 仕事する
1. 仕事終わる
1. EC2の停止を忘れる
1. 自動終了する


# ユーザーデータを設定する

[EC2 インスタンスの初回起動後にユーザーデータを実行する](https://aws.amazon.com/jp/premiumsupport/knowledge-center/execute-user-data-ec2/)

EC2 コンソールからインスタンスに対して以下の操作をしてください

 - [Actions] (アクション)、[Instance Settings] (インスタンスの設定)、[Edit User Data] (ユーザーデータの編集) の順に選択します。

 - ユーザースクリプトを [Edit user data] (ユーザーデータの編集) ボックスにコピーして、[Save] (保存) を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62413/ea907513-d946-6d86-9fb2-31897b6eb9c2.png)


ユーザデータに以下を書き込む

```sh
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [scripts-user, always]

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash
sudo shutdown -h +300 # <- ここに自分の命令を入れておくだけ
--//--
```

## 実行結果

起動後3分でシャットダウンを指定した例



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62413/1507bc35-2289-afeb-82d0-181c6886bbb2.png)

起動後、シャットダウン時刻が近づくと、そろそろ落ちるとメッセージが表示されて便利。


## キャンセルする場合

もっと仕事頑張りたい時は、再設定ください

```sh
# キャンセル
$ shutdown -c

# 再設定
$ sudo shutdown -h +120
```


終わり
Ubuntu 20.04 Wi-Fiが使えない & トップバーからアイコンが消えたら

# 環境
- Ubuntu 20.04（Windows 11 Homeとデュアルブート）
- GIGABYTE AORUS 15P KC

# 状況
主にdocker上での開発に使用しているPC（普段は有線LAN接続で使用）で、無線LANが使えなくなっていました。
どのタイミングで使用できなくなったかは不明です。
主症状は以下の通りです。

- 画面右上に表示されるWi-Fiマーク（扇形）が表示されない
- 設定画面左側の項目一覧の一番上が「ネットワーク」になっており、「Wi-Fi」のタブがない
- ```nmcli devive wifi```で何も表示されない
など。


# 対処法（の一例？）
以下を片っ端から試したら治りました。どれが決定的だったのかは微妙ですが、おそらくbcmwl-kernel-sourceのインストールと思われます...?

**追記：これでダメな場合もありました。最下項もご覧ください。**

以下を実行。
```
sudo apt update && sudo apt upgrade
sudo apt-get install -y bcmwl-kernel-source
sudo reboot
```
これだけでは治らず、以下を数回繰り返しました。
- Ubuntuをリカバリーモードで起動
- メニューに示された選択肢を片っ端から実行（余計なものを消したり修復してくれたり...?）
- resumeする（文鎮化して起動してくれなかったので、物理ボタンで強制シャットダウンしました）

その後、他のユーザでログインしたらWi-Fiが復活しており、自分のアカウントにログインしたら嘘のようにWi-Fiが使えるようになっていました。

まだまだ素人なので、ご指摘等いただければ幸いです。


# 追記
同じ症状が数日起きに発生しており、上記を実行しても治らない場合があります。
直近としては
- WindowsでWi-Fiのパスワード再入力を求められたとき
- 一晩放置したとき
にUbuntuでのWi-Fi接続が復活しました。
新しいことがわかったらまたここに追記しようと思います。