OmniAICreator/Qiita-1.07M huggingface dataset:
Lambda→SNS→Chatbot→Slackへの通知がうまくいかない

## はじめに
Lambdaで取得した内容をSlackへ通知させようとしたときの話です。
以前、CloudWatchアラームをSlackへ通知させるために「SNS→Chatbot→Slack」の構成で実装した経験があったため、今回もその構成を使用したのですが、Slackへ通知されない、エラーも出ない、という状況に陥りました。

## 原因
原因調査のために色々と調べていたところ、こちらの記事を発見しました。

* [Amazon SNS から AWS Chatbot を経由した通知がうまくいかない原因と対処方法](https://dev.classmethod.jp/articles/tsnote-support-chatbot-launch-001/)

Chatbotは、[ドキュメント](https://docs.aws.amazon.com/chatbot/latest/adminguide/related-services.html)に記載しているサービスからの通知のみサポートしているとのことで、Lambdaがそのサービスの中にないことが原因と判断しました。

## 対処方法
今回は、「SNS→Chatbot」を使用せずに、SlackのWebhookを使用することにしました。
下記の記事を参考にさせていただきました。
* [Lambda で Python を使って、Slack に通知するハンズオンを勝手に作ってみた](https://zenn.dev/mn87/articles/f102140a0540bf)
* [Python + AWS Lambda関数でslackに投稿する方法](https://zenn.dev/ushknn/articles/65d9560c0dad6c)
AccessのVBAでエクセルファイル内に非表示シートが存在するか判定

# 概要

Accessで外部エクセルファイルを操作する前に
『エクセルファイル内に非表示シートが存在するか』
を判定したい。

非表示シートがあると下記のような弊害がある為。

https://qiita.com/waokitsune/items/7042c47dd9484d7e6d29

# やり方

```vb:非表示シートが存在するエクセルファイルか判定
Public Function IsHideSheetExistExcelFile(ByVal excel_file_path As String) As Boolean


    Dim excel_ As New excel.Application


    'バックグラウンドで起動。
    excel_.Visible = False
    excel_.UserControl = False
    excel_.Workbooks.Open fileName:=excel_file_path
    

    '全シート走査して表示状態確認。
    'excel_.WorksheetsはFor Eachのインターフェース無いのでForでまわす必要あり。
    Dim i_ As Long
    For i_ = 1 To excel_.Worksheets.Count
        If Not excel_.Worksheets(i_).Visible Then
            IsHideSheetExistExcelFile = True
            'バックグラウンドのエクセルを閉じる必要がある為、早期リターンはしない。
        End If
    Next
    
    
    'バックグラウンド起動のエクセル終了。
    excel_.Workbooks(1).Close SaveChanges:=False
    excel_.Quit
    

End Function
```

# 蛇足

非表示シートが一つでもあれば処理させないように設計した方がいいかも。

エクセルは人が見て処理することが多い。
非表示シートがあるということはつまり、そこに記載された内容を見落とす危険がある。

# 参考サイトさん

https://kirinote.com/excelvba-hiddensheet/

# バージョン

Windows 10 Pro 22H2 OSビルド 19045.2486
Microsoft Access for Microsoft 365 MSO (バージョン 2212 ビルド 16.0.15928.20196) 32 ビット
Riderで独自の名前空間を設定したい！

# はじめに
Unityでゲーム開発する際にRiderを使うとき自動で名前空間を命名し、挿入してくれるのですがその命名がディレクトリ構造になってしまい自分がおこなっている命名規則と合わないため独自で命名する方法をまとめたモノが本記事です。
# 解決方法
自分が解決した方法を順を追って説明します。
まずは画面左上にあるプルダウンを選び ”Unity” から ”Solution” に変えましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1915044/52316a30-69ff-65c0-dbb3-731099f63bf7.png)
次に "Assembly-CSharp" というファイルを右クリックして、Project Propertiesを開きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1915044/3f363e9c-9a01-0308-5732-e84035248870.png)
開くとRoot namespaceという項目があるのでそこに自分が設定したい名前を入れてあげましょう。今回は TestNamespace という名前空間にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1915044/27d00325-3796-3a34-671e-efd0a33f32e2.png)
この状態で以下のフォルダーにあるスクリプトは、
Riderに自動命名してもらうと以下のような命名をしてくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1915044/c55ed214-b1da-84c0-ad1a-9ed6bd5b7e7e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1915044/7676f63d-dfec-268f-8cf6-8d8508a1da73.png)
ただし例えば名前空間からEnemyを消したい、MyAssetを消したい場合はもう1つ作業が必要です。まず消したいフォルダーのところで右クリックしてFolder Propertiesを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1915044/093e4260-981b-8aaf-5507-7a5f0604e0e9.png)
EditableのNamespace providerのチェックを外しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1915044/3b0c8a73-c6b4-62f0-849a-3628021757e0.png)
同様にしてEnemyフォルダーのNamespace providerのチェックを外し、自動で名前空間を命名すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1915044/d64167e6-5c17-abac-af25-8c2c86ab6806.png)

これで無事に命名できました！
フォルダーごとにNamespace providerのチェックを外す必要がありますがこれでRiderの警告なしに独自の名前空間を命名することが出来ました。

# 参考サイト
https://pleiades.io/help/rider/Refactorings__Adjust_Namespaces.html
https://unity-yuji.xyz/rider-root-namespace-settings-edit/
https://qiita.com/__poosuke/items/5a51c5673775c9b2a3f6
AccessのVBAでエクセルファイル操作時に1004エラー起きた時の対応

# 現象

外部エクセルファイルを編集する処理。
（一番左のシートの特定セルに値をセットするなど）

下記の ```excel_sheet_.Select Replace:=True```　で例外。

```vb:
Dim excel_ As New Excel.Application

'バックグラウンドでエクセルファイル開く。
excel_.Visible = False
excel_.UserControl = False
excel_.Workbooks.Open FileName:=CurrentProject.Path & "\test.xlsx"

'一番左のシートのみを選択状態に。
Dim excel_sheet_ As Excel.Worksheet
Set excel_sheet_ = excel_.Worksheets(1)
' ↓ ここで例外
excel_sheet_.Select Replace:=True

'セルに値セットするなど各種処理。

'エクセル保存して閉じる。
excel_.Workbooks(1).Close SaveChanges:=True
excel_.Quit
```

>実行時エラー1004
>Selectメソッドは失敗しました'_WorkSheet'オブジェクト

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/e2487cd3-7e11-5b1d-456b-ebdc1466112c.png)

# 原因

一番左のシートが非表示になっている為。

下記のように再表示してあげればOK。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/df7214e5-2bf8-38c5-bb9a-c5e06e8b445f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/7866cf06-17fc-e2eb-50ab-a43273643b3c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/5227e6a1-6d59-9926-2184-1474086003b0.png)

全シートが非表示になっていれば見た目で分かりやすい
でも、一部シートだけ非表示にされると分かりにくい。

# 残プロセスに注意

1. エクセルファイルをバックグラウンドで開いて処理中に例外。
1. AccessのVBE上で処理終了させる。
（ ```Quit``` を呼び出さずに、強制的に処理中断させるような形）

だと、下記のように不要プロセスが残ってしまうので注意。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/8f3a0ae7-f60a-a11c-6de3-c8e9234f5a32.png)

要はエクセルファイルが開きっぱなしの状態なので、いろいろ弊害あり。

# バージョン

Windows 10 Pro 22H2 OSビルド 19045.2486
Microsoft Access for Microsoft 365 MSO (バージョン 2212 ビルド 16.0.15928.20196) 32 ビット
Microsoft Excel for Microsoft 365 MSO (バージョン 2212 ビルド 16.0.15928.20196) 32 ビット
Google Cloud コンソールにアクセスする際に自動で会社アカウントに切り替える

## 背景

Google Chrome で Google Cloud コンソールにアクセスする場合、Chrome にログインしているアカウントが認証に使用される仕様になっています。また、必要に応じて別のアカウントを追加して、コンソール上からアカウントを切り替えることも可能になっています。

自分の場合、Chrome には個人アカウントでログインしているので、業務中に GCP プロダクトからの Slack 通知やチームメンバーに共有してもらったリンクからコンソールにアクセスすると、以下のように認証に個人アカウントが使用されて権限エラーで何も見れないので、アクセスの度に手動で会社アカウントを切り替える作業を行っていました。
![スクリーンショット 2023-01-20 16.11.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49924/60e5cb60-5d29-cd24-70a9-1d61754c9818.png)
この作業が大きなストレスだったので、このアカウント切り替えを自動化する仕組みを用意しました。

## Google Cloud コンソールの認証に使用されるユーザーについて

公式な情報ではありませんが、認証ユーザーは `authuser` というクエリパラメータによって制御されています。Chrome にログインしているアカウントは `authuser=0` と表現され、複数アカウントを追加している場合は追加した順に数値がインクリメントして表現される仕様です。

先述の画像にある会社アカウントは `authuser=1` と表現されるイメージです。つまり、自分のケースではコンソールへのリンクに `authuser=1` を付与すれば、自動で会社アカウントを切り替えることができます。

ちなみに数値の代わりに Google アカウントの ID (ログイン時のメールアドレス) を `authuser` に指定することも可能なので、この記事ではそちらの方法を採用します。

## 自動で会社アカウントに切り替える仕組みを用意する

### 1. URL を加工する Chrome 拡張をインストールする

Requestly という Chrome 拡張をインストールします。
拡張は何でも良いので、好きなものを使ってください。

https://requestly.io

### 2. Query Param Rule を追加する

以下のような Query Param Rule を追加します。
追加した後に保存や有効化も忘れずに実施してください。
![スクリーンショット 2023-01-20 16.34.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49924/af584406-d926-153d-451b-355d80d3f8f8.png)

これでコンソールにアクセスする際に自動で会社アカウントに切り替わるようになります。
`authuser` は後勝ちなので、URL に既に `authuser=0` が含まれていても自分の設定が適用されます。

## さいごに

地味な Tips ですが、有用ではあるので是非参考にしてもらえればと思います。
RSAは終わらない - RSA 7680bitのICカードの実現可能性

## はじめに
RSAは終わらないというタイトルですが筆者(Naoki Hirayama)がRSAが安全であることを保証するのではなくて既に量子コンピュータによって解読が懸念されているECDSAに移行するつもりがあるならRSAは終わらないということです。

暗号移行を促すQiita投稿 : [「RSAの終わりの始まり - 暗号移行再び」](https://qiita.com/lemiyachi/items/c20a18b172c6f192a262)
投稿者のラング・エッジ 宮地さんは、ネット上では有名な方のようです

上記、Qiita投稿ではRSA 7680bitのICカードは非実用的という評価によってECDSA(楕円曲線暗号)に移行すべきかを検討しましょうという流れになっているようなのでRSA 7680bitのICカードの実現可能性について考えてみます。

## FPGAによるRSA 2048bitの実装結果
[暗号プロセッサSnakeCubeのWebサイト](https://snakecube.idletime.tokyo/)に詳しく書かれていますがRSA 2048bitの復号化1回の性能が1.74[ms]です。これは概ねRSA署名1回の時間と同じです。

**この実装結果で使われたFPGAはXilinxのコスト重視のFPGA(Artix-7)です。さらにスピードグレードの一番遅いものなのでICカードへの実装可能性を考えるには良さそうです。** このXilinxのArtix-7シリーズは28nmの半導体です。28nmと言えば国が作ったTSMCの熊本工場の半導体と同じ。ハードをソフトウェアのように書き込めるFPGAで1.74[ms]の性能が出るのでASICで開発すれば、さらに高速に動作します。

## NAOKIの法則を使って7680bitの性能を予想
SnakeCubeは演算器ブロックを一筆書きで並べていくことで大きな鍵長に対応できて容易に開発可能です。[NAOKIの法則](https://icf.hatenablog.com/entry/2022/01/27/074607)は、僕が作った法則です。自分で言うと馬鹿っぽいですけど(笑)。**法則と言っていますけど保証できるくらいの精度です。**

このXilinx FPGA(Artix-7)に実装されたSnakeCubeでは中国人剰余定理(CRT)を使っています。しかしICカードでは中国人剰余定理の脆弱性の対策が難しいので中国人剰余定理を使わないことを考えます。
中国人剰余定理が無い場合、おおよそRSA 1024bit復号化 1.74[ms]になります

[NAOKIの法則](https://icf.hatenablog.com/entry/2022/01/27/074607)から鍵長を8倍の8192bitにすると演算時間は64倍になるので
1.74[ms] × 64 = 111.36[ms]

8192bitの演算器ですが7680bitの演算ではループ数が少なくて良いので
111.36[ms] × 7680 ÷ 8192 = 104.4 ≒ 105[ms]

## 結論
FPGAによる実機の実測値を使ってRSA 7680bit署名1回の演算時間を予想すると105[ms]の性能が出ます。ICカードはFPGAより楽なASICで実装するためRSA 7680bit署名1回の演算時間　0.1～0.2秒のICカードは実現可能であるように思われます。
[SnakeCube](https://snakecube.idletime.tokyo/)はゲート間の配線が局所化しているので高性能プロセッサにありがちな高価な配線材料は不要です。ICカード向けの安価な実装ができるように思われます。

筆者はRSA暗号の高速な演算の実装方法、つまり筆者の発明[SnakeCube](https://snakecube.idletime.tokyo/)を提案していますが、RSA暗号が解読されないということについては一切保証しないことを予めご了承下さい。

暗号プロセッサSnakeCubeはRSAほど効率良く演算できませんがECDSAも演算可能です。また巨大整数の四則演算が高速なので困難性の異なる新しい公開鍵暗号を促したり、新しいアプリでも利用できることを考えるなら暗号プロセッサSnakeCubeを、ここで開発しておくことは、良いことだと思っています。

##### 参考URL
FPGAによる実機で2048bit RSA復号化1回、1.74[ms]を記録した動画
[https://www.youtube.com/watch?v=beaFg0x8Qj8](https://www.youtube.com/watch?v=beaFg0x8Qj8)

プレスリリース、暗号プロセッサSnakeCubeをマイコンに接続できる ソフトウェア「WZeta BIOS」を5月28日に提供開始
[https://www.atpress.ne.jp/news/310208](https://www.atpress.ne.jp/news/310208)
Pythonの`with`やGolangの`defer file.Close`に似た機能

Haskellにも`withFile`が存在する。
ただし、この関数の型が独特なのでモナド変換子のスタックからでは使えない。
この場合には、 `bracket` が使える。

# 参考文献

- 問題提起
    - https://www.fpcomplete.com/blog/2016/11/covariance-contravariance/#lifting-codeiocode-to-codemonadiocode
- 解決策
    - https://www.stackage.org/haddock/lts-20.8/base-4.16.4.0/Control-Exception.html#v:bracket
clasp login --no-localhost が使えない

### clasp login --no-localhost を使いたい
docker環境でclaspを使っていたがターミナルからコマンドでログインできなくなった
シェルスクリプトでログイン処理をまとめていたのでその内容をメモ
結論から言うと、clasp login --no-localhostの代わりにclasp loginを実行してブラウザで表示されるURLにcurlでアクセスするとログインできます
同じ環境のターミナルを別に開く必要があります
面倒臭いです
### 該当するソースコード
```bash
clasp login --no-localhost
```
### 発生している問題・エラー
```
アクセスをブロック: clasp – the apps script cli のリクエストは無効です
```
これはclasp login --no-localhostを実行して出力されたURLにブラウザからアクセスしたときに表示されるエラーですが面倒なので画像は貼りません
googleのドキュメントなどをみると
OAuth out-of-band (oob) flow will be deprecated
という項目などがあり、自分が対象なのか調べる方法としてURLにoobが含まれるか確認するというのがありますが、自分の場合も該当しました
ざっとしか読んでませんが解決方法はとくになくclasp login --no-localhostはもう使えないということみたいです

### 自分で試したこと
調べたところ、そもそも仮想環境ではなくローカルPCでclasp loginするとできるらしいです
開発環境を作業者間で統一するためにdockerを使っているので試してません

仮想環境でclasp loginするとclasp login --no-localhost と同様にURLが出力されますが、アクセスするといつもの認証画面がでます
そのあと通常なら
>ブラウザ側では、認証が終わった段階でブラウザ上にコードが表示される。
>それを待機していたコマンドラインのEnter the code from that page here:
>の後ろに貼り付ければ、認証完了。

となりますが、clasp loginだとコードは表示されず無効なURL（localhost:***）に遷移します

さらに調べたところ、実はこのURLにcurlでアクセスするとログインできるらしいです
ただしclasp loginを実行したターミナルは入力を受け付けない状態になるので、同じ環境のターミナルを別に開く必要があります
別のターミナルで
```curl　localhost:***```
とすると、元のターミナルでとまっていた処理が再開します
最終的にsuccessful.となればOKです
別のターミナル開くのとか、それを説明するのも大変なのでがんばりました

```bash:login.sh
#!/bin/bash -eu

RUNNING_MODE=$1
cd $(dirname $0)

#設定ファイルから変数を取得
source ./env/claspConfig.text

# login先を明示的に設定
if [[ $RUNNING_MODE = dev ]]; then
    # login先を開発環境に変更
    SCRIPT_ID=$SCRIPT_ID_DEV
elif [[ $RUNNING_MODE = prod ]]; then
    # login先を本番環境に変更
    SCRIPT_ID=$SCRIPT_ID_PROD
else
    echo 'usage: ./login.sh <dev|prod>'
    exit 1
fi

# 設定を反映
echo '{"scriptId":"'$SCRIPT_ID'"}' > .clasp.json

# 仕様変更でclasp login --no-localhostが使えなくなった
echo '出力されたURLにブラウザでアクセスして、フローに従って許可してください。最後に遷移するURL（localhost:***）をコピーしてINPUT_URL_STR: にペースト、エンターしてください。'

# バックグランドでlogin処理を継続させて次の処理を行う
{
    clasp login
} &

# スリープで表示順を調整する
sleep 3
#プロンプトをechoを使って表示、
echo -n INPUT_URL_STR:
#入力を受付、その入力を「str」に代入
read str
#結果を表示
curl $str

# バックグラウンドのログイン処理が完了したら次の処理をする
wait
echo 'login to' $RUNNING_MODE
# 開発環境に戻す
SCRIPT_ID=$SCRIPT_ID_DEV
echo '{"scriptId":"'$SCRIPT_ID'"}' > .clasp.json
echo 'scriptId changed to dev'
```

これで bash ./login.sh prod などと打つと clasp login --no-localhost のときと同じように実行できるようになりました
開発環境と本番環境の設定もそのままのせましたが気にしないでください
バックグラウンドとsleepの処理だけ書けばひとつのターミナルで動くと思います
PySimpleGUIで簡易アプリのメニュー画面を作る

# PySimpleGUIでメニュー画面を作成する。

 PySimpleGUはデスクトップアプリを作成するGUIライブラリ
:::note alert　
その名の通りデスクトップアプリなので、ローカル上で動作する。googleclabでは実行してもGUIは表示されないので注意。
:::

## インストール
```
pip install pysimplegui
```

## インポート
```
import PySimpleGUI as sg
```
でインポートできる。
毎度毎度pysimpleguiと打つのは大変なので
as sg
とすると後が楽。

## レイアウトでよく使うもの

・sg.Text('キーワード')
・sg.In(key='word')
・sg.InputText()
・sg.FolderBrowse(key="folder")
・sg.Button('スタート')

### Text
テキストの表示
### In
入力欄
### InputText
文字入力
### FolderBrowse
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079535/b9e991e3-aedc-df7e-7b41-9a9115464337.png)
こんな感じにファイル参照される。

###Button

##レイアウトの仕組み
GUIを表示させるには、Windowを作成する必要がある。
window = sg.Window('メニュー名', layout )
event, values = window.read()

### メニュー名はこんなの
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079535/e7c000b8-a572-23b5-92f2-eb59527af237.png)

### layout
レイアウトは作成したテキストとかボタンとかの並び順を指定できる。
レイアウトは以下のように配列みたいに格納する
```
layout=[
 
            [sg.Text('検索キーワード',font=100)],

            [sg.In(key='word')],
                
  
            [sg.Text('保存先ファイルを選択(ファイルのアドレスを記入)',font=60)],
                 

            [sg.InputText(),sg.FolderBrowse(key="folder",size=(10,5))],
                 

            [sg.Button('スタート',font=50,size=(15,3),pad=(100,10))], 
            [sg.Button('終了',font=50,size=(15,3),pad=(100,10))]
        
        ]
```
これを実行すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079535/8b406ebe-2055-259d-e95e-ed31c6516126.png)
        図　GUI表示

こんな感じの画面が出てくる。

レイアウトはカンマ（,）区切りで行が変わる。
```
layout=[
        [一行目],
        [二行目],
        ///
        [n行目],
        ]
```

一つの行に２つ以上の要素を入れたいときは、
[　n行目要素2　,　n行目要素2]　のように指定する。
上のGUI表示図を見ると、
```
[sg.InputText(),sg.FolderBrowse(key="folder",size=(10,5))]
```
がこれにあたる。
```
layout=[
        [一行目],
        [二行目要素１,二行目要素２],
        ///
        [n行目],
        ]
```
SalesforceのイベントをAppFlowに伝える方法

# 概要

- SalesforceのイベントをAppFlowに伝える方法を2通り紹介したいと思う。

# AppFlowを使ったSalesforce同期

- 今まではSalesforce（以降SF）の情報をアプリケーションに同期する方法は下記のようなものが一般的だった。
    - アプリケーション側でAPIを用意する。
    - SFからアプリケーションのAPIのエンドポイントにリクエストを送る。

    ![private__Online_Whiteboard_for_Visual_Collaboration.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b2553323-c08e-78db-4cf7-bd62459e49cb.png)

- 現在下記のような同期方法もあります。一見すると工程が増えて複雑ですが、諸事情により「SFからリクエストを投げる」部分の実装がなくてもSFの情報をアプリケーションに同期する事ができる。
    - AppFlowにてSFの任意のオブジェクトの更新イベントを監視する。
    - SFで任意のオブジェクトが更新されたことをきっかけにAppFlowがS3にSFの情報を書き出す。
    - LambdaがS3に情報が書き出されたことをきっかけに実行され、S3から情報を取得しアプリケーションのエンドポイントにリクエストを送る。

    ![private__Online_Whiteboard_for_Visual_Collaboration.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/1802ed01-72cc-b4a9-7690-420a3d409a27.png)

- 今回は後者の方法で、SFからAppFlowにイベント発生を伝える方法を2通りまとめてみます。

# 方法1 「変更データキャプチャ」を使う

- この方法は簡単に設定ができるが、複雑なことはできない。
- 指定したSFのオブジェクトに何かしらの変化（登録・更新）などがあった場合に紐づくAppFlowを実行する。
- 例えば。。。
    - SFのAccountオブジェクトにレコードが新規登録されたら「新規登録されたAccountオブジェクトの指定した項目をCSVとして出力」する事はできる。
    - SFのAccountオブジェクトにレコードが新規登録され、Name項目が`太郎`だった時のみ「新規登録されたAccountオブジェクトの指定した項目をCSVとして出力」する事はできない。
- ようは監視対象のオブジェクトに何かしらの変化があった時にAppFlowを動かすことはできる。
- ただし「何かしらの変化」を独自にいじる事はできない。

# 方法2 「プラットフォームイベント」と「フロー」を使う

- この方法は少々設定が複雑だが、複雑なトリガー条件をつけることができる。
- 例えば。。。
    - SFのAccountオブジェクトにレコードが新規登録され、Name項目が`太郎`だった時のみ「新規登録されたAccountオブジェクトの指定した項目をCSVとして出力」する事ができる。
    - SFのAccountオブジェクトのレコードが更新され、何かしらのフラグ値の項目がONの場合のみ「更新されたAccountオブジェクトの指定した項目をCSVとして出力」する事ができる。
    - SFのAccountオブジェクトにレコードが新規登録され、Name項目が`太郎`で、かつ、何かしらのフラグ値の項目がONの場合のみ「新規登録されたAccountオブジェクトの指定した項目をCSVとして出力」するといった条件の組み合わせも行うことができる。（orやandの演算子条件も選択できる）
- 流れとしては下記になる。
    1. プラットフォームイベントを定義する。
    1. プラットフォームイベントのメッセージ用オブジェクトが生成されるので、AppFlowに渡したい情報を項目として定義する。
    1. フローを定義する。
    1. フローのトリガーの条件（「Name項目が`太郎`」とか「何かしらのフラグ値の項目がON」）を設定する。
    1. フローの中で定義したプラットフォームイベント用オブジェクトの項目にAppFlowに渡したい情報を入れてレコードを作る。
    1. プラットフォームイベント用オブジェクトにレコードが作られたことを起点にAppFlowが実行されプラットフォームイベント用オブジェクトの内容をCSVに出力する。

# まとめ

- 単純な条件でAppFlowでCSVを出力する → 変更データキャプチャを使う。
- 複雑な条件でAppFlowでCSVを出力する → プラットフォームイベントとフローを使う。
validatesのエラーメッセージを表示する仕組み

## 環境
Rails 5.2

## 内容

validatesのチェックで引っかかった場合、どのような仕組みでエラーが表示されているのか、確認してみました。

userモデルには、**name**と**name_id**の２つのカラムがあり、次のようにvalidatesチェックをかけています。
```user.rb
validates :name,    presence: true
validates :name_id, presence: true, uniqueness: true
```

editで編集画面を表示して、**name**を空白にし、**name_id**に重複したデータを入力して、更新ボタンを押します。すると、コントローラの**update**メソッドに入ります。validatesのチェックは、**@user.update**が実行されるタイミングで行われます。validatesのチェックで引っかかった場合、**@user.update**の戻り値が**false**で返ってくるため、if文のelseに入ります。**flash**には「更新が失敗しました。」と表示されますが、具体的に、どの項目がどのような理由で更されなかったのかといった情報までは、このメッセージだけでは分かりません。
```users_controller.rb
def update
	@user = User.find(params[:id])
    if @user.update(user_params)
        flash[:notice] = "更新しました。"
        redirect_to master_user_url
    else
        flash[:notice] = "更新が失敗しました。"
        render :edit
    end
end
```

**@user**オブジェクトの**errors**に、エラーに関する詳細な情報がセットされます。次の変数を使って拾うことができます。**full_messages**を使うと、エラーが複数ある場合、全てのエラーを配列で取得することができます。
```

@user.errors.full_messages          => ["名前を入力してください", "ユーザーIDはすでに存在します"]
```

項目名だけを指定すると、次のような取得のされ方をします。
```
@user.errors.messages[:name]        => ["を入力してください"]
@user.errors.messages[:name_id]     => ["はすでに存在します"]
```
validatesチェックのエラーメッセージはデフォルトで英語になっています。日本語に変換するために、**ja.yml**ファイルを次のように作成します。未入力エラーの場合は、「blank⇒を入力してください」に、重複チェックの場合は、「taken⇒はすでに存在します」にそれぞれ変換されます。変換後、エラーメッセージは**format**の形式で出力されます。
```config/locales/ja.yml
ja:
  activerecord:
      attributes:
          master/user:
            name: 名前
            name_id: ユーザーID
  errors:
    format: "%{attribute}%{message}"
    messages:
       blank: を入力してください
       taken: はすでに存在します
```

配列にセットされたエラーメッセージは、**each**で１個づつ取り出して画面表示します。**present**を付けることで、**errors**にエラーメッセージが存在するときだけ、画面表示することができます。
```_from.html.slim
- if full_messages user.errors.present?
    ul#error_explanation
        - user.errors.each do |msg|
            li = msg
```
十分(じゅうぶん)の翻訳と句読点ルール:大学入学共通テスト2023 数学Ⅰ・数学A 第4問の問題文の１文です。

オリジナル翻訳文
色のついた長方形は，向きを変えずにすき間なく並べることとし，色のついた長方形は十分あるものとする．

大学入学共通テスト2023 問題 数学Ⅰ・数学A

https://www.fukuishimbun.co.jp/common/dld/pdf/f8b8055fea4fd66217ce44500de52173.pdf#page=24

上と同じです。大学入試数学問題集成＞第4問

https://mathexamtest.web.fc2.com/2023/202310000/2023100000100mj.html#top-0106

注)上のid=の機能が効かないケースあり。調査中。

# 翻訳について

①一文を翻訳しました。
「十分」の翻訳を調べるつもりが、「あるものとする。」の翻訳になりました。

②日本語の文法について。
オリジナルの句読点が、ちょと気になります。「〜長方形は、〜」と「〜長方形は十分〜」。下にリンク参考があります。句読点ルール通りか?教えて下さい。
翻訳できるから文法は正しい?と思います。

③アプリがありますか？
**日本語を入力したら、以下の翻訳結果のように、6通りに翻訳してほしい。**


# (再出)オリジナル翻訳文
色のついた長方形は，向きを変えずにすき間なく並べることとし，色のついた長方形は十分あるものとする．

### 翻訳結果
DeepL翻訳　日本語→英語
The colored rectangles shall be placed in an unoriented, gapless arrangement, and there shall be sufficient colored rectangles.

goole翻訳　日本語→英語
The colored rectangles should be arranged without any gaps without changing their orientation, and there should be enough colored rectangles.

DeepL翻訳　英語→日本語
色付き長方形は無指向性で隙間なく配置され、十分な数の色付き長方形がなければならない。

google翻訳　英語→日本語
色付きの四角形は、方向を変えずに隙間なく配置し、色付きの四角形が十分にある必要があります。

DeepL翻訳　(google翻訳の結果)英語→日本語
色のついた長方形は、向きを変えずに隙間なく並べること、色のついた長方形が十分にあることが必要です。

google翻訳　(DeepL翻訳の結果)英語→日本語
色付きの四角形は、方向付けられていない隙間のない配置で配置され、十分な数の色付きの四角形が存在する必要があります。

# 参考

https://www.google.com/search?q=%E5%8F%A5%E8%AA%AD%E7%82%B9+%E3%83%AB%E3%83%BC%E3%83%AB&oq=%E5%8F%A5%E8%AA%AD%E7%82%B9+%E3%83%AB%E3%83%BC%E3%83%AB&aqs=chrome..69i57j0i512l7.3056j0j7&client=ms-android-huawei&sourceid=chrome-mobile&ie=UTF-8

必要十分条件
DeepL,google翻訳結果とも necessary and sufficient condition
POP2-CCSM4海洋モデルの特殊グリッドを緯度経度格子座標に変換する

アホみたいに時間を浪費したので、メモを日本語でまとめておきます。
今回は、gx1v6グリッドを1度x1度グリッドに変換しました。

# ゴール
**海洋モデルPOP独自の座標 (グリーンランドに極がある) を、普通の緯度経度格子座標 (1度x1度) に変換する。** 

## 問題点

1. [CMIP5-PMIP3](https://esgf-node.ipsl.upmc.fr/search/cmip5-ipsl/)で提供されている出力が、モデル座標のものしかなかった。
2. ググったところ、NCLで変換する方法は、わりとたくさん紹介されていた ([例](https://www.ncl.ucar.edu/Applications/ESMF.shtml)）。だが、筆者はNCLは今まで使ったことがなく、このためだけにゼロからNCLを勉強するのは避けたい。

## 解説している記事を発見
[こちらのページ](https://iloveocean.top/index.php/archives/807/)にある方法でうまくいった。
以下、日本語でまとめなおしたが、適宜引用元を参照されたし。

# 手順
## グリッド情報を入手

[POP-tool](https://pop-tools.readthedocs.io/en/latest/)という、POPの特殊なグリッドを描画するためのPythonパッケージがある。
今回は、グリッド情報をnetCDF形式で得るために利用する。

まずは、インストール。
```bash
conda install -c conda-forge pop-tools
```

軸情報をダウンロード。

```Python:Python3
import xarray as xr
import pop_tools
ds = pop_tools.get_grid('POP_gx1v6', scrip=True) 
ds.info()
```

特に指定しなければ、`~/.pop_tools`以下にインストールされるよう。

ファイル形式(`.ieeer8`)をnetCDFに変換。

```Python:Python3
ds.to_netcdf('~/.pop_tools/inputdata/ocn/pop/gx1v6/grid/gx1v6_grid.nc')
```

## 変換先の軸情ファイルを作成
NCOの`ncremap`コマンドを使う。

まずは、ncoをインストール。
```bash:
conda install -c conda-forge nco
```

これで、`ncremap`が使えるようになる。

今回は1度x1度の直交座標系に変換したいので、下記のように指定し、`grid_1x1_uni_global.nc`というグリッド情報ファイルを作成。

```bash:
ncremap -g grid_1x1_uni_global.nc -G ttl='Equi-Angular grid 180x360'#latlon=180,360#lat_typ=uni 
```

## グリッド変換用の重み付けファイルを作成

引き続き、`ncremap`コマンドを使用して、**gx1v6**から**1度x1度の直交座標系**に変換するための重み付けファイル`gx1v6_to_1x1_uni_global.nc`を作成。

```bash:
ncremap -a bilinear -s ~/.pop_tools/inputdata/ocn/pop/gx1v6/grid/gx1v6_grid.nc -g grid_1x1_uni_global.nc -m gx1v6_to_1x1_uni_global.nc
```

## グリッド変換

さきほどNCO (`nremap`) をインストールした際に、同時にインストールされたコマンド群のなかに、`ncks`がある。

`ncks`コマンドを使用して、大元のNetCDFファイル (`tos_Oclim_CCSM4_piControl_r1i1p1_180001-230012-clim.nc`) から必要な変数 (`tos`) のみを切り出し、`tos_gx1v6.nc`として出力。

```bash:
ncks -v tos tos_Oclim_CCSM4_piControl_r1i1p1_180001-230012-clim.nc tos_gx1v6.nc
cdo setmissval,-999.0 tos_gx1v6.nc out.nc ; mv out.nc tos_gx1v6.nc # ついでに欠損値の変更 (必須ではない)
```

`ncremap`コマンドでグリッド変換！！

```bash: 
ncremap -m gx1v6_to_1x1_uni_global.nc tos_gx1v6.nc tos_180x360.nc
```

`ncdump -h`とか`ncview`とかしてみると、グリッド変換できているのが確認できる。**やったね！！**

軸が(i,j)となっており、(lon,lat)に直したい。今回は、下記の方法で別のファイルで同じ(lon,lat)座標のものから軸情報をうつすことに成功。`ncremap`はNCOコマンド群に同梱。

```bash:
ncrename -d i,lon -d j,lat tos_180x360.nc tmp.nc # 軸の名前を変更。
cdo merge tmp.nc ../sic.nc tmp2.nc # 正しい軸情報を持っているファイルといったんマージ。
ncks -v tos tmp2.nc tmp3.nc        # 改めて、必要な変数のみ書き出し。
mv tmp3.nc tos_180x360.nc
```

## おまけ

海陸マップを変更した古気候実験の結果に同じ方法を適用したら、グリッド変換後に海岸線付近に変な値が入りました・・・。本来はgrid情報ファイルの海岸線を変更すべきなのだろうが、ひとまず海水温を地表気温を利用して埋めました。
aws cli で組織の子アカウント課金情報をOU単位で抽出したい

Organizations使っていて、OU単位での課金情報取ろうとすると
大概`じゃあCostCategolyを使って`みたいな話になるんですが

`そうじゃねえんだよ`OUさえ分けてればアカウント単位での利用料金を
自動で振り分けしてレポートされるようにしたいんだよ
という思いで作ったスクリプトです。

```
#!/bin/csh

set LASTMONTH=` date +%Y-%0m-01  -d '1 month ago'`
set THISMONTH=` date +%Y-%0m-01`
set REGION=us-east-1
set PROFILE=orgprofile

echo TimePeriod : $LASTMONTH to $THISMONTH
echo Region : $REGION
echo PROFILE : $PROFILE

aws ce get-cost-and-usage --profile ${PROFILE} --region ${REGION} --time-period Start=${LASTMONTH},End=${THISMONTH}\
  --granularity MONTHLY --metrics UnblendedCost  --group-by Type=DIMENSION,Key=LINKED_ACCOUNT  \
| jq -c '.ResultsByTime[].Groups[]' | cut -d\" -f4,12,16 | sed -e 's/"/ /g' | awk -e '{printf "%-15s %8.2f USD\n",$1,$2}' > /var/tmp/AWSCostList

set OUID=ou-mxus-12345678
set OUNAME=MyOU1
echo OU : $OUNAME , OUID : $OUID

foreach AWSID (`aws organizations list-accounts-for-parent --profile $PROFILE --parent-id ${OUID} --query 'Accounts[].Id' --output text`)
 egrep $AWSID /var/tmp/AWSCostList
end
```

実行結果。

```
$ ./BillUnderOU.sh 
TimePeriod : 2022-12-01 to 2023-01-01
Region : us-east-1
PROFILE : orgprofile
OU : MyOU1 , OUID : ou-mxus-12345678
17xxxxxxxx58      143.03 USD
84xxxxxxxx89        4.38 USD
```
このスクリプトでは1 OUだけの結果を出してますが、増えてきたらループで回せばいい感じになるかと思います。
確実に動くGWT開発環境を作る

2023年1月　windows10 で開発できる環境を用意

・GWT(旧Google Web Toolkit)は情報は多いものの、古かったり、動かない事例が紹介されており、苦労した挙句に開発環境が作れない状態です。
　そこで、かなり初期から開発しているワイですが、確実に動く、GWT開発環境をzipファイル化して、作成手順をまとめましたので、ご利用ください。

■Eclipse 4.6 + GWT プラグイン
https://drive.google.com/file/d/1-IaQOlnH1IsYzSbBbHO7_pzST4hbJq4L/view?usp=sharing
(*)ちょい古いですが、動作確認しています。

■セットアップ方法
(1)ダウンロードする
(2)ファイルを解凍
(3)回答したフォルダの中のpleiades-4.6をCドライブ直下へ移動
　　(*)GWTの設定がCから基準になっているので
　　C:\pleiades-4.6\pleiades\eclipse
　　こんな感じになっていればよい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132663/a5d84e66-98c0-a0b7-426c-d012179b0a83.png)

(4)移動した先のエクリプスフォルダから、「eclipse.exe」を実行
　ショートカットを作った方が楽だとおもう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132663/7ca22509-c12c-4ce1-8130-2ffd48775854.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132663/acf99c48-0e3f-3800-c201-fa321bfa23bd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132663/d046312f-01ee-fa62-45ec-9ef80eb4d7a9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132663/f2ac80a4-f1bb-dea7-33a7-aa8717652c33.png)

■サンプルアプリも作ってあるので、是非動かしてほしい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132663/910910cc-aeb4-0634-2df3-36d9aab52d26.png)

■開始は、実行→Webアプリケーション(GWT Super Dev Mode)だ　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132663/8b8824dd-7132-e47d-27ac-9bbdd0416157.png)

■URLをコピーして、動かしたいブラウザへ貼り付ければ起動する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132663/0db61d1c-0ab8-c5aa-e82a-d30717c2a7b9.png)

エンジョイ！

もしも、動かない場合は、連絡をください。
(リンクだけです) 「【空間図形】 辺や面を表すときのアルファベット順」を調べた。（扇形を含む)

# 【空間図形】 辺や面を表すときのアルファベット順

https://chu.benesse.co.jp/qat/881_m.html

https://www.google.com/search?q=%E2%96%B3ABC&oq=%E2%96%B3&aqs=chrome.1.69i57j69i59j0i512l7.9115j0j7&client=ms-android-huawei&sourceid=chrome-mobile&ie=UTF-8

# 参考

http://office-qa.com/Word/wd1039.htm

https://www.google.com/search?q=%E5%BC%A7+ab+%E2%8F%9C+%E5%87%BA%E3%81%97%E6%96%B9&oq=%E5%BC%A7%C2%A0AB%C2%A0%E2%8F%9C%C2%A0&aqs=chrome.2.69i57j69i59j33i160.19655j0j7&client=ms-android-huawei&sourceid=chrome-mobile&ie=UTF-8

http://k-maeda.la.coocan.jp/code/uni/uni006.html
aws cli で組織子アカウントのサービス単位課金を抽出したい

ちょいコツがいる処理だったので備忘も兼ねて投稿

組織アカウントのプロファイルでサービス単位の課金情報は
こんな風にSERVICE の DIMENSIONで取れますが
```
aws ce get-cost-and-usage --profile ${PROFILE} --region ${REGION} --time-period Start=${LASTMONTH},End=${THISMONTH}\
  --granularity MONTHLY --metrics UnblendedCost  --group-by Type=DIMENSION,Key=SERVICE \
```

子アカウント(LINKED ACCOUNT)単位での情報を取ろうとすると、既にDIMENSIONが
使われていて指定できない。
でも子アカウント毎に都度profile作るのは面倒だしメンテもしたくない。
サポートに訊いたら`--filter使えや`って話だったので早速設定。
https://docs.aws.amazon.com/ja_jp/cli/latest/reference/ce/get-cost-and-usage.html

filter ファイルを準備
```
$ cat filter-linkedaccount 
{ "Dimensions": { "Key": "LINKED_ACCOUNT",  "Values":  [ "17xxxxxxxx58" ] } }
```

実行コード。実行日の前月の課金情報を取得
```
#!/bin/csh 

set LASTMONTH=` date +%Y-%0m-01  -d '1 month ago'`
set THISMONTH=` date +%Y-%0m-01`
set REGION=us-east-1
set PROFILE=orgprofile

echo TimePeriod : $LASTMONTH to $THISMONTH
echo Region : $REGION
echo PROFILE : $PROFILE

aws ce get-cost-and-usage --profile ${PROFILE} --region ${REGION} \
  --time-period Start=${LASTMONTH},End=${THISMONTH}\
  --granularity MONTHLY --metrics UnblendedCost  --group-by Type=DIMENSION,Key=SERVICE \
  --filter file://filter-linkedaccount \
 |  jq -c '.ResultsByTime[].Groups[]' | awk -F'"' '{printf "%-50s %10.3f \n",$4,$12}'
```

実行結果。CostExplorer の値と比較したけど正しい値拾えてました。

```
$ ./ServiceBillUnderOU.sh 
TimePeriod : 2022-12-01 to 2023-01-01
Region : us-east-1
PROFILE : orgprofile
AWS CloudTrail                                          0.000 
AWS Config                                              0.102 
AWS Key Management Service                              0.000 
AWS Secrets Manager                                     0.000 
AWS Security Hub                                        0.000 
AWS Service Catalog                                     0.000 
EC2 - Other                                           122.220 
Amazon Elastic Compute Cloud - Compute                  7.691 
Amazon GuardDuty                                        0.000 
Amazon Simple Notification Service                      0.000 
Amazon Simple Queue Service                             0.000 
Amazon Simple Storage Service                           0.015 
AmazonCloudWatch                                        0.000 
Tax                                                    13.000 
```
AWSのCLIリファレンスは初心者に厳しい。もっと設定のサンプルを載せて欲しいといつも思う。
Googleプロジェクト管理：コミュニケーションプラン

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/7c79c997-e4e4-7d71-3686-e01b7badaa3c.png" width="800">

# コミュニケーションプランとは

コミュニケーションプランとは、プロジェクトにおけるコミュニケーションの

- プロセス
- 種類
- 期待値

などを整理し、文書化したものです。

コミュニケーションプランの規模や複雑さは、プロジェクトごとに異なりますが、常に持っておくとよいでしょう。

プロジェクトに関連する他の計画と同様に、コミュニケーション計画も、

- 何を伝えるべきか？
- 誰が伝えるべきか？
- いつ伝えるべきか？
- なぜ、どのように伝えるか？
- 伝えた情報はどこに保管されるか？

といった質問に答える必要があります。

# コミュニケーションプランのサンプル

https://docs.google.com/spreadsheets/d/11O2DZHsKkjj36W36mxzwFkTJe6CZ5anY1DahpuKGrEY/template/preview

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/1c99a395-c124-1dad-7a51-0883023c2fa6.png" width="900">


# プロジェクトプラン作成のベストプラクティス

### Identify, identify, identify

プランの作成を始める前に、以下の質問に答えて、関連する情報がすべて揃っていることを確認してください。

- **ステークホルダー：**
    - すべてのステークホルダーの RACI チャートまたはステークホルダーマップを作成しましたか？
    - 聴衆は誰ですか？
    - プロジェクトのライフサイクルの各時点で、誰に情報を提供する必要がありますか?

- **コミュニケーションの頻度と方法:**
    - ステークホルダーといつ、どれくらいの頻度で連絡を取るべきですか？
    - ステークホルダーは、どのようなコミュニケーション手段を好みますか？
    - 各ステークホルダーは、どの程度詳細な情報を必要としているか?

- **目標:**
    - コミュニケーションのゴールは何か？
    - 回答が必要ですか？
    - 関与を促そうとしているのか、それとも単に最新情報を提供しようとしているのか?

- **障壁:**
    - 時間帯の制限はありますか？
    - 言葉の壁はあるか？
    - 回答や返答に時間がかかる関係者がいるか（役員など）？
    - プライバシーやインターネットアクセスの問題はないか？


### Document and develop

コミュニケーションのニーズをすべて文書化するツールやテンプレートを選び、計画の策定を開始します。基本的な要素（ステークホルダー、コミュニケーション方法、目標、障壁）を理解したら、次は細部を詰めていきましょう。

- **メモ用の列を追加する:**
プロジェクト管理は一様ではなく、追跡が必要な部分がたくさんあります。例えば、
   - シニアリーダーやエグゼクティブに連絡を取る場合、メールに他の人をコピーする必要がありますか？
   - ステークホルダーが外出中であったり、特定の日に連絡が取れない場合、バックアッププランを用意しておく必要がありますか？

- **計画書の重要な部分を強調するために書式を使用する:**
プロジェクトが前進するために必要な発表や緊急の決定がありますか？これらの重要な要素には、異なるフォントの色や大きさでハイライトを入れ、その重要性を強調します。

- **チームが文書にアクセスできることを確認する:**
計画をチームと共有します。チームが文書を確認できるようにすることで、計画を認識し、フィードバックを提供する機会が与えられます。また、文書を共有することで、重要な部分に抜けがないか、さらに確認することができます。

- **計画をテストする:**
チーム全体にメールやリンクを送る場合は、自分自身か同僚にテストメールを送ります。バーチャルなプレゼンテーションを計画している場合は、視覚、聴覚、その他の技術的な側面を事前にテストしてください。そうすることで、技術的な問題を最小限に抑えることができます。

### Check in

コミュニケーションプランを世に送り出したら、そのプランの有効性について、聴衆に確認してください。定期的なチェックインを行うことで、何が効果的で、何が効果的でないかを理解し、計画を改善することができます。コミュニケーション・プランでは、適切な情報を適切なステークホルダーに適切なタイミングで届けることを心がけてください。さらに、主要なステークホルダーが時とともに変化していないか、再確認してください。

情報共有の過不足やステークホルダーの欠落がないか評価する。これは、以下の方法で行うことができます。

- 匿名の調査票
- チームミーティングでの投票またはオープンフィードバックセッション
- 主要なステークホルダーとの1対1の会話とチェックイン
【超シンプル】Bash の find コマンドで .htaccess (特定ファイル) のパス一覧を出力する


ウェブサイトの中にある .htaccess などの特定ファイルが、サーバー上のどこに存在しているか、一覧を出力するのには find コマンドが便利です。

フォーマット

```
find [親フォルダパス] -name "[ファイル名]" -print
```

例

```
find /Users/katz/Sites/example -name ".htaccess" -print
```

こんな感じでパス一覧が出ます。

サンプル

```
% find /Users/katz/Sites/example -name ".htaccess"
/Users/katz/Sites/example/public/.htaccess
/Users/katz/Sites/example/public/application/.htaccess
/Users/katz/Sites/example/public/application/files/.htaccess
# .... (省略).....
```

find コマンド、便利

参考
https://stackoverflow.com/questions/1739013/find-all-htaccess-files-on-server
https://linuxjm.osdn.jp/html/GNU_findutils/man1/find.1.html
SwiftUI BindingのあるViewのプレビューを正しく表示する

# 概要

例えば、地図を表示するViewをSwiftUIで構築します。
このViewは地図と、現在地を示す位置情報をテキストで表示します。
地図はMapKitを使って、`Map`で表示します。

Mapのinitの形式には`MKCoordinateRegion`や`MKMapRect`を使いますが、いずれの型式でもBindingでの指定が必要になります。
構築するViewが外から＠Bindingの形でパラメータを受け取る形の場合、PreviewにもBindingに指定する＠Stateなどの値が必要になります。

Stateを用意せず、プレビューで`.constant`で固定のMKCoordinateRegionを入れておけばビルドとしては動きますが、プレビューとしては、地図を動かしても位置情報テキスト部分の値が変わりません。

![修正前.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687960/399db71d-a6cb-8e5a-2e3c-06f86727a58b.gif)



# 正しくBindingをPreviewで動かす

動的にBindingの値を動かしたい場合、Preview内部で中間のViewを用意し、そのViewで＠Stateを使ってMapViewを実装することにより、プレビューでも値が追従されることを確認可能になります。

![修正後.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687960/89f458df-8671-850b-5dec-e9bf02b052b4.gif)


この中間Viewの名前を`Shim`としていますが、この命名及びコードはWWDC20の[Structure your app for SwiftUI previews](https://developer.apple.com/videos/play/wwdc2020/10149/)を参考にしています。

```swift
import SwiftUI
import MapKit

struct MapView: View {
    @Binding var coordinateRegion: MKCoordinateRegion
    
    var body: some View {
        VStack {
            Text("\(coordinateRegion.center.latitude.description)")
            Map(coordinateRegion: $coordinateRegion)
        }
    }
}

struct MapView_Previews: PreviewProvider {
    struct Shim: View {
        @State private var coordinateRegion = MKCoordinateRegion(center: .init(latitude: 35,
                                                                               longitude: 139),
                                                                 span: .init(latitudeDelta: 0.01,
                                                                             longitudeDelta: 0.01))
        var body: some View {
            MapView(coordinateRegion: $coordinateRegion)
        }
        
    }
    static var previews: some View {
        Shim()
    }
}

```
UnitV2にいれたGentooでWiFiを使えるようにするまで


https://qiita.com/ebisuke/items/49eaf1087928bffe9b23

一応↑の関連記事になります。

# 手順
以下の手順はUnitV2で行いました。
git等はemergeで入れています。  
## ソースをクローン

fifteenhexさんの RTL8188FUをクローンします。
```
git clone https://github.com/fifteenhex/rtl8188fu
```
## ソース修正
makeする前にREADMEのConfigurationに書いてあることをやればいいのですが、  
なぜか`Disable Power Management`だけは効いてなさそうだったので、ソースを修正します。  
`CONFIG_POWER_SAVING`の`#define`を全てコメントアウトし、`#undef CONFIG_POWER_SAVING`を入れます。

`include/autoconf.h Line 233-248`
```
#ifdef CONFIG_POWER_SAVING
	//#define CONFIG_IPS
	//#define CONFIG_LPS
    #undef CONFIG_POWER_SAVING
	#ifdef CONFIG_IPS
	/* #define CONFIG_IPS_LEVEL_2	1  */ /*enable this to set default IPS mode to IPS_LEVEL_2 */
	#endif

	#if defined(CONFIG_LPS) && defined(CONFIG_SUPPORT_USB_INT)
		/* #define CONFIG_LPS_LCLK */
	#endif

	#ifdef CONFIG_LPS_LCLK
	//	#define CONFIG_XMIT_THREAD_MODE   
	#endif
#endif /* CONFIG_POWER_SAVING */
```
## インストール
ドライバのビルドとインストール、ファームウェアのコピーをします。
出来たら再起動します。
```
cp firmware/rtl8188fufw.bin /lib/firmware/rtlwifi/
make && make install && depmod -a
modprobe rtl8188fu

reboot
```


## WiFi設定
私は`nmtui`でやりました。 USEフラグに`tools`を追加すればいいと思います。

# 結果
良好です。カーネルの`CONFIG_TUN`も有効にして、tailscaleも入れました。
```
unitv2 ~ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether be:e7:57:62:c2:e0 brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.6/24 brd 192.168.2.255 scope global dynamic noprefixroute eth0
       valid_lft 86331sec preferred_lft 86331sec
    inet6 fd16:1f82:dc89:4897:e84b:863d:3d28:4085/64 scope global dynamic noprefixroute
       valid_lft 2591932sec preferred_lft 604732sec
    inet6 fe80::d577:e952:671b:22ef/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:e0:4c:01:45:ed brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.45/22 brd 192.168.3.255 scope global dynamic noprefixroute wlan0
       valid_lft 7147sec preferred_lft 7147sec
    inet6 fdb6:d77:8a51:4665:5ac6:ba77:7f1d:fed7/64 scope global dynamic noprefixroute
       valid_lft 1747sec preferred_lft 1747sec
    inet6 fe80::1aa8:6165:5bb3:3a82/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
4: tailscale0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1280 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none
    inet 100.67.130.25/32 scope global tailscale0
       valid_lft forever preferred_lft forever
    inet6 fd7a:115c:a1e0:ab12:4843:cd96:6243:8219/128 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::14e7:c87:68a2:f1e3/64 scope link stable-privacy
       valid_lft forever preferred_lft forever
```
python get business days between two dates

```python
import holidays
from datetime import datetime
import pandas as pd

HOLIDAYS_US = holidays.US()
def GetBusinessDays(start, end):
    startTime = datetime.strptime(start, '%Y-%m-%d')
    endTime = datetime.strptime(end, '%Y-%m-%d')
    dates = pd.date_range(startTime,endTime,freq='D')

    res = []
    for date in dates:
        if date.weekday() in holidays.WEEKEND or date in HOLIDAYS_US:
            continue
        res.append(date)
    return res

if __name__ == '__main__':
    dates=GetBusinessDays('2020-03-18','2023-01-19')
    print(dates)
```

### NextBusinessDay
```python
from datetime import datetime, timedelta
import holidays
import pytz

HOLIDAYS_US = holidays.US()

def GetNextBusinessDay(days=1):
    next_day = datetime.now(pytz.timezone('America/Chicago'))
    if (
        next_day.hour >= 15 or 
        next_day.hour < 9 or 
        next_day.hour == 9 and next_day.minute <= 30
    ): days += 1
    days = timedelta(days=days)
    next_day = next_day.date() + days
    while next_day.weekday() in holidays.WEEKEND or next_day in HOLIDAYS_US:
        next_day += days
    return next_day
```
Googleプロジェクト管理：効果的なコミュニケーション

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/7c79c997-e4e4-7d71-3686-e01b7badaa3c.png" width="800">

# コミュニケーションの重要性

コミュニケーションは、どのプロジェクトでも非常に重要です。プロジェクトを円滑に進めるための最も重要なツールであるとさえ言えるでしょう。プロジェクトチームの成否は、多くの場合、全員が何が起きているのか、自分の仕事がプロジェクトの目標にどのように貢献しているのかを理解しているかどうかにかかっています。

プロジェクトマネージャーであるあなたは、全員が自分の役割と仕事を理解しているかどうかを確認する大きな役割を担っています。また、チームメンバーが困ったときに相談する相手でもあります。明確で効果的なコミュニケーションをとることが重要なのです。効果的なコミュニケーションなくして、プロジェクトは重要なチャンスを逃し、失敗する可能性があることを忘れてはなりません。

効果的なコミュニケーションとは、常に

- ***<font color="MediumVioletRed">明確で</font>*** 
- ***<font color="MediumVioletRed">正直で</font>*** 
- ***<font color="MediumVioletRed">適切で</font>*** 
- ***<font color="MediumVioletRed">頻繁で、しかし頻繁すぎない</font>*** 

ことです。

プロジェクトマネージャーとして、プロジェクト期間中のコミュニケーション計画を立てることが重要です。良いコミュニケーションは、プロジェクトを円滑に進め、より良い成果をもたらし、健全なチーム文化を支えるものです。

# 4つの効果的なコミュニケーション戦略


## 1.個人差の認識と理解

オープンで包括的なコミュニケーションを促進するには、次のような方法があります。

- 聴衆の背景、アイデンティティ、経験について決めつけない。
- 自分自身の偏見に注意する。
- 適切で、専門的、かつ中立的な言葉を使う。
- 多様な視点を取り込み、尊重し、好奇心を持つ。

プロジェクトマネージャーとして、あなたはプロジェクトごとに多様なチームメンバーや利害関係者と仕事をすることになります。効果的なコミュニケーションを図るためには、各メンバーの背景、経験、考え方、偏見などを理解する必要があります。

### 2.ブレーンストーミングと適切なメッセージの作成

コミュニケーションでは、常に、理由を明確にしましょう。

- 聴衆はどのようなチャネルを使ってあなたやチームにコンタクトを取ることができるのか？
- 情報を伝えているのか？
- 意見を求めているのか？
- 問題を明確にしているのか？
- 問題を解決するためですか？

チームメンバーによっては、詳細な情報を必要とする場合もあれば、状況の概要のみを必要とする場合もあります。どのような相手であっても、メッセージの目的を明確にし、情報や要望を明確かつ簡潔に述べ、話題を絞る必要があります。

### 3．メッセージを届ける

メッセージを作成する際には、直接会う、ビデオ会議、電話、電子メール、会議など、さまざまなメンバーとのコミュニケーションに適した方法を考えてください。特に、地域や時間帯の異なるチームメンバーやステークホルダーがいる場合は、適切な方法を選択することが重要です。

また、次のことも確認してください。

- 機密情報や個人情報を含まないようにする。
- 会社の全員がそのコミュニケーションを受け取ることを想定する。

### 4.フィードバックを得て、今後に反映させる

コミュニケーションは、メッセージを伝えたら終わりではなく、次のようなフォローアップを心がけましょう。

- あなたのメッセージが明確であったかどうかを確認する。
- フィードバックを求める。
- オープンなコミュニケーションを奨励する。
- 質問には迅速に対応する。

この最終ステップでは、あなたのメッセージが意図したとおりに受け取られたことを確認するために、聴衆からフィードバックを得ます。
Oracle Analytics Cloud ： 分析を始める。DataVisualizationで作成した表形式のビジュアライゼーションに小計、総計をセットする。

はじめに
---
Oracle Analytics Cloud ： DataVisualizationで作成した表形式のビジュアライゼーションで、小計や総計を合わせて表示したい。
といったような場合には、プロパティ・ペインを利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/2d100462-b39c-cbd6-9369-34b38b202ddd.png)


記事記載時のOAC ver：Nov 2022 Update


前提
---
Data Visualizationでワークブックを作成したことがある
Qiita記事の「Oracle Analytics Cloud ： 分析を始める。」シリーズで、表形式のビジュアライゼーションを作成し、保存している。

総計をセットする
---
ワークブックを開き、編集モードにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/80048a01-24be-38bf-0054-65f76da0f19f.png)

プロパティ・ペインの左から3番目、"合計"タブをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/c19b9053-91a2-a2d2-3416-a4bf442eaaa8.png)

"総計"がオフになっています。"オフ"のところをクリックすると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/b10ae5b6-dee9-6a77-f7dd-a5edf95f250e.png)

"総計"がオンに切り替わります。
表形式の最下部に、総計が追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/9d1921e5-8f51-6faa-e622-a9807f081a4c.png)

"総計の確定"を切り替えます。"オフ"のところをクリックすると、オンに切り替わり、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/8e7d6ec3-44b5-37f1-86b7-66a667317361.png)

表形式のビジュアライゼーションの下部に総計が固定されます。
スクロールして最下部までいかなくても、常に総計が表示されるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/04a102db-31c7-bea4-2246-fcf9ba6c1394.png)

小計をセットする
---
小計をセットします。同様に、プロパティ・ペインの"合計"タブをクリックし、小計の"なし"のところをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/203f7d94-46a7-def0-b308-44ff2d75d8e6.png)

小計をセットする列を選択します。PROD_CATEGORYをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/a7b4e6c2-fac6-3b57-af09-4b12040cc377.png)

PROD_CATEGORY毎に小計がセットされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/5ed4444a-aa08-d3d3-52d6-c496804d008c.png)

表形式で総計、小計をセットする場合は、プロパティ・ペインでセットしました。ピボット形式でも同様にプロパティ・ペインでセットします。ピボット形式では合計行の位置を前後、上下を選択できますので、総計を前にもってきたい場合などはピボット形式をつかうことも考えられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/6caade4f-b800-a275-01ea-ab3b313f3f6e.png)



以上
Excelで正のデータの平均値を算出する方法


# Excelで正のデータだけを数えて、その平均値を算出したい

## COUNTIF関数を使おう
**=COUNTIF(データ範囲, ">0")**
→正の値を取るデータだけをカウントできる


**=SUM(データ範囲/COUNTIF(データ範囲, ">0"))**
→正の値を取るデータの平均値を計算できる。
　Excelでデータ範囲は既定だが、0の値は無視して
　正の値のみ平均値を算出したい時に使える。
### 応用
**=COUNTIF(データ範囲, "<0")**
→負の値を取るデータだけ数えられる

**=COUNTIF(データ範囲, ">=0")**
→0以上だけ数えられる（正の値、および0のデータ）

### おわりに
COUNTIF関数を使うことで、Excelのデータ処理を効率化できる！！
うれしい！！

## 参考資料

https://white-circle7338.com/seinokazu_count/
ImportError: cannot import name 'extract_features' from 'tsfresh' (unknown location) で一生嵌った話

tsfreshの`extract_features`関数をimportできずに一生嵌っていた。

環境
tsfresh==0.20.0, Python 3.9, Jupyter lab
```
from tsfresh.feature_extraction import extract_features
```
で
```
ImportError: cannot import name 'extract_features' from 'tsfresh' (unknown location)
```
のエラーがでて`extract_features`関数をimportできなかった。

https://github.com/blue-yonder/tsfresh

を見てみると...

おい、`extract_features`関数があるの、feature_extractionディレクトリの下の`extraction.py`じゃねーか！！

https://github.com/blue-yonder/tsfresh/blob/main/tsfresh/feature_extraction/extraction.py

ということで、
```
from tsfresh.feature_extraction.extraction import extract_features
```
としたら無事importできた。ローカル環境では`from tsfresh.feature_extraction import extract_features`でできたんだけどな、パッケージのPath系は謎が多くてしんどい。。。
デヂエとは何ぞや・・・？

 # はじめに
業務で行っているお客様対応で「デヂエ」という単語を見かけ、聞いたことがなかったためデヂエについての記事を残します。ちなみに、そのお客様は以前までデヂエを使っていましたが、現在はプリザンターを使われているそうです。なぜプリザンターを選んでいただいたのか、そこも最後に考察してみようと思います。

 # デヂエとは・・・？
サイボウズ デヂエという製品だろうか。この製品について少し調べてみようと思います。デヂエはお手軽に使えるWEBデータベースらしいです。デヂエをダウンロードし、サーバーにインストールすることで使えるそう。Web ブラウザだけでデータベースを構築、閲覧、活用することができます。

 # どのような会社さんにおすすめなのだろうか・・・？
主にエクセルファイルでデータを管理している会社さんで導入しているそうです。複数人がファイルサーバーでエクセルを管理している場合、無駄なエクセルファイルをそのまま放置し容量がひっ迫してしまったり、最新のファイルをだれが所有しているのか把握しきれていない会社さんにおすすめだそうです。

 # デヂエの使い方
デヂエは、自由に項目を作成し、情報を蓄積する箱（ライブラリ）を作成できるツールだそうです。データベースの役割をするそうですね。また、ほかのサイボウズ製品と互換性があるのだとか・・・。WEBにアクセスできる環境であれば操作可能。特別な設定などは不要らしいです。

 # 無料のサンプルも・・・？
ダウンロードしたデヂエに無料のサンプルを同封しているそうです。そのため、無料で使うことができるそう。

 # 料金は？
細かくはここで記載しませんが、無料期間なるものがあり、60日までは無料だそうです。それ以外も料金はかかりますが、いろいろできるそうでした。

 # つぶやき
プリザンターと機能はほとんど一緒なのかなと思いました。(ザッとしか見ていませんが・・・)ただ、プリザンターにあってデヂエにないのは、お客様の環境でお客様自身がローコードで、お客様自身のプリザンターを作ることができる機能なのかなと思いました。また、プリザンターは機能の数が豊富でやりたいことのほとんどはプリザンターで済むかと・・・個人的な感想でした。

 # プリザンターが選ばれたのはなぜ・・・？
「サイボウズ　デヂエ8」は2023年9月末にサポートが終了するようです。そのため、プリザンターに切り替えていただいたのかと思われます。では、なぜプリザンターだったのか。ここは個人的にも気になりますね。すでにプリザンターの特徴をサクッとご紹介していますが、ローコードで業務アプリが開発・カスタムできることが決め手なのかなと思いました。つまり、いわゆるプログラミングなどを専門としているプログラマーなどの技術者がいなくても、それぞれの業務アプリを構築することができ、自社内で管理・運用できるということがプリザンターの強みでもあり、決め手でもあったのかと思われます。それに、基本的な機能は無料です。そのため手の出しやすいという点も決め手かと思われます。機能など足りないものを補うためには料金が発生しますが、一度プリザンターを無料で体験してみてもよいかもしれません。

 ## 参考にした記事
https://kantan.cybozu.co.jp/dezie/product/

https://products.cybozu.co.jp/dezie/replace/
13.テーブル

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf8">
    <meta name="description" content="初めてHTMLを勉強するサイトです。">
    <title>プログラミングの勉強</title>
</head>
<body>
    <table border="1">
        <caption>男の子の小学生の習い事</caption>
        <tr>
            <td><b>ランキング</b></td>
            <td><b>習い事</b></td>
            <td><b>平均月謝</b></td>
        </tr>
        <tr>
            <td>1</td>
            <td>プログラミング</td>
            <td>3,000円</td>
        </tr>
        <tr>
            <td rowspan="2">2</td>
            <td>サッカー</td>
            <td>5,000円</td>
        </tr>
        <tr>
            <td>スイミング</td>
            <td>4,000円</td>            
        </tr>
        <tr>
            <td rowspan="2">3</td>
            <td>野球</td>
            <td>2,000円</td>
        </tr>
        <tr>
            <td>そろばん</td>
            <td>1,000円</td>
        </tr>

        <tr>
            <td colspan="3">以降は人気なし</td>
        </tr>
    </table>
</body>
</html>
```
R の Xaringan でスクロールできるようにする方法

Xaringan でスライドのスクロールができるようにする方法

1.  libs\remark-css-0.0.1 (Xaringan テンプレートで Rmarkdown を作成した場所に自動的に作られる) に入ってある CSSファイルをRディレクトリ（Rmarkdown のファイルがあるところ）にコピペする 
1.  CSSファイルを開き、以下のコードをコピペ、保存し、適当に名前を付ける (今回は "Scrollable.css")
    -   .remark-slide-scaler {
    overflow-y: auto;
}
1. タイトルにある lib_dir: libs を削除する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116948/e1bc520d-0b52-b6c0-143c-1f21c319e44c.png)

1. 代わりに、以下のようにCSSを指定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116948/55c28790-e59c-c6b7-6087-061a5da58e13.png)


これでスクロールが可能になります（スライド内容がはみ出してしまう場合）。
Python 逆ポーランド記法の電卓


逆ポーランド記法（Reverse Polish Notation;RPN)の電卓です。
chmod +x revp.pyで実行権を付けて動かして下さい。
引数の式はコマンドラインに、`revp.py 10 20 +`のように、スペースで区切って入力して下さい。
エラーチェックはしてませんので、誤った文字列を渡すと、pythonがエラーを返します。

```revp.py
#!/usr/bin/python3
import sys
stack=[]
s=sys.argv[1:]

while(s):
  e=s[0]
  if (e=='+'):
    stack.append(stack.pop()+stack.pop())
  elif (e=='-'):
    a=stack.pop()
    stack.append(stack.pop()-a)
  elif (e=='*'):
    stack.append(stack.pop()*stack.pop())
  elif (e=='/'):
    a=stack.pop()
    stack.append(stack.pop()/a)
  else:
    stack.append(float(e))
  s=s[1:]

print(stack.pop())

```

実行例

```
$ revp.py 10 20 +
30.0
$ revp.py 10 20 /
0.5
$ revp.py 10 20 - 30 +
20.0
$ revp.py 10 20 30 + -
-40.0
```
09.箇条書きリスト

```index.html
<!-- 解答例 -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Jun Shimono's Webサイト</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
<header>
    <h1>Jun Shimono's Webサイト</h1>
    <nav>
        <ul>
            <li>ホーム</li>
            <li>このサイトについて</li>
            <li>プロフィール</li>
        </ul>
    </nav>
</header>
<main>
    <section>
        <h2>私のおいたち</h2>
        <p>広島市南区出身。24歳からスタプロで先生をやっていて、26歳で<strong>大臣</strong>に就任。</p>
        <p>その後、様々な分野で大臣と呼ばれています。<br>現在は、生徒のみんなが楽しく授業できるような教材を作っています。<br>検定問題は私が制作しました。</p>
        <p>いつも温めています。</p>
    </section>

    <section>
        <h2>私の得意なこと</h2>
        <p>ゲームが得意です！</p>

        <hr>
        <p>経験がある言語</p>
        <ul>
            <li>プログラミン</li>
            <li>Scratch</li>
            <li>マインクラフト</li>
            <li>HTML/CSS</li>
        </ul>
    </section>
</main>

<footer>
    <p>Copyright @ Jun Shimono All Rights Reserved.</p>
</footer>
</body>
</html>
```

```style.css

body {
    background-color: skyblue;
}

h1 {
    color: red;
}

h2 {
    color: blue;
}

ul li {
    color: gray;
}
```