OmniAICreator/Qiita-1.07M huggingface dataset:
システム開発の提案における概算見積書の作り方

「システム開発の提案における概算見積書の作り方」と題し、弊社で行っている概算見積書の作り方の記事となります。会社によって様々な算出方法があるかと思われますので、当方個人の備忘録として残します。

## 1.必要機能の洗い出し
###### お客様からヒアリングした情報を元にシステムに必要な機能一覧を作成します。

今回は、某サイトを参考に見積もりを作成していきます。

##### 手順
1. 分類の粒度を設定します
    a. 大分類 = 操作する人物(ロール)
    b. 中分類 = 画面（今回はこちらを省いています）
    c. 小分類 = 機能
1. 機能の項目に機能の詳細を記述

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1263502/066b165b-7341-2ddf-9e27-25ec8091c015.png" width="50%">


## 2.機能ごとにざっくりとした工数を考える
###### 開発において一番工数が掛かるのは製造・単体になります。
製造・単体の工数を基準に要件定義・設計・結合テスト・総合テストの工数を洗い出します。

前提として、製造・単体の工数(人日)を基準として割合を設定する
- 要件定義では製造・単体の工数×0.2
- 設計では製造・単体の工数×0.5
- 結合テストでは製造・単体の工数×0.5
- 総合テストでは製造・単体の工数×0.1

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1263502/df172993-918e-d564-b6e0-e480f36b1ad2.png" width="50%">

##### このようにして、機能ごとに大まかな工数(人日)を算出することができます
概算見積もり時に機能単位の正確な工数を考慮することは難しいため、小(１日)・中(３日)・大(５日)・特大(10日)のようにあらかじめ設定しておく良いでしょう。

## 3.スケジュール全体に必要な工数(人月)を洗い出す
###### 開発工程ごとの総工数を一ヶ月の稼働日数(20日)で割り、必要な工数(人月)を洗い出す
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1263502/09c9caeb-0198-4101-a83e-6a5fae47d07a.png" width="60%">

洗い出した開発工程ごとの工数(人月)
- 要件定義の総工数 = 30.8(人日) = 1.54(人月)
- 設計の総工数 = 77(人日) = 3.85(人月)
- 製造・単体の総工数 = 154(人日) = 7.7(人月)
- 結合テストの総工数 = 77(人日) = 3.85(人月)
- 総合テストの総工数 = 15.4(人日) = 0.77(人月)
- 全工程の総工数 = 354.2(人日) = 17.71(人月)

例えば、製造・単体テストの場合、下記のような計算となる
人日(154)/稼働日数(20日)=人月(7.7）

##### 上記の工数(人月)を参考に山積みを作成する

## 4.山積みを作成する
###### (今回はアジャイル開発を想定しています)
##### お客さんの希望しているスケジュールに寄り添って、いつのタイミングでどのロールの人物が何人月アサインするかを当てはめていく

前提として、役割と工程は下記で設定しています
- PMとPLで要件定義・設計を担う
- PG(FE・BE)は製造・単体を担う
- テスターは結合テスト・総合テストを担う

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1263502/d22721fc-d599-86b3-f191-62d3d31df51f.png" width="60%">

##### 手順
1. 役割に必要なプロジェクトの役職を記載する
1. 役割ごとに作業内容を記載する
1. 必要な期間を1ヶ月単位で記載する
1. 「3.スケジュール全体の必要な工数(人月)を洗い出す」で計算された総工数と山積みの工数合計がなるべく同じになるように工数を記載する
1. 役割ごとに単価を記載する

##### 売価の合計が概算見積の価格となります。
## 5.概算見積の価格
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1263502/3aaf37be-7c9c-8c74-b93c-0586794bde48.png" width="60%">

ここまでが「システム開発の提案における概算見積書の作り方」となります。

今回の方法の概算見積書の作成はあくまで一例ですので、他の見積書作成の仕方がありましたら、ご教示いただければと思います。

長文駄文失礼しました。
Ender3 で CR Touch

# Ender3 で CR Touch がうまく動かない

## 困ったこと

Ender3 に CR Touch を付け、ファームウェアを書き換えたのだが、
CR Touch のマニュアルに書かれている通りに設定を行ってもオートレベリングが正常動作しない。
（1点目、中央のレベリングはできるが、2点目がプラットフォームからはみ出した位置でレベリングしようとする）

## 問い合わせを実施

CR Touch は Amazon で購入したので Amazon から問い合わせてみたところ、
サポートから以下のような回答をもらった。

> このファームウェアにフラッシュしたかどうかを確認してください。
Ender-3 Marlin2.0.1 - V1.1.2 - ALT - TMC2225
ダウンロード方法:
https://www.crealitycloud.cn/en/software-firmware/other
CR Touch--→Ender 3--→Mainboard Version: V4.2.7

上記ファームウェアを書き込んだところ、オートレベリングできるようになりました。
でも、いつも https://www.creality.com/ からファームウェアをダウンロードしていたけど、どういうこと？

念のため creality.com からダウンロードするのは適切でないのか、質問中。

## 回答を受領 (2023/03/07追記)

以下の回答をもらった。

* どちらのサイトも CREALITY ブランドであり基本的には中身は同じ。
* creality.com はファームウェアがたくさん登録されているが、整理されておらず正しいものを見つけるのが難しい
* crealitycloud.cn は最新に整理されており目的のものが探しやすい

とのこと。
ローカル環境で動くVue.jsアプリをhttpsで起動する方法



## 背景

* ローカル環境で起動するVue.jsアプリと外部サービス(認証系)を連携しようとした際、`https`での接続を求められるケースがあったため。

## 事前準備

* `Vue.js`,`Vue CLI`をインストールする。

  バージョン

  ```shell
  vue --version
  @vue/cli 5.0.8
  ```

* `Vue.js`テストプロジェクトを準備する。

  ```shell
  vue create vue-test
  ```

  ※`Vue3`を指定する。

## 設定

* プロジェクト直下に作成される`vue.config.js`を修正する。

  `devServer`部分を追記する。

  ```javascript
  const {defineConfig} = require('@vue/cli-service')
  module.exports = defineConfig({
      transpileDependencies: true,
      devServer: {
          https: true
      }
  })
  ```

## 動作確認

* アプリを起動する

  ```shell
  npm run server
  ```

  ※`https://localhost`でアプリが起動する
ColabでPyCairoを使う

Google Colabで趣味のSVGお絵描きに[PyCairo](https://pycairo.readthedocs.io/en/latest/index.html)を使おうとして、import cairoだけでは使えず、pip install pycairoも失敗しましたが次のようにしたらインストールにも成功しました。ご参考までに。

```python
! sudo apt install libcairo2-dev pkg-config python3-dev
! pip install pycairo
```

参考
https://github.com/krassowski/jupyter-manim/issues/28#issuecomment-1121631623
InfluxQL: 過去 24 時間からレコードを選択しますか?

これはクエリです：

SELECT mean("value") FROM "autogen"."°C" WHERE ("entity_id" = 'shelly_1l_our_room_device_temperature') AND $timeFilter GROUP BY time($__interval) fill(null)

同じデータを使用して2番目のクエリを追加しようとしていますが、24時間遅れています

多くのことを試しましたが、うまくいかないようです:

SELECT mean("value") FROM "autogen"."°C" WHERE ("entity_id" = 'shelly_1l_our_room_device_temperature') AND DATE_SUB(NOW(), INTERVAL 24 HOUR) GROUP BY time(20s) fill(null)


SELECT mean("value") FROM "autogen"."°C" WHERE ("entity_id" = 'shelly_1l_our_room_device_temperature') AND time >= now() - 48h and time <= now() - 24h GROUP BY time($__interval) fill(null)

そんなの構文は私には良さそうですが、データ自体に問題がある可能性があります。

確認のため、以下をお試しいただけますでしょうか。

過去 24 時間のデータがあるかどうかを確認する

SELECT "value" FROM "autogen"."°C" WHERE ("entity_id" = 'shelly_1l_our_room_device_temperature') AND time >= now() - 24h

集計を適用する

SELECT mean("value") FROM "autogen"."°C" WHERE ("entity_id" = 'shelly_1l_our_room_device_temperature') AND time >= now() - 24h GROUP BY time(20s) FILL(null)
Go言語のジェネリック機能について

ジェネリック機能とは、汎用的なデータ型や関数を実現するための機能であり、型安全かつコンパイル時にエラーを検出することができます。
以下、簡単なサンプルコードです。

```go
type Stack[T any] []T

func (s *Stack[T]) Push(v T) {
    *s = append(*s, v)
}

func (s *Stack[T]) Pop() (T, error) {
    if len(*s) == 0 {
        return nil, errors.New("stack is empty")
    }
    v := (*s)[len(*s)-1]
    *s = (*s)[:len(*s)-1]
    return v, nil
}
```
このコードでは、`Stack`構造体に型パラメータ`T` を指定し、`Push` メソッドと `Pop` メソッドを定義しています。
`Push` メソッドは、スタックに要素を追加するための関数であり、`Pop` メソッドは、スタックの一番上にある要素を取り出すための関数であることがわかります。

### Stack[T] 型のスタック構造体を使って、整数型のスタックを作成する例

```go
func main() {
    // 整数型のスタックを作成
    var s Stack[int]

    // スタックに要素を追加
    s.Push(1)
    s.Push(2)
    s.Push(3)

    // スタックから要素を取り出し
    for len(s) > 0 {
        v, err := s.Pop()
        if err != nil {
            fmt.Println(err)
            break
        }
        fmt.Println(v)
    }
}
```

このコードでは、まず `Stack[int]` 型のスタックを作成し、`Push` メソッドを使って要素を追加しています。
その後、`Pop` メソッドを使ってスタックの一番上にある要素を取り出し、`fmt.Println` を使って出力しています。
`Pop` メソッドは、取り出す要素がなくなるまで繰り返し呼び出され、エラーが発生した場合はエラーメッセージを出力してループを抜けるようになっています。

### Stack[T] 型のスタック構造体を使って、文字列型のスタックを作成する例

```go
func main() {
    // 文字列型のスタックを作成
    var s Stack[string]

    // スタックに要素を追加
    s.Push("foo")
    s.Push("bar")
    s.Push("baz")

    // スタックから要素を取り出し
    for len(s) > 0 {
        v, err := s.Pop()
        if err != nil {
            fmt.Println(err)
            break
        }
        fmt.Println(v)
    }
}
```

このコードは、整数型のスタックを作成する例とほとんど同じですが、`Stack[string]` 型のスタックを作成しています。
`Push` メソッドを使って文字列型の要素を追加し、`Pop` メソッドを使ってスタックの一番上にある要素を取り出しています。`fmt.Println` を使って出力する際も、文字列型に合わせて出力しています。

### Stack[T] 型のスタック構造体を使って、マップ型のスタックを作成する例

```go
func main() {
    // マップ型のスタックを作成
    var s Stack[map[string]int]

    // スタックに要素を追加
    s.Push(map[string]int{"foo": 1, "bar": 2})
    s.Push(map[string]int{"baz": 3, "qux": 4})
    s.Push(map[string]int{"quux": 5, "corge": 6})

    // スタックから要素を取り出し
    for len(s) > 0 {
        v, err := s.Pop()
        if err != nil {
            fmt.Println(err)
            break
        }
        fmt.Println(v)
    }
}
```

このコードは、マップ型の要素を持つスタックを作成しています。
`Stack[map[string]int]` 型のスタックを作成し、`Push` メソッドを使ってマップ型の要素を追加しています。
各マップには、キーと値が文字列型と整数型のペアで格納されています。

`Pop` メソッドを使ってスタックの一番上にある要素を取り出す際には、`map[string]int` 型で要素を受け取っています。`fmt.Println` を使って出力する際も、マップ型に合わせて出力しています。

このように、ジェネリック機能を使って定義したスタック構造体は、任意のデータ型に対応することができます。マップ型の例でも、整数型や文字列型の例と同様にスタックを作成することができます。

https://go.dev/doc/tutorial/generics
rex0220 計算式プラグイン テーブルに月カレンダー

rex0220 計算式プラグインで、テーブルに指定月のカレンダーを作ってみます。

# 概要

指定月の日数分のテーブル行を作成して、各行に日付を設定します。

- 月の日数分のテーブル行
- 月～金のみのテーブル行


![2023-02-27_18h45_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/0a07786d-086e-233a-5d90-96feaae6efa7.png)

# 操作例（月～金の曜日のテーブル行）

![2023-02-27_18h53_28.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/1949f34d-d513-9278-c87c-9c5c3801cd8a.gif)

# プラグイン設定（月の日数分のテーブル行）

- 年月：　月の１日目に自動変換
- テーブル：　年月の最終日で、テーブル行数を指定
- 日付：　年月にテーブル行位置を加算
- 曜日：　日付を 0 ～ 6 の曜日に変換後、"日月火水木金土"の位置で曜日に変換

~~~.js
// 年月
DATE_FORMAT(年月,"YYYY-MM-01")
// テーブル
DATE_ENDOF(年月, "month", "DD")
// 番号
ROWNO(テーブル)+1
// 日付
DATE_ADD(年月,ROWNO(テーブル),"day")
// 曜日
MID("日月火水木金土",DATE_FORMAT(日付,"e")+1,1)
~~~

![2023-02-27_18h58_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/b9e3e89d-d854-9794-6635-b1b4ebdf1529.png)

# プラグイン設定（月～金のみのテーブル行）

- 年月：　月の１日目に自動変換
- テーブル：　年月の最終日から土日の日数を引いて、行数を算出
- 日付：　前行が金曜の場合、+2。
- 曜日：　日付を 0 ～ 6 の曜日に変換後、"日月火水木金土"の位置で曜日に変換

~~~.js
// 年月
DATE_FORMAT(年月,"YYYY-MM-01")
// テーブル
LET(x,DATE_FORMAT(年月,"e"),
  y,DATE_ENDOF(年月, "month", "DD"),
  y-SWITCH(y,
    29,SWITCH(x,0,9,6,9,8),
    30,SWITCH(x,0,9,5,9,6,10,8),
    31,SWITCH(x,0,9,4,9,5,10,6,10,8),
    8)
)
// 番号
ROWNO(テーブル)+1
// 日付
LET(r,ROWNO(テーブル),
  IF(r=0,
    DATE_ADD(年月,TR_SUM(r,SWITCH(DATE_FORMAT(年月,"e"),0,1,6,2,0)),"day"),
    DATE_ADD(SUBTABLE(日付,r-1),
       IF(DATE_FORMAT(SUBTABLE(日付,r-1),"e")=5,3,1),"day")
  )
)
// 曜日
MID("日月火水木金土",DATE_FORMAT(日付,"e")+1,1)
~~~

![2023-02-27_19h07_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/4aa34ab0-1a8b-a4ee-d475-332a1c4ee9cd.png)


## 月の始まりの曜日と土日の日数

※土曜日始まりで30日の月は、土日の日数が 10 日
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/8faaaa18-b17b-d757-f854-f26560677250.png)

※ 各曜日の始まりと土日の日数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/d869ab52-5273-4c54-43d7-ea06f4d6db43.png)
【C#】たくさんHTTPリクエストを出して全て終わるまで待つ

C#は素人なのでよくわかりません。
PHPerなので非同期もよくわかりません。
よくわからないの二乗でさっぱりわかりません。


やりたいことはタイトルどおりなんだけど、PHPで書くとこうです。

```php:PHP
	// URL
	$urls = {
		"https://example/com/a",
		"https://example/com/b",
		"https://example/com/c",
		……
	}

	$client = new \GuzzleHttp\Client();
	$promises = [];

	// リクエスト出す
	foreach ($urls as $url) {
		$promises[] = $client->getAsync($url);
	}

	// 全部終わるまで待つ
	$responses = \GuzzleHttp\Promise\all($promises)->wait();
```

これをAzure Functionsとかでやりたかったわけです。

探してみたんだけど、何故か複数リクエストを出す場合という情報が全然見当たりません。
[よく見かける実装](https://qiita.com/rawr/items/f78a3830d894042f891b)だと`await HttpClient.GetAsync(url)`とかなんだけど、これだとURLひとつひとつにリクエストするたびに待機するってことだよね？

ようやく[ここ](https://qiita.com/takutoy/items/d45aa736ced25a8158b3#whenall-%E3%81%99%E3%82%8B)でそれっぽいのを見つけたので、これを参考に作った。

```cs:C#
	
	// URL
	string[] urls = {
		"https://example/com/a",
		"https://example/com/b",
		"https://example/com/c",
		……
	}

    var client = new HttpClient();
    List<Task> promises = new List<Task>();

	// リクエストを投げる
    foreach (string url in urls) {
        promises.Add(client.GetAsync(url));
    }

    // 全部終わるまで待つ
    Task.WaitAll(promises.ToArray());
```


さて、とりあえずこれで一応動いたんだけど、本当にこれが適切な実装なのかはよくわからない。

どうも[このあたり](https://qiita.com/skitoy4321/items/dc6bd2b62b62c2414642)を見ると[SNATが爆発しそう](https://qiita.com/superriver/items/91781bca04a76aec7dc0)な気配を感じるのですが、ではどうすればいいのかがよくわかりません。
[HttpClientHandler.MaxConnectionsPerServer](https://learn.microsoft.com/ja-jp/dotnet/api/system.net.http.httpclienthandler.maxconnectionsperserver?view=netcore-2.0#System_Net_Http_HttpClientHandler_MaxConnectionsPerServer)を指定すればいいのか、そうするとそれ以上のリクエストは待たされるのか破棄されるのか。
そもそもPHPだったころは何も考えなくてもSNAT問題とか起きたことがないんだけど、どうしてC#になった途端に死ぬのか。

`Task.WaitAll()`と`await Task.WhenAll()`の違いもわかりません。
あとどうして[これがデッドロックする](https://learn.microsoft.com/ja-jp/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming#%E3%81%99%E3%81%B9%E3%81%A6%E9%9D%9E%E5%90%8C%E6%9C%9F%E3%81%AB%E3%81%99%E3%82%8B)のか全くわからない。

調べればわかるのかもしれないけど面倒になったので解決もせずにここで終わり。
fetchメソッドが通信成功時にfulfiled状態のpromiseオブジェクトを返すことの確認

<p>javascript初学者が一度はつまづくであろう、非同期処理。</p>
<p>promiseやらfetchやらを使う際に思ったように動かないことをいったい何度繰り返しているか・・・。</p>
<p>例に漏れず私も初学者であるので、日々頭を悩ませているわけですが、fetchおよびpromiseまわりで気づきがあったので同じように詰まった人向けの記録として書き残しておきます。</p>
<p>基礎的な内容でありながら、初学者ゆえ間違った理解をしている部分もあるかもしれませんので、なにかありましたらぜひご指摘ください。</p>

<h2>promiseとは</h2>
<p>そもそもpromiseとは何なのかを振り返っておきます。</p>
<ul>
<li>promiseは非同期処理の結果を成功（resolve)か失敗(reject)で返すオブジェクト</li>
<li>処理状態をfulfiled（正常終了）、pending（処理中）、rejected（拒否）というstatusで示す</li>
<li>通常はnew Promise()としてインスタンスを使って生成する</li>

</ul>
<p></p>

<h2>promiseの基本的な処理</h2>
<p>例えばpromiseインスタンスに関しては以下の様なコードを良くみるかと思います。</p>

```javascript:test.js
const promise = new Promise( (resolve)=>{
    console.log("最初");
    resolve();
} );
promise.then( ()=>{ console.log("最後"); } );
```
<p>変数promiseに格納したpromiseインスタンスをresolve()した上で、変数promiseに対してthen()の処理を行う様に指示しています。</p>
<p>これをresolve()を書かないで実行すると、thenメソッドの中の処理は動作しません。</p>
<p>なぜならthen()はresolve状態のpromiseオブジェクトでないと処理が発火しないからです。</p>

<h2>fetch()の基本的な処理</h2>
<p>続いてfetch()のよくある形のコードを見てみます。</p>

```javascript:test.js
url = "https://pokeapi.co/api/v2/pokemon/pikachu/"
const data = fetch( url )
  .then( (response) => { return( response.json(); ) } )
  .then( (data) => { console.log(data); } );
```

<p>※ エラーの処理は省略しています</p>
<p>fetchメソッドはAPIのURLを引数にとって、promiseオブジェクトを返します。</p>
<p>返されたpromiseオブジェクトに対してthenメソッドを書くことでjson形式のデータを取得することができるわけですね。</p>
<p>ここで先ほどpromiseオブジェクトに対してthenメソッドの処理をすることについて述べた内容を思い出します。</p>
<p>「thenメソッドはresolve状態のpromiseオブジェクトに対してのみ動作する」のでした。</p>
<p>これを踏まえて考えると「fetchメソッドから返ってくるpromiseオブジェクトは、resolve状態なのではないか」と考えられます。</p>



<h2>確認してみる</h2>
<p>実際に単純なコードを書いて確認してみます。</p>

```javascript:test.js
url = "https://pokeapi.co/api/v2/pokemon/pikachu/"
const test = fetch( url ); //変数testにpromiseオブジェクトを格納
console.log( test );

setTimeout( () => { console.log( test ); }, 2000 );
```

<p></p>

<p>実行結果</p>

```
Promise {<pending>}

Promise {<fulfilled>: Response}
```

<p>fetchメソッドを格納した変数testをそのままコンソールに出力したときはpending状態のpromiseオブジェクトを返している一方、setTimeoutで一旦タスクキューへの登録を遅らせてからconsole.logを使ってpromiseオブジェクトを呼び出すとfulfiled状態となっていることがわかります。</p>
<p>つまりfetchはpromiseを返す際に、サーバーからのレスポンスの取得が完了するとfulfiled状態となるっぽいことがわかります。</p>
<p>これを理解した上でpromiseを扱わないと、なぜかundefinedを返される、という罠にハマりつづけて悲しい結末を迎える様です。</p>

<h2>fetchの中でresolve()をしなくて良い理由</h2>
<p>上で述べた様にfetchは通信が成功しレスポンスの取得が完了するとfulfiledのpromiseオブジェクトを返す、という挙動をする様です。</p>
<p>なので、fetchの後にresolveの処理をしなくてもそのまま続けてthenチェーンを書くことができる、というわけなのですね。</p>
<p>fetchを触り始めの頃は、「fetchってpromiseオブジェクトを返しているはずだし、なんでthenメソッドをいきなりチェーンで書くことができるねん、、」と混乱しましたが、こういうことだったみたいです。</p>
DatabricksにおけるAmazon Rekognitionの活用(PrivateLink環境編)

先日こちらの記事を書きました。

https://qiita.com/taka_yayoi/items/136fc8f72157edea36b2

ただ、上の記事の手順だけでは[PrivateLink環境](https://qiita.com/taka_yayoi/items/c6bdbb6452f6a0895961)では動作しませんので、PrivateLinkのDatabricks環境でRekognitionを使用する際に必要な手順をまとめます。

一言でいうと「Rekognitionのエンドポイント」を作成する必要があります。

1. AWSマネジメントコンソールで**VPC**にアクセスし、**エンドポイント**に移動します。
1. **エンドポイントの作成**をクリックします。
1. エンドポイント名を入力し、サービスカテゴリでは**AWSのサービス**を選択し、サービスに`rekognition`と入力して検索します。
1. `com.amazonaws.ap-northeast-1.rekognition`が表示されるので、これを選択します。
![Screenshot 2023-02-27 at 18.59.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/399e77ea-ca03-b411-3f1c-dfe07a52d997.png)
1. VPCはDatabricksワークスペースがデプロイされているVPCを選択し、サブネットは[こちら](https://qiita.com/taka_yayoi/items/1ca54463469df05dd3ee#sts-vpc%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9%E3%82%A8%E3%83%B3%E3%83%89%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88)で説明されているように、ワークスペース用の2つのサブネットを選択します。
1. セキュリティグループもワークスペース用に作成したセキュリティグループを選択します。
![Screenshot 2023-02-27 at 19.01.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/717e088a-ce8a-74ea-cb05-94486fa12d1c.png)
1. エンドポイントが**使用可能**になるまで待ちます。
![Screenshot 2023-02-27 at 19.11.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d16f81a3-ce56-9ac5-c448-be33de2c7555.png)

これでPrivateLink環境でもRekognitionを利用できるようになります。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
[Android/Kotlin] Enum classの型を評価するときにハマった

## はじめに
地味にハマったのでメモと解説を。

## 何が起こったか
レスポンスに含まれているステータス（今回は試合結果：勝ち負け引き分けの三種類）毎に表示を切り替えたい。
Enumで列挙型の定数を羅列し、その名前で列挙型定数をゲットすれば良さそうだ。
ということで、Enum classとそのメソッド（valueOf()）を使おうとしたら、valueOf()が使えなかった。

あれ？使えないんだっけ？？？

## こうした

```MatchResult.kt
enum class MatchResult(val result: String) {
    WIN("win"), //勝ち
    LOSE("lose"), //負け
    DRAW("draw"); //引き分け

    companion object {
        fun from(search: String): MatchResult = requireNotNull(values().find { it.result == search }) {
            "No TaskAction with value $search"
        }
    }
}

```

## Enumclassとは
### Documentation
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-enum/
Go言語で複数のMiddlewareを綺麗に取り扱う

APIサーバーを開発する際、複数のMiddlewareを実装しなければならない場合があると思います。普通に実装すると、以下のようになると思います。

```golang:router.go
func NewRouter() *http.ServeMux {
    mux := http.NewServeMux()
    h := handler.NewHandler()

    mux.Handle("/", middleware.Middleware1(
                        middleware.Middleware2(
                            middleware.Middleware3(
                                h))))
    ...

    return mux
}
```


このように、通常の書き方ではMiddlewareの数が増えれば増える程ネストが深くなっていき、可読性が損なわれていきます。今回は、Middlewareの数が増えても可読性をある程度確保できないかと思い、調査をしてみました。

## 解決策
解決策を一言で表すと、「Middlewareをチェインする関数を別途用意する」になります。

```golang:utils.go
// Middleware型を定義
type Middleware func(http.Handler) http.Handler

// Middleware型のスライスでハンドラーをWrap
func ChainMiddleware(h http.Handler, ms ...Middleware) http.Handler {
	if len(ms) < 1 {
		return h
	}
	wrapped := h
	for i := len(ms) - 1; i >= 0; i-- {
		wrapped = ms[i](wrapped)
	}
	return wrapped
}
```

<br>
この用意した関数を利用すると、下記のようにルーティングを実装できます。

```golang:router.go
func NewRouter() *http.ServeMux {
    mux := http.NewServeMux()
    h := handler.NewHandler()

    mux.Handle("/", middleware.ChainMiddleware(
        h,
        middleware.Middleware1,
        middleware.Middleware2,
        middleware.Middleware3,
    )
    ...

    return mux
}
```

<br>
コードの量自体にはほとんど変化がありませんが、可読性は上がっていると思います。さらに、複数のパターンで全く同じMiddlewareが呼び出される場合には、Middlewareのスライスを変数に格納することで、コードの量を大幅に減らすことができます。

```golang:router.go
func NewRouter() *http.ServeMux {
    mux := http.NewServeMux()
    h := handler.NewHandler()
    ms := []middleware.Middleware{
        middleware.Middleware1,
        middleware.Middleware2,
        middleware.Middleware3
    }
    mux.Handle("/", middleware.ChainMiddleware(h, ms)
    mux.Handle("/p1", middleware.ChainMiddleware(h, ms)
    mux.Handle("/p2", middleware.ChainMiddleware(h, ms)
    ...

    return mux
}
```

## 注意点
ただし、呼び出されるMiddlewareの順番は、スライスに格納される順番に依存するので、ネストが浅い順にスライスに格納する必要があります。上記の例を参考にしてみて下さい。

## 参考にした記事
https://www.mohitkhare.com/blog/go-middleware/

https://medium.com/@chrisgregory_83433/chaining-middleware-in-go-918cfbc5644d
令和５年基本情報技術者試験について

# 情報処理技術者試験とは
高度IT人材となるために必要な基本的知識、技能をもち、実践的な活用能力を身につけた者を認定するための試験。

科目Aと科目Bがあり、両科目で合格点を取ることで、試験の合格となります。
科目Aは２０２２年までの午前試験と同範囲ですが、科目Bはそれまでの午後試験とは大きく異なる試験となりました。

## 2023年の試験制度改定ポイント

ほぼ毎日受験可能になったそうです。また、リテイクポリシーといって、再受験規定の範囲内であれば何度も再受験可能となりました。ありがたいですね。


## 科目Bの出題範囲

擬似言語分野とセキュリティ分野です。
具体的には、

＊　プログラミング全般
＊　プログラムの処理の基本要素
＊　データ構造とアルゴリズム
＊　プログラミングの諸分野への適用
＊　情報セキュリティの確保

科目Bは科目Aの延長線上ではありません。出題する内容も大きく異なるため、科目Bに特化した試験対策が必要です。


## 試験形式

科目Aと科目Bの評価点が６００点以上の場合に合格となります。
試験時間、出題形式、出題数は以下のとおりです。

||科目A|科目B|
|:--|:--|:--|
|試験時間|90分|１００分|
|出題形式|多肢選択式（四肢択一）|多肢選択式|
|出題数|６０問|２０問|
Laravel10　ファイルダウンロード方法


# ファイルをstorageに用意

```php
Laravel
   ┗ storage
        ┗ app
           ┗ public
               ┗ susr.xlsx
```
# コントローラーを用意する

```php
namespace App\Http\Controllers;

use Illuminate\Support\Facades\Storage;

class FilesController extends Controller
{
    public function download()
    {
        $filePath = 'public/susr.xlsx';
        $fileName = 'susr.xlsx';
        
        $mimeType = Storage::mimeType($filePath);
            $headers = [['Content-Type' => $mimeType,
                  'Content-Disposition' => 'attachment; filename*=UTF-8\'\''.rawurlencode($fileName)
        
        return Storage::download($filePath, $fileName, $headers);
    }
}    
```
# Bladeファイルを用意する
```php
<a href="{{ route('download') }}">ダウンロード</a>
```

# route
```php
 Route::get('/excel/download', [ExcelTargetUserController::class,'download'])->name('download'); 
```
フィクションなどから拾う情報処理用語 その41 フィルタリング (秘密戦隊ゴレンジャー?)

ピクシブ百科事典にはいろいろな記事が載っている。でペギー松山に関しては以下のページに記述がある。

https://dic.pixiv.net/a/%E3%83%9A%E3%82%AE%E3%83%BC%E6%9D%BE%E5%B1%B1

その中にこういう文章がある。

敵に捕らわれて催眠攻撃を受けたりするなどピンチ描写も多く、その喘ぎ声は特撮番組とは思えない官能的なものである。

そしてこれを読んで以来、邪念によってフィルタリングされるのか、「秘密戦隊ゴレンジャー」でのペギー松山やモモレンジャーのピンチでの叫びがそういうのに聞こえてしまうのであーる。

だが、何故か同じ俳優が演じている「バトルフィーバーJ」でのダイアン・マーティンやミスアメリカ(初代)の声はそうは聞こえない。ところでオープニングで汀マリアがクルクル回るのは萩奈緒美さんではないでしょうねえ。
ロリポップサーバーとSSH通信をする

# ロリポップサーバーとSSH接続をしたい！
## 何故か公式で紹介されている方法が通用しない！？
何故か不思議なことに公式が出してるSSH通信の方式ではこんなエラーがおきてしまう！？なんでぇ。。。
[公式のssh接続マニュアル](https://lolipop.jp/manual/user/ssh/)
```sh
Unable to negotiate with 133.***.**.***port 2222: no matching host key type found. Their offer: ssh-rsa,ssh-dss
```
## エラーの真相
エラーメッセージの招待ですが、ssh接続を確立しようとした際に、サーバー側で提供されたホストキータイプがクライアント側に存在しないからではないかな？っておもいます。

## 解決
解決策としては
ssh接続を確立する際に、ホストキーのアルゴリズムを指定する！！って感じですね。
以下一例なんですけど、ロリポップの場合はsshは2222番がポートとして割当されてるので、これでうまくいきました！
```sh
ssh -o HostKeyAlgorithms=ssh-rsa <ユーザー名>@<ホスト名> -p 2222
```

## 最後に
厚かましいかもしれないですが、少しでも役に立ったらいいねやシェアの方よろしくおねがいします。
Twitterは結構いろんなことつぶやいているので、ぜひともffになってほしいです！
それでは今日はここで！
お疲れさまでした！
【UiPath】ラストチャンス！クラシックフォルダーからモダンフォルダーへの移行方法 #1

# はじめに
UiPath Orchestratorをお使いの方は、ご存知かと思いますが、Orchestratorの機能である「クラシックフォルダー」がいよいよ廃止されます。
これまで小さな機能の廃止は何度かあったかと思いますが、UiPathにおける主要機能の廃止は、おそらく初めてなのではないでしょうか？何も対策していない場合は、必ず大きな混乱が発生するので、まだ何も対策を考えていない方は、すぐ始めてください！

# クラシックフォルダーとモダンフォルダー
Orchestratorにおける「フォルダー」機能とは、プロセス、ジョブ、キュー、アセット、ロボットなどのリソースを分離することができる機能です。例えば、組織・チーム単位にフォルダーを分けることで、それぞれのリソースを分けて管理することができます。
「クラシックフォルダー」は、オンプレ版OCの2019.10に正式にリリースされた機能ですが、それ以前は、「組織単位（Organization Units：OU）」という名称の機能として存在していました。OUはプレビューの位置づけのため、configファイルを修正しないと有効化されない機能でしたので、使用している方は少なかったと思います。

一方、「モダンフォルダー」のリリースも2019.10とクラシックフォルダーと同じタイミングでした。
クラシックとモダンの両方が同じタイミングでリリースされるのであれば、モダンしか使わないと思われがちですが、リリース当時、モダンフォルダーはUnattendedが使用できないなど制約があり、当時はクラシックフォルダーとモダンフォルダーの両立が必要でした。
（クラシック・モダンの両方を使うと管理が面倒なので、クラシックフォルダーに統一していた方も多いかと思います。）

しかしながら、リリースを重ねるごとにモダンフォルダーも進化し、現在（v2022.10）ではモダンフォルダーは機能的に完全にクラシックを追い越しています。

![機能比較1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/9162a2e1-40a4-667d-258f-6f706a9ce739.png)

v2019.10時点の機能比較

https://docs.uipath.com/orchestrator/lang-ja/v2019/docs/classic-folders-vs-modern-folders#feature-comparison

v2022.10時点の機能比較

https://docs.uipath.com/orchestrator/lang-ja/docs/classic-folders-vs-modern-folders#feature-comparison


# 廃止までの流れ
UiPathの各製品サービスについて、機能の廃止はドキュメントポータルにて情報が公開されています。

https://docs.uipath.com/overview-guide/lang-ja/docs/deprecation-timeline#orchestrator

対象の機能は、まず「非推奨」のカテゴリに分類され、しばらくすると「削除」のカテゴリに移行します。
「削除」に分類されると、Automation Cloudならリリース時点で機能が削除されます。
オンプレ版の場合は、バージョンアップをしなければ、対象の機能を使い続けることができますが、バージョンにもサポート期間が設定されているため、サポート外の製品はバージョンアップをすることを推奨します。ということは、オンプレ版OC（v2022.10）の延長サポートは2025年11月14日までなので、ここまではクラシックフォルダーは使用可能です。

2021年10月・・・非推奨の発表
2022年4月 ・・・削除の発表
2022年10月・・・非推奨化
2023年4月 ・・・削除の実施

では、Automation Cloudでは具体的にいつ削除されるのでしょうか？
過去の3年間の4月リリースは、2020年4月2日、2021年4月12日、2022年4月4日なので、4月の最初の1週目くらい（遅くても2週目）になると思われます。

:::note warn
因みに同じ2023年4月のタイミングで「標準マシン」も削除されます。マシンテンプレートに移行しましょう！
:::


# 削除されるとどうなるのか
Automation Cloudでの4月リリース後は、クラシックフォルダーは読み取り専用となり、編集不可・ロボット接続不可となるらしいです。
データがいつまで残っているかは不明ですが、過去に実行したジョブのログ確認などの目的には使用できそうです。
データが消失したらマズい人は、データをエクスポートしておくことをお勧めします。Orchestrator ManagerでExcel出力できます。

https://marketplace.uipath.com/ja/listings/orchestrator-manager

# 何をやればよいのか
クラシックフォルダーからモダンフォルダーへの移行は、以下のステップにて行います。

:::note info
使用状況やリスク、態勢に応じで簡略化しても良いと思います
:::

1. 計画・準備
    1. 移行方針・計画の策定
    1. 移行方式・手順の検証
    1. 移行手順書の作成
1. 移行
    1. 移行作業の実施
    1. 移行作業結果の検証

## 1-1. 移行方針・計画の策定
移行に関する方針や計画を決めます。
移行方針については、移行ツールがあるので、これを使用することをお勧めします。開発環境がある場合は、開発環境で検証した後、本番環境での移行作業に入るのが普通ですが、本番環境しかない場合は、検証用テナントやフォルダーを作って、テストデータで検証します。
スケジュールについては、移行作業のために環境を専有する必要があり、業務利用しているユーザとの調整が必要になる場合があります。業務時間中に移行作業するのか、夜間・休日に対応するかなど、具体的な作業計画を決めていきます。

* スケジュール
* 体制と役割
* 移行対象リソース（ロボット、アセット、キューなどなど）
* 移行方針（ツールを使うのか・使わないのか、検証環境を用意するか・しないか）
* 検証方法（作業結果に対して、どんな検証を実施するのか）
* 移行失敗時の対応

## 1-2. 移行方式・手順の検証
開発環境やその他の環境を使って、移行に関する手順を検証し、事前にリスクや課題を洗い出します。
移行ツールを使用する場合、手作業での移行（移行ツールが対象外とする箇所）の有無を洗い出します。

## 1-3. 移行手順書の作成
1-2で実施した検証を元に本番用の手順書を作成します。

## 2-1. 移行作業の実施
1-3で作成した手順書を元に移行作業を実施します。

:::note info
移行ツールの使い方については次回の記事で解説します
:::

## 2-2. 移行作業結果の検証
正しく移行できているかチェックします。

* 移行対象のリソースの突合（件数が合っているか、データの中身が合っているか）
* 移行後のロボットが正しく動作するか

# おわりに
次回は移行ツールについて説明します。
動画ファイルの撮影日を維持しながら圧縮する方法

FFmpegでは、動画ファイルの撮影日を維持しながら圧縮するために、 -map_metadata オプションを使用することができます。以下は、撮影日を維持したまま動画ファイルを圧縮するための例です。

```
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a copy -map_metadata 0 output.mp4
```



この例では、入力ファイル input.mp4 を H.264 でエンコードして、音声はそのままコピーし、撮影日を維持するように -map_metadata オプションを使用しています。また、出力ファイル名は output.mp4 となっています。

なお、 -map_metadata オプションの引数には、元のメタデータを持つストリームのインデックスを指定する必要があります。この例では、 0 を指定していますが、元のファイルによっては、異なるインデックスを指定する必要がある場合がありますので、注意してください。
AWS Control Towerのアクション「SetupLandingZone」について

# はじめに
このブログでは、AWS Control Towerのアクションである「SetupLandingZone」についてまとめました。
(2023/02時点の情報)

きっかけは、特定ユーザーからのランディングゾーンの「バージョンアップ」「修復」を禁止するためSetupLandingZoneをDenyしようと考えましたが、この場合に他にもどのような操作に影響があるか確認したかったためです。

# AWS Control Tower とは
AWS Control Towerは、AWSアカウントを管理するためのサービスであり、複数のAWSアカウントを統合的に管理することができます。また、AWS Control Towerには、AWSアカウントのセットアップに必要な基盤を提供するLanding Zoneという概念があります。

# Landing Zone とは
Landing Zoneは、AWSで安全に複数のアカウントを使ってシステムを運用するための仕組みです。

# AWS Control Tower のアクションである「SetupLandingZone」について

## 仕様

[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/list_awscontroltower.html)には「AWS Control Tower ランディングゾーンを設定または更新するアクセス許可を付与」と記載されています。

[Control Tower紹介ページ](https://aws.amazon.com/jp/controltower/)の図中では赤枠の部分が当てはまりそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599875/81eaf579-14ca-7d2c-5dfc-3ab05e924e2c.png)

この「ランディングゾーンを設定または更新する」の具体的に、どの操作が該当するかAWSサポートに問い合わせました。回答によると、「SetupLandingZone」アクションに該当する操作は以下①〜④の通りです。

### ①ランディングゾーンの新規作成
ランディングゾーンと呼ばれる、アカウントに関連付けられたリソースが起動されます。これにより、AWS Control Towerで複数のアカウントを一元管理することができます。

### ② ランディングゾーンのバージョン更新
既存のランディングゾーンを更新できます。AWS Control Towerでは、最新の機能や最新のベストプラクティスを利用するために、定期的にバージョン更新を行うことが推奨されています。

### ③ ランディングゾーンの修復
ランディングゾーン内のAWSリソースやサービスの問題を自動的に解決する機能を提供しています。

### ④ ランディングゾーン設定の変更
既存のランディングゾーンの設定を変更することができます。
2023年2月時点では、以下のランディングゾーンに関するオプション設定の変更が可能です。

    - リージョン拒否設定：有効・無効の切り替え
    - ガバナンスのための追加リージョン：ホームリージョンに加えて、管理するリージョンを選択
    - CloudTrailの設定：有効・無効の切り替え
    - S3のログ保持期間の設定：標準ログ用は1年、アクセスログ用は10年のデフォルト値
    - KMS暗号化：有効・無効の切り替え

### 留意点
注意すべき点として、Control Tower コンソールを含む各サービスのコンソールは日々アップデートが行われており、今後のアップデートによっては、例えば何らかのボタンが追加された際に、そのボタンを押下した先の操作で当該権限が必要になる可能性もあります。

### リソースタイプ、条件キーについて

リソースタイプ、条件キーは、[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/list_awscontroltower.html)に記載されている表で空欄になっているので指定ができません。

## SetupLandingZoneに含まれない操作(ガードレールの有効・無効化)
「SetupLandingZone」アクションとは別に、ガードレールの有効・無効を制御するためのアクションが存在し、ポリシーで「SetupLandingZone」アクションを拒否していても、ガードレールの操作は可能です。

# 挙動確認

「SetupLandingZone」アクションをDenyした場合、Control Towerコンソールのランディングゾーン設定から行うランディングゾーンの「新規作成」「修復」「更新」および「設定を変更する」という操作が全て権限不足によるエラーになることが確認されました。各ガードレールの有効・無効化は実施可能です。

以下は、「SetupLandingZone」アクションをDenyしてその他は許可するポリシーの例です。

```JSON
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenySetupLandingZone",
            "Effect": "Deny",
            "Action": "controltower:SetupLandingZone",
            "Resource": "*"
        },
        {
            "Sid": "AllowAllOtherActions",
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        }
    ]
}
```

# まとめ
AWS Control TowerとLandingZoneについての基本的な説明と、アクション「SetupLandingZone」に含まれる具体的な操作について紹介しました。
ランディングゾーンに関して何らかの変更を加える際に当該権限が必要になるものと理解して、その観点でアクセス制御することを検討することが重要です。
PythonでExcelから必要なデータを抜き出す件

# メモ

- 案件リストから必要な案件を抜き出したり、日付から年・月を抜き出す
- もっといい書き方があるかもしれないので更新したい

~~~getdata.py python
#!/usr/bin/env python
# coding: utf-8
# 必要なモジュールのインポート
#import matplotlib.pyplot as plt
#import japanize_matplotlib  # <- これ
#import numpy as np
import pandas as pd
#import calendar
#import datetime
# 不要な警告を非表示にする
import warnings
warnings.filterwarnings('ignore')

# 入力Excelのファイル名、シート名
in_file   = 'リスト_xxxxx.xlsx'
in_sheet1 = '案件リスト'
# 出力Excelファイル名
out_file = 'OutData.xlsx'

#----------
# Excelの読込
in_df = pd.read_excel(in_file, sheet_name=in_sheet1)
# 読込み位置とindexを指定
df1 = in_df[3:]
col_lists   = in_df.iloc[2]
df1.columns = col_lists

#----------
# 年と月を抜き出す
def get_int_year_and_month(obj):
    print(obj)
    yy = obj.year
    mm = obj.month
    return (yy, mm)
#----------
# データ加工
def my_proccessing(df):
    # 書き込み用DataFrame
    print("----------")
    # 必要な行のみ抽出
    df = df[df['担当'] == '橋本']
    df = df[df['対応開始月'].notna()]  # 無視
    # 新しい列
    df['対応開始年int'] = 0
    df['対応開始月int'] = 0
    # Excelから読込んだデータに対して一行ごとに処理
    count = 0;
    for index, row in df.iterrows():
        print("index is "+ str(index))
        (yy1, mm1) = get_int_year_and_month(row['対応開始月'])
        row['対応開始年int'] = yy1
        row['対応開始月int'] = mm1
        df.iloc[count] = row
        count += 1
    return df
#----------
# 加工処理
out_df = my_proccessing(df1)
# indexを振り直してファイル書き出し
out_df = out_df.reset_index(drop=True)
#print(out_df.head(5))
with pd.ExcelWriter(out_file) as writer:
    out_df.to_excel(writer, sheet_name=in_sheet1)
    in_df.to_excel(writer, sheet_name='orig')
~~~
picoCTF Writeup picoGym Practice Challenges Dachshund Attacks (注意<spoiler>)

# Description
What if d is too small? Connect with nc mercury.picoctf.net 36463.

netcat で接続すると、以下のように表示される。

~~~
nts/vscode$ nc mercury.picoctf.net 36463
Welcome to my RSA challenge!
e: 83077563702343554104974996434204739715645265602158673538690676471463336678613073880241775254228605106314353101710729653105703801639218664265081281431800464768751108207853871447670242797434974960441087184849197992674269375516588035103695638200385202471858474940467172884556768907433680138245599680626741810005
n: 121284873122734173170589805129141828295734462070736051160234618042523930722218189770628981423754078589956502455716817264371793634639863579905483351333596734771084564158158237582686931067049984902518851429985265857972394495978382581497493613778673575845608203816577795080850903131867388133380707501389132343227
c: 111706960717247640773070034560791401516861975925294183308134273305345496149225528086786540735265768015796964138975156865137538532095816868770852225744950925213608920146611723694488931500427074463572885488370631349565427800972434165100944213038448250274326828594322342022449855379423340174278552163361661239365
~~~

e が大きすぎる場合、Wiener attack で d を求めることができる。

~~~
import owiener

def long_to_bytes(x: int) -> bytes:
    return x.to_bytes((x.bit_length() + 7) // 8, 'big')

def main():

    e = 83077563702343554104974996434204739715645265602158673538690676471463336678613073880241775254228605106314353101710729653105703801639218664265081281431800464768751108207853871447670242797434974960441087184849197992674269375516588035103695638200385202471858474940467172884556768907433680138245599680626741810005
    n = 121284873122734173170589805129141828295734462070736051160234618042523930722218189770628981423754078589956502455716817264371793634639863579905483351333596734771084564158158237582686931067049984902518851429985265857972394495978382581497493613778673575845608203816577795080850903131867388133380707501389132343227
    c = 111706960717247640773070034560791401516861975925294183308134273305345496149225528086786540735265768015796964138975156865137538532095816868770852225744950925213608920146611723694488931500427074463572885488370631349565427800972434165100944213038448250274326828594322342022449855379423340174278552163361661239365

    d = owiener.attack(e, n)
    print('d =', d)

    m = pow(c, d, n)
    flag = long_to_bytes(m).decode()
    print(flag)

if __name__ == '__main__':
    main()
~~~

owienerをインストールしていなかったためpip install owienerをしたが動かなかった。

https://pypi.org/project/owiener/

ここからcurl -O https://raw.githubusercontent.com/orisano/owiener/master/owiener.py
経由で取得するとowienerが使えるようになった。

picoCTF{proving_wiener_2635457}
ClosedXML-導入・新規Excelファイル操作

サーバー側でExcelファイルの操作をするために、OpenXMLを使い開発をすすめようとしましたが、カラムのコピペや範囲選択(range)の扱いに苦戦し、ClosedXMLで代替しました。
備忘を兼ねて、ClosedXMLの導入と簡単な操作について記載したいと思います。
（他のClosedXML関連ページと重なる部分があると思いますがご容赦いただければ幸いです）

https://github.com/ClosedXML/ClosedXML

# 目次
　[導入](#導入)
　[主なクラス構成](#主なクラス構成)
　[新規Excel作成](#新規Excel作成)
　[まとめ](#まとめ)

## 導入
#### NuGetパッケージからインストール
visual studioのNuGet パッケージの管理から
ClosedXMLと検索をしインストールしました。

![closedxml_nuget.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3096978/f4555bfd-4166-53b6-624a-b261e7e3250f.png)

#### usingディレクティブの追加
ClosedXMLをつかうためファイルの上部にusingを追加しました。
```cs:C#
using ClosedXML.Excel;
```

## 主なクラス構成
ざっくり分類すると３つのクラスで構成されています。
|クラス名|概要|利用例|
|:---|:---|:---|
|XLWorkbook|ファイル本体|シート追加、ファイル保存|
|IXLWorksheet|シート|作業するセル、行(row)、列（column)の指定|
|IXLCell|セル|値書き込み、読み込み、スタイル指定|

https://closedxml.readthedocs.io/en/latest/

## 新規Excel作成
#### 新規でExcelファイルを作成する

```cs:C#
XLWorkbook workbook = new XLWorkbook();
//シート作成 デフォルトではシート名"Sheet1"で作成される
workbook.Worksheets.Add();
```

#### セルへの値書き込み
```cs:C#
//シートの選択　今回はシート名"Sheet1"で検索
IXLWorksheet workSheet = workbook.Worksheets.Where(x => x.Name.Contains("Sheet1")).FirstOrDefault();
//セルの選択 今回は[A1]のセルを選択
IXLCell cell = workSheet.Cell(1, 1);
//セルへの値代入
cell.Value = "セルへ書き込み"
```

#### Excelファイルを保存
新規でExcelファイルを作成している場合、名前を付けて保存をすることになります。
```cs:C#
xLWorkbook.SaveAs("<ファイルパス>")
```

## まとめ
今回はClosedXMLを導入方法や新規でファイルを操作する方法を記載しました。
開発を進める中で新たな発見をについては、別途追記していきたいと思います。
paiza.ioでelixir その194

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。
構想編。

# 練習問題

俺cpuのアセンブラを実行する、インタープリターを作れ。

 命令セット
|命令コード|ニーモニック	|意味	|stackの状態	|pcの状態|
|:--|:--|:--|:--|:--|
|000|nop	|何もしない。	|変化無し	|1つ増える
|1nn|jp i	|無条件でi番地へ飛ぶ。	|変化無し	|i番地になる。
|2nn|push 1	|stackに整数を積む。	|1個増える	|1つ増える
|3nn|get a	|stackに変数aの値を入れる。	|1個増える	|1つ増える
|4nn|set b	|変数bにstackを入れる。	|1個減る	|1つ増える
|500|out	|stackをそのまま出力する。	|1個減る	|1つ増える
|501|out1	|stackの100の位を出力する。	|変化無し	|1つ増える
|502|out2	|stackの10の位を出力する。	|変化無し	|1つ増える
|503|out3	|stackの1の位を出力する。	|変化無し	|1つ増える
|6nn|if i	|stackが真ならi番地へ飛ぶ。	|1個減る	|場合によりi番地になる
|7nn|if! i	|stackが偽ならi番地へ飛ぶ。	|1個減る	|場合によりi番地になる
|800|dup	|stackにコピーを積む。	|1個増える	|1つ増える
|801|rnd	|stackに乱数を積む。	|1個増える	|1つ増える
|900|drop	|stackを一個減らす。	|1個減る |1つ増える
|ann|call i	|stackへ今の番地を積んでi番地へ飛ぶ。	|1個増える	|i番地になる。
|001|ret	|stack番地へ飛ぶ。	|1個減る	|stack番地になる。
|f00|+	|stack-1,stackの加算を求める。	|1個減る	|1つ増える
|f01|-	|stack-1,stackの減算を求める。	|1個減る	|1つ増える
|f02|*	|stack-1,stackの乗算を求める。	|1個減る	|1つ増える
|f03|/	|stack-1,stackの除算を求める。	|1個減る	|1つ増える
|f04|%	|stack-1,stackの剰余を求める。	|1個減る	|1つ増える
|f05|=	|stack-1,stackの等しいを求める。	|1個減る	|1つ増える
|f06|>	|stack-1,stackの大小を求める。	|1個減る	|1つ増える

 1から100までのアセンブラ

```
  1
loop  set  a
  get  a
  100
  >
  if  tugi
  get  a
  out3
  out2
  out1
  ' '
  out
  drop
  get  a
  1
  +
  jmp  loop
tugi  jmp  0

```
インタープリターを実装せよ。

# 方針
- ループは、再帰でやる。終了条件は、pc=0です。
- １行、１番地。
- 区切りは、スペース２個。
- ラベル、命令、値の順。
- split, Agent使う。
- 文字コードで印字。

 


以上。
Firebaseなら、RDB思考をやめよう

## はじめに
- まず、firebaseを使うことで、uriをイメージしながら設計し直さないといけないと思った。

`/users/{user_id}/profile`

でデータを取り出すようなね。

- 現在トレーニング管理アプリをFlutterで作成中です。

![fitness_hack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682283/2ec4f86d-4fe0-c8d5-19f5-cd3ac62aae02.png)

- menuとpartなどのテーブルをfirebaseでいうcollection。当初、別のテーブル(コレクション)でも、外部キーであるmenu_idから引っ張ってくればいいと思っていた。が、なんともコードがごちゃごちゃ。出来ないことはないと思うが、コードを見てみると、破綻しているよう思うのだ。そう、完全に別々に取得しているのである。

```dart
// Firestoreのインスタンスを取得する
final db = FirebaseFirestore.instance;

// menuコレクションとpartコレクションを外部キーのmenu_id=1で取得する関数
Future<Map<String, dynamic>> getMenuAndPartDocumentsByMenuId(int menuId) async {
  // menuコレクションのクエリを作成する
  QuerySnapshot menuQuerySnapshot =
      await firestore.collection('menu').where('menu_id', isEqualTo: menuId).get();
  // partコレクションのクエリを作成する
  QuerySnapshot partQuerySnapshot =
      await firestore.collection('part').where('menu_id', isEqualTo: menuId).get();
  // 取得したドキュメントをMapにまとめて返す
  return {'menu': menuQuerySnapshot.docs, 'part': partQuerySnapshot.docs};
}
```

なので、設計をやり直す必要が出てきた。
以下のように変えました。

- ユーザ
ユーザーごとの情報を管理するためのCollection
Firebase Authenticationを使用してユーザーを認証する場合、passwordをCloud FirestoreのusersCollectionに保存しなくてよいので、passwordのドキュメントは持たなくて良い
```yaml
/users/{user_id}/workouts
       - user_name
       - email
       - created_at
       - updated_at
```

- トレーニング実施のlog
トレーニングごとの情報を管理するためのCollection
トレーニングごとにSubcollectionとしてsetsがあり、セットごとの情報を持つドキュメントが作られます
```yaml
workouts/{workout_id}/sets/{set_id}
		 - workout_name: 肩
		 - 実施日時
		 - user_id
                            - weight
                            - reps
                            - time: s
                            - wait: s
                            - 実施日時
```

- 種目
種目ごとの情報を管理するためのCollection
```yaml
exercises
　　- 種目ID
　　- 種目名
　　- 部位
　　- 詳細
```

## 参考文献
https://zenn.dev/yucatio/articles/173f386c471398
３乗根の分母の有理化「2023京都大学文系大問1問2」をwolframalphaとsympyでやってみたい。

sympyで、分母に√の無理数n個?の和で計算できるかも？

オリジナル

https://m.youtube.com/watch?v=8oYnyF9RS34

上と同じです。大学入試数学問題集成＞【１】問２

https://mathexamtest.web.fc2.com/2023/202310541/2023105410100mj.html#top-0109

# wolframで
#### 数学入力で
数学入力がわかる方へ。教えて下さい。

#### 自然言語で

https://ja.wolframalpha.com/input?i=55%2F%28%282*9**%281%2F3%29%29%2B%283**%281%2F3%29%29%2B5%29

近似値
5.1874962923423608227404783781198993208514183555680475277732968199...
別の形
**(7 3^(1/3))/2 - (9 3^(2/3))/2 + 19/2**

# wolframで(まじめに?)
上も下も、同じです。

https://ja.wolframalpha.com/input?i=55%2F%28%282*9**%281%2F3%29%29%2B%283**%281%2F3%29%29%2B5%29%E3%81%AE%E5%88%86%E6%AF%8D%E3%82%92%E6%9C%89%E7%90%86%E5%8C%96


https://ja.wolframalpha.com/input?i=Rationalize%5B55%2F%28%282*9**%281%2F3%29%29%2B%283**%281%2F3%29%29%2B5%29%5D

# sympyで(オリジナルの手順で)
???? もしかしたら、y=1/(Σ(有理数(i)*√の無理数数(i))の有理化ができますか　????

```python
from sympy import *
var('x a b c')
y=55/(2*x**2+x+5)
bunsi =numer(y)
bunbo =denom(y)
bunbo2=a*x**2+b*x+c
f=sympify(str((bunbo*bunbo2).expand()).replace('x**4','3*x').replace('x**3','3'))
mysubs=solve([f.coeff(x**2),f.coeff(x**1)],[b,c])
print("#",(
          bunsi*bunbo2.subs({x:root(3,3)})/
          Poly(f,x).coeff_monomial(x**0)
         ).subs(mysubs).simplify()
     )
# -9*3**(2/3)/2 + 7*3**(1/3)/2 + 19/2
```
ちょっと、上のソースを修正しました。
```python
from sympy import *
var('x a b c')
def my3jokonYurika(bunsu):
    bunsi1=numer(bunsu)
    bunbo1=denom(bunsu)
    bunbo2=a*x**2+b*x+c
    f=sympify(str((bunbo1*bunbo2).expand()).replace('x**4','3*x').replace('x**3','3'))
    bunbo3=Poly(f,x).coeff_monomial(x**0).subs(solve([f.coeff(x**2),f.coeff(x**1)],[b,c]))
    return (bunsi1*bunbo2.subs({x:root(3,3)})/bunbo3).simplify()
print("#",my3jokonYurika(55/(2*x**2+x+5)))
# -9*3**(2/3)/2 + 7*3**(1/3)/2 + 19/2
```


# sympyで(Rationalize)
関数を探しています。よろしくお願いします。

https://www.google.com/search?q=sympy+Rationalize&rlz=1CAUHAM_enJP1038JP1038&oq=sympy+Rationalize&aqs=chrome..69i57.7742j0j7&sourceid=chrome&ie=UTF-8

# 参考

https://ja.wolframalpha.com/input?i=1%2F%283-%E2%88%9A5%29%E3%81%AE%E5%88%86%E6%AF%8D%E3%82%92%E6%9C%89%E7%90%86%E5%8C%96&lk=3

https://reference.wolfram.com/language/ref/Rationalize.html.ja?source=footer

https://stackoverflow.com/questions/61348225/how-to-rationalize-nth-root-in-sympy

多項式の係数

https://ja.stackoverflow.com/questions/33677/sympy%E3%81%AEcoeff%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E4%B8%8B%E3%81%95%E3%81%84

分数
denom(expr) # 分母
numer(expr) # 分子

https://flap1.gitlab.io/docs/python/sympy/#_9

https://www.google.com/search?q=2023+%E4%BA%AC%E9%83%BD%E5%A4%A7%E5%AD%A6+%E6%95%B0%E5%AD%A6+%E6%9C%89%E7%90%86%E5%8C%96&rlz=1CAUHAM_enJP1038JP1038&sxsrf=AJOqlzUoZwg2iMKn-bLcPNsgtBN_SypJRw%3A1677486354788&ei=Emn8Y7LhL9Hf2roP6f63kAY&ved=0ahUKEwiysqvSo7X9AhXRr1YBHWn_DWIQ4dUDCA8&uact=5&oq=2023+%E4%BA%AC%E9%83%BD%E5%A4%A7%E5%AD%A6+%E6%95%B0%E5%AD%A6+%E6%9C%89%E7%90%86%E5%8C%96&gs_lcp=Cgxnd3Mtd2l6LXNlcnAQAzIFCAAQogQyBwgAEB4QogQyBQgAEKIEMgUIABCiBDIFCAAQogQ6CggAEEcQ1gQQsAM6BAgAEAM6BAgjECc6BQghEKABOgkIIRCgARAKECpKBAhBGABQnAJY70Jgp1FoAXABeACAAb8BiAH6CpIBAzMuOZgBAKABAcgBCsABAQ&sclient=gws-wiz-serp
picoCTF Writeup picoGym Practice Challenges Mini RSA (注意<spoiler>)

eが非常に小さい数なのでLow Public-Exponent Attackで平文を求められます。

~~~
# solve.py
from Crypto.Util.number import *
import gmpy2
N = 1615765684321463054078226051959887884233678317734892901740763321135213636796075462401950274602405095138589898087428337758445013281488966866073355710771864671726991918706558071231266976427184673800225254531695928541272546385146495736420261815693810544589811104967829354461491178200126099661909654163542661541699404839644035177445092988952614918424317082380174383819025585076206641993479326576180793544321194357018916215113009742654408597083724508169216182008449693917227497813165444372201517541788989925461711067825681947947471001390843774746442699739386923285801022685451221261010798837646928092277556198145662924691803032880040492762442561497760689933601781401617086600593482127465655390841361154025890679757514060456103104199255917164678161972735858939464790960448345988941481499050248673128656508055285037090026439683847266536283160142071643015434813473463469733112182328678706702116054036618277506997666534567846763938692335069955755244438415377933440029498378955355877502743215305768814857864433151287
e = 3
c = 1220012318588871886132524757898884422174534558055593713309088304910273991073554732659977133980685370899257850121970812405700793710546674062154237544840177616746805668666317481140872605653768484867292138139949076102907399831998827567645230986345455915692863094364797526497302082734955903755050638155202890599808146956044568639690002921620304969196755223769438221859424275683828638207433071955615349052424040706261639770492033970498727183446507482899334169592311953247661557664109356372049286283480939368007035616954029177541731719684026988849403756133033533171081378815289443019437298879607294287249591634702823432448559878065453908423094452047188125358790554039587941488937855941604809869090304206028751113018999782990033393577325766685647733181521675994939066814158759362046052998582186178682593597175186539419118605277037256659707217066953121398700583644564201414551200278389319378027058801216150663695102005048597466358061508725332471930736629781191567057009302022382219283560795941554288119544255055962
i = 1
while True:
    m, ok = gmpy2.iroot(c + i * N, e)
    if ok:
        break
    i += 1
print(long_to_bytes(m))

~~~

```
\picoCTF\crypto\minirsa>python rsa.py
b'                                                                                                        picoCTF{e_sh0u1d_b3_lArg3r_6e2e6bda}'

```
Flutterでブロックが丸なブロック崩しゲームを作ってみた

## 作ろうと思った経緯

普段の業務での開発はWeb関連の開発が基本で今までFlutterやiOSアプリの開発については触ったことがなかったのですが、今回業務でFlutterを使う機会があり、また会社のメンバーで個人開発をやっていこうというイベントがあったので、良い機会だと思って作ってみようと思った次第です。

## 技術スタック

- Flutter 3.3.10
- Flame 1.5.0

Flutterでゲーム開発をする場合はパッケージを使うことになり、入れるパッケージにはいくつか選択肢があるようですが、Flutterでのゲーム制作については日本語記事が思ったより少なく、その中でも参考にできそうなものがいくつかあったので今回はFlameを使うことにしました。

## どんなものができたか

タイトル通り、ブロックが丸なブロック崩しゲームです。

![スクリーンショット 2023-02-25 16.31.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159896/ab0f78c1-5a8f-3adf-3737-04486e650e72.png)
![スクリーンショット 2023-02-25 16.28.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159896/bac5f11d-5d12-1b9e-bb69-fedb3916e64b.png)

![スクリーンショット 2023-02-25 16.28.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159896/fe71e118-a8ce-f8e5-2aa8-635a0497eeb6.png)

リリースはしていないのですが、もうちょっと色々なところを調整したらリリースできそうかなーという感じです。

## 感想

- Flutterを触っていたので環境構築など最初に詰まる部分については比較的スムーズに進められたのですが、Flameに関してはFlutterの発展版というよりはもう完全に独立しているものという印象でした
- Flameでは衝突検知や衝突した瞬間の情報取得などはパッケージで便利な機能が色々用意されているのですが、衝突後の動作については自前で実装をしなければならず、ブロックを丸にしたことでそこの実装はとても難しかったです。というか滑らかな動作に出来ず、物理演算処理を入れるにはさらに別のパッケージを入れる必要がありそうでしたので今回の開発ではそこまではやらないことにしました
- ゲームがどういう実装で動いているのかというのはとても勉強になりました。オブジェクトの動かし方だったり動作部分の実装については奥が深く、世の中のゲーム開発者は改めてすごいなーと感じました

:::note info
この記事は、株式会社mofmofの「水曜日の個人開発」の取り組み内で書きました。
:::

https://indie-dev.mof-mof.co.jp
【TestCafe】TestCafeで実行スピードを変更する メモ

## TestCafeで実行スピードを変更する
TestCafeでテストを実行するとき、
```
testcafe chrome test.ts
```
のように実行します。

しかし、これだと実行スピードが速すぎて本当にできているのか疑うときがあります。
そこで、実行スピードを下げることができるコマンドが存在します。
以下の様に記述します。

```
testcafe chrome test.ts --speed 0.5
```
`0.5`の様に実行スピードを変更することができます。
testcafeのjsonを定義してそちらに記載することで変更することもできますが、こちらの方が手軽だと思います。

### 余談
テストカフェでは実行したいテストを絞ることができます。
例えばこんなテストケースがあるとして、`test1`のみ実行したいとします。
```typescript
test("test1",async(t) => {

})

test("test2",async(t) => {

})
```

その場合、testの後に`only`を付けてあげることで絞ることができます。
```typescript
test.only("test1",async(t) => {//実行される

})

test("test2",async(t) => {//実行されない

})
```
[Unity] Timeline使って、任意のタイミングでアクションを起こす

# 初めに
曲のビートのタイミングでアクションを起こす

曲とかビートとかさっぱり分からなかったので色々調べてみた。


## 取り合えず、こんな感じで出来た
![bpm.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37068/f974e5de-2422-1f71-68b4-ab5308994f20.gif)


### やったこと
とりあえず、下記のURLのようにプログラムで制御しても良かったのだが
unity のtimelineの制御を使ってアクションを行ってみた。

https://am1tanaka.hatenablog.com/entry/beat-calc

bpmの計算は下記のgitのリポジトリ使って取得してた

https://github.com/tanakaedu/BeatDetector

timelineのPlayableDirectorのコンポーネントを
Update MethodをDSPに設定して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37068/20d6f3df-8134-ee44-fd36-0c2451cd4ae9.png)

Update Methodの説明は下記を見てください。

https://docs.unity3d.com/ja/2018.4/Manual/class-PlayableDirector.html

60フレームの所にSignal Emitterを置きタイミングでイベントが起きるように設置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37068/6b080bac-4569-2b2a-c424-c15d3276044a.png)

60フレーム目に置くのは、下記を参考にちょうど1秒でイベント起きて欲しいので

```
BPM＝60であれば、4分音符を1分間に60回刻むということですので、
時計の秒針とまったく同じ速さということになります。
と、いうことは、4分音符1つ分の長さはジャスト1秒ですね。
```
https://www.ototeku.com/entry/2018/04/15/BPM%E3%81%8B%E3%82%89%E9%9F%B3%E7%AC%A6%E3%81%AE%E9%95%B7%E3%81%95%E3%82%92%E6%B1%82%E3%82%81%E3%81%A6%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F

#### 計算とtimelineの速度変化

```c#
    var speed = bpm / 60.0f;
    timeline.playableGraph.GetRootPlayable(0).SetSpeed(speed);
```
曲からbpmしらべて、unity timelineのPlayableDirectorからSetSpeedを指定します。
でデフォルトだと1.0なので60フレーム目は1秒になる（早いビードなら120bpmならspeedは2 240bpmならspeedは4）

timelineのスピードの変え方は下記参考

https://sole-game-creater.com/unity-timeline-change-speed/

#### 最後に
音ゲーみたいなの作ってみたいけど、さ、どうやって手を付けていけばいいかな？
っていつも思っているが、こんな感じでtimelineを制御すればいけるのかな？
って思ってます。下記のサイトみたいに

https://developers.10antz.co.jp/archives/2352

※ここ重要
もし、認識や考え方間違っているって所ありましたら突っ込んでください。。
【TestCafe】TestCafeでidのない要素を取得する

## 現状
Reactとtypescriptでアプリを作成しています。
TestCafeでテストを書いていますが、↓のような場合、idのついていない場所をうまく取得できませんでした。
これを解決する方法を書いていきたいと思います。

```html
<div id="qiita">
  <div>
    <div>
      <div>ここの要素を取得したい</div>
    </div>
  </div>
</div>

```

### 解決策
TestCafeにはSelectorオブジェクトとして`.find`があり、これを使っていきます。
詳しくはこちら→https://testcafe.io/documentation/402750/reference/test-api/selector/find

下の様に`qiita`という現状分かっているidでSelectorを定義し、そこから3つ下の階層にあるので`.find("div")`を3つ記述するという流れになります。

```typescript
export const displaySeat = Selector("#qiita")
  .find("div")
  .find("div")
  .find("div");
```

このようにして、idやclassが振られていない要素も取得し、テストすることができます。
ABC291回答メモ

0.はじめに
　昨日のARCでレートが699と700まであと１に迫ったので
　気合を入れて臨みました。
　結果としてはCまでしか正解できず、レートダウンとなりました・・・。
　ただ、今回のD問題は予選と違っていつものレベルだった気がします。

1.A - camel Case
　文字列ないから大文字を探す問題。
　文字コードとかはややこしいので
　前に使った大文字一覧を検索して
　大文字だったら出力でACとなりました。

　https://atcoder.jp/contests/abc291/submissions/39228337

2.B - Trimmed Mean
　リストから指定した範囲を抜き出す問題のアレンジ版。
　いろいろやり方はありそうでしたが、要素数も少ない制約だったので
　　-もらったリストをソートしたのち、回答用リストLに移していく
　　　-ただし、先頭N個(添え字がNより小さい場合)と
　　　 末尾N個(添え字が4*Nより大きい場合)はうつさない
　　-Lの合計をLの個数で割って平均を求め表示
　と、素直に組んでACとなりました。

　https://atcoder.jp/contests/abc291/submissions/39237397

3.C - LRUD Instructions 2
　座標移動問題。
　最初、途中で原点に戻るかどうかの問題と勘違いしてWAを食らいました。
　（例題含め、ミスリードしている気がしないでもない。）
　その後移動後の座標位置を辞書に登録する形で実装し
　移動後に前に訪れた場所かを判定し訪れていればYesを表示して
　exitする実装でACを頂けました。
　もったいなかったのは、提出時にテスト用のdictを出力する
　バージョンを提出してWAを食らったことでした・・。5分ロス。

　https://atcoder.jp/contests/abc291/submissions/39246854

4.D - Flip Cards
　一時間以上時間が残ってましたが正解にたどり着けませんでした。
　考え方の方向性はあっていた・・・ようないないような・・・。

　【考え方(誤)】
　　・まず先頭のカードは裏表どちらでもよいので
　　　パターン数(ans)に2をセット
　　・その後、1枚ずつパターン分けして考える。
　　　前表：後表、前表：後裏、前裏：後表、前裏：後裏
　　　をそれぞれ比較し、Nans(初期値0)に同じなら+1、違うなら+0する
　　　-i番目のカードが、表でも裏でもi-1番目のカードと
　　　 同じ数字にならない（Nans＝0）時は、ansに2をかける。
　　　-表も裏も同じ数字かつ、1枚前のカードも表も裏も
　　　 同じ数字の場合（Nans＝4)は、ansに0をかけて出力してexit。

　　といったところまでは、思いついたのですが、
　　Nans＝1～３の時どうすればいいの？？となって時間切れ。

　解説を見ると、DPとなってはいましたが、上の考え方の
　ansをXとY（前のカードが表のパターンと裏のパターン）　に分けて
　考えればよいと理解しました。

　【考え方(正)】
　　1)リストXにカードの1枚目から表の数字を格納
　　2)リストYにカードの1枚目から裏の数字を格納
　　3)前のカードが表の場合の変数ansXと裏の場合の変数ansYを用意し
　　　1枚目のケース分ansX=1、ans=1で初期化。
　　　（Nが1の場合は、答えはansX+ansYで2となる。）
　　4)以下、添え字iを１～Nまで繰り返す。
　　　4-1)添え字iのカードが表の場合のケース数をセットする変数NansXと
　　　　　添え字iのカードが裏の場合のケース数をセットする変数NansYを用意
　　　4-2)前のカード(i-1枚目)の表裏と今のカード(i枚目)の表裏を比較
　　　　4-2-1)前表(X[i-1])：後表(X[i])が違うとき
　　　　　　　　NansXにansXを加算
　　　　4-2-2)前裏(Y[i-1])：後表(X[i])が違うとき
　　　　　　　　NansXにansYを加算
　　　　4-2-3)前表(X[i-1])：後裏(Y[i])が違うとき
　　　　　　　　NansYにansXを加算
　　　　4-2-4)前裏(Y[i-1])：後裏(Y[i])が違うとき
　　　　　　　　NansYにansYを加算
　　　4-3)ansXにNansXをセット
　　　4-4)ansYにNansYをセット
　　5)ansX+ansYのmodを出力
　
　　前のカードが表だった場合、今のカードが表裏どちらでもよい場合は、
　　今のパターンが表＆前のカードが表のパターン数+今のパターンが裏＆前のカードが表のパターン数
　　なので結果的に2倍、
　　前のカードが表だった場合で、今のカードが表しかだめな場合は、
　　今のパターンが表＆前のカードが表のパターン数なので、結果的にパターン数は増えない。
　　と、うまく説明できているかはわかりませんが、私の中では納得いきました。

　https://atcoder.jp/contests/abc291/submissions/39280542

以上