OmniAICreator/Qiita-1.07M huggingface dataset:
プロダクトマネージャーが技術力を求めて駆け抜けた1年を振り返る

### はじめに

現在、IT会社でプロダクトマネージャーをしているものです。
前職では営業をしており、カスタマーサクセスで今の会社に入社後、社内異動で2年ほど前にプロダクトマネージャーになりました。
それまでは、ずっとカスタマーサクセスをやっていましたので、技術力はほぼゼロの状態で異動しました。

プログラミングの勉強をはじめて1年以上が経ちため、今日はこの1年半の振り返りをしてみようと思います。
### 学習のきっかけ

異動直後、技術力がなさすぎて、「エンジニア同士の会話についていけない、どうしよう、、、」と上司にぼやいていたら、
「ちょっとエンジニアになってくれば？」と打診を受けたのがちょうど1年半くらい前でした。

冗談かと思ったら、本当で、話はとんとん拍子で進み、私は2021年1月から3ヶ月間エンジニアになることが決まりました。


### 事前学習　2021年12月

その当時、エンジニアになる前に冬休み中に読んでおくよう言われたのが、『Webを支える技術』と『Real World HTTP』でした。どちらも難し過ぎてさっぱりでした。笑

焦った私は、冬休みのすべての時間をかけて、（コロナ禍で出かける先もなかった）、ドットインストールやyoutubeでhtml/css/javascriptあたりの勉強ともう少し優しめの本を買い漁り勉強を進めました。

ふと気分転換にyoutubeでプロダクトマネージャーについて、調べていると「技術のわからないプロダクトマネージャーにあたったらそれはハズレくじ」という動画に対するコメントを見つけて、泣きたくなりました。

しかしこの技術書が読めない＆自分がハズレくじと捉えられる立ち位置にいるという厳しすぎる現実がモチベーション維持に繋がったかと思います。

### 実践学習 2021年1月〜3月
1月からのエンジニア在籍期間では、簡単な文言修正・機能拡張などを対応させてもらいました。

このエンジニアの経験を通し、Githubの使い方やアジャイル開発の進め方をざっくり理解することができました。

しかしhtml/css/Javascriptを勉強し、エンジニアに3ヶ月在籍をしたからといって、webアプリケーションの開発ができる状態では全くありませんでした。

最低限の開発の流れはつかめたので、ここのタイミングで勉強をやめる選択もありましたが、思いのほかプログラミングが楽しかったのもあり、インドアの趣味として続けることにしました。

### 自己学習期間　2021年4月〜2022年3月

その後、1人で勉強を続けていましたが、独学に飽きて、なかなか思うように勉強が進まなかったので、仲間を募って、チーム開発を始めました。
自己学習期間においてどんな活動をしていたかは、別の記事にまとめているので、今日は割愛します。

https://qiita.com/bonbons_ramune/items/818fa903e9ea0ac73230

### プログラミングの勉強で得られたこと

以下、プログラミングの勉強をして得られたことや学んだことを整理してみました。

#### エンジニアが話している技術的な会話がわかるようになった（少しだけ）

デザインをエンジニアやUXと考えていて、パターン化して進めたいという話が出たときに、「あ、コンポーネントを共通化して効率的にやりたいのだな、コンポーネントで共通化するなら細かい仕様の違いはなるべくないほうが使い回しやすいよな」とその意図を想像できるようになりました。

パターン化して進めたいという発言に対して、技術力がなくても「そうですね」と言えるので、出てくる言葉として一緒なのですが、
実際に自分で、パターン化しないで、量産して大変になったつらい経験と、パターン化したのに、細かい仕様をいろいろ変え過ぎて、複雑になってしまった経験があるので、勝手に「そうですね」の深みが増したと思っています。

また、「まだ決まってないことが多くて、検討はもう少し先ですね」という状態になっているとき、「見えてない部分はどのあたりですか？」と突っ込んでいけるようになり、決めていくためにどんな情報をエンジニアに共有すれば議論が前に進むのか動いていけるようになりました。

これは、時間が経てば、あるいは、信頼関係が強くなれば、自然とできていける話のかもしれませんが、
自分で1つWebアプリケーションを作ってみて、見えないところから（リファレンスを見たり、技術記事を探す）、見えていくプロセスがあることを知れたことが後押しになっている気がします。


### 調査系のチケットを自分で返せるようになった（ちょっとだけ）

スプリントで動いていて、このまま今のスプリントのチケット対応を維持したい一方で、ユーザーさんからのお問い合わせがエスカレーションされ、急ぎの仕様確認として調査が発生した際、これまではどちらかの対応を一時的に止めるしかなく、何もできない私は指をくわえて待つことしかできませんでした。

プログラミングを勉強をしたことにより、簡単なコードであれば自分でみて問い合わせを返すことができるようになり、計画している開発を止めずに、緊急なユーザーさんからのお問い合わせも臨機応変にチームで対応しながら、回せていけるようになりました。

### エンジニアの方と話せるテーマが増えた

エンジニアのコミュニティにも入ったことで、エンジニアの方々の普段の雑談に触れるようになり、エンジニアの人が好きなテーマを自分も自然と好きになっていきました。

プログラミングを始める前は、なぜMacにキーボードが付いているのにどうしてエンジニアの人はキーボードを新たに買うんだろうと思っていた私も、

プログラミングを始めて、ガジェットに対する興味が湧き、マウス・キーボード・PCスタンド・モニター・モニターアーム・スタンディングデスクなどをこの1年で買っており、結果的によりエンジニアの方とのガジェットに関する会話を非常に楽しめるようになりました。

まもなく憧れのHHKBを買う予定ですが、いつか自作キーボードにもチャレンジしてみたいです。

### エンジニアの方へのリスペクトの気持ちがさらに高まった

以前からモノを作れる人への漠然とした憧れはあったのですが、自分で少しやってみたことで、自分がやるよりも何倍も早いスピードで美しいコードを書く人への憧れがより強くなりました。

### 朝型人間になれた

プログラミングを始める前までは、8時か9時くらいに起きる生活でしたが、現在は6時からの朝活に日々参加しており、いまでは自然と5時半くらいに目が覚めるようになりました。
朝はプログラミングの勉強を主にやっていますが、ラジオ体操をしたり散歩をしたり、朝の時間にゆったりできるようになり、QOLも格段に上がったように思います。

### 終わりに

当時、ちょうどコロナ禍でもあり、アウトドア系の趣味しかなかった私は趣味が全滅してやる気を失っていましたが、
プログラミングを始めたことで、空いた時間にやることが明確になり、土日に「あー暇だ」とか「あーつまらん」と嘆くことがなくなりました。

趣味を失ってしまった非エンジニア出身の新人プロダクトマネージャーの方がいたら、プログラミングは仕事にも活き、趣味にもなりとてもおすすめです。
原始ピタゴラス数の木とその応用



### 原始ピタゴラス数の生成
「[ピタゴラスの定理(Wikipedia)](hhttps://ja.wikipedia.org/wiki/%E3%83%94%E3%82%BF%E3%82%B4%E3%83%A9%E3%82%B9%E3%81%AE%E5%AE%9A%E7%90%86)」等にあるように、原始ピタゴラス数の生成は以下の式が有名ですが、今回はMatrixを用いて原始ピタゴラス数の木を作る方法を紹介します。

```math 
(a, b, c) = (m^2 − n^2, 2mn, m^2 + n^2) 
```

### 原始ピタゴラス数の木

[原始ピタゴラス数の木（高校数学の美しい物語）](https://manabitimes.jp/math/1435) に定理と証明が記載されています。定理は以下のようなものです。

```math
\begin{align}
&すべての原始ピタゴラス数は　\\
&(3,4,5)に以下の行列A,B,Cの任意の組合せの積をM^nとすると \\
&(a,b,c)=(3,4,5)M^nで表せる \\ \\

&A=\left(
\begin{array}{rr}
1 & 2 & 2 \\
-2 & -1 & -2 \\
2 & 2 & 3 \\
\end{array}
\right) \\

&B=\left(
\begin{array}{rr}
1 & 2 & 2 \\
2 & 1 & 2 \\
2 & 2 & 3 \\
\end{array}
\right) \\

&C=\left(
\begin{array}{rr}
-1 & -2 & -2 \\
2 & 1 & 2 \\
2 & 2 & 3 \\
\end{array}
\right) \\
\end{align}
```

これを図に表すと以下のようになります。レベル4までが求められています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1922159/91fba5a7-c0b4-848a-7959-19509c2ed01c.png)

幅優先探索のプログラムにすると、以下のようになります。

```python 
import numpy as np
A = np.matrix([[ 1, 2, 2],[-2,-1,-2],[ 2, 2, 3]])
B = np.matrix([[ 1, 2, 2],[ 2, 1, 2],[ 2, 2, 3]])
C = np.matrix([[-1,-2,-2],[ 2, 1, 2],[ 2, 2, 3]])
ABC = [A,B,C]

pt = np.matrix([3,4,5])
L = [[pt], []]
lp1,lp2,count = 0,1,1
for d in range(1,3+1):
  print(d, L[lp1])
  L[lp2] = []
  for pt in L[lp1]:  
    for M in ABC:
      L[lp2].append(pt @ M)
  lp1,lp2 = lp2,lp1
# 1 [matrix([[3, 4, 5]])]
# 2 [matrix([[ 5, 12, 13]]), matrix([[21, 20, 29]]), matrix([[15,  8, 17]])]
# 3 [matrix([[ 7, 24, 25]]), matrix([[55, 48, 73]]), matrix([[45, 28, 53]]), matrix([[39, 80, 89]]), matrix([[119, 120, 169]]), matrix([[77, 36, 85]]), matrix([[33, 56, 65]]), matrix([[65, 72, 97]]), matrix([[35, 12, 37]])]
```

### 原始ピタゴラス数の木アルゴリズムの応用

このアルゴリズムは面白いのですが、既にピタゴラス数を効率的に生成するアルゴリズムはあるので、その実用性はあまりないのかなと思われますが。**実はあるのです**。

この定理は、$a^2+b^2=c^2$だけではなくて以下の式でも成り立つからです。

```math 
\large a^2+b^2=c^2+k
```
これを確かめるために以下の問題を考えてみます。

**問題：$a^2+b^2=c^2-1$となる (a,b,c)の組の数をを$(a+b+c) \le 100$で求めよ**

上のプログラムのMatrixの初期値**pts**を(2,2,3)に変えることで簡単に求まります。ただし$a$と$b$を交換した答えが両方生成されるので、$a \le b$の物だけカウントしています。

```python
pts = [np.matrix([2,2,3])]
print(0, pts[0], np.sum(pts[0]))
N = 100
L = [pts, []]
lp1,lp2,count = 0,1,1
for d in itertools.count(1):
  L[lp2] = []
  for pt in L[lp1]:  
    for M in ABC:
      pt1 = pt @ M
      if np.sum(pt1) <= N: 
        L[lp2].append(pt1)
        if pt1[0,0] <= pt1[0,1]:  # a <= b
          print(d, pt1, np.sum(pt1))
          count += 1
  if len(L[lp2]) == 0: break
  lp1,lp2 = lp2,lp1

print(f"N = {N}, count={count}")
# 0 [[2 2 3]] 7
# 1 [[4 8 9]] 21
# 1 [[12 12 17]] 41
# 2 [[ 6 18 19]] 43
# 2 [[18 30 35]] 83
# 3 [[ 8 32 33]] 73
N = 100, count=6
```

このアルゴリズムはEuler Project: Problem 223, 224を解くのに役に立ちます。

（開発環境：Google Colab）
質問テンプレ

○○を実行すると、○○というエラーになってしまいます。

私の行った手順は以下です。
(1)
(2)
(3)

以下のような結果になりました。

【結果のスクショやコピペ】

【参考資料】を参考にして、
私は【予想結果】になると思いました。

原因を確かめるため、以下のようなことを試しましたが、
解決には至りませんでした。

(a) 入力を○○ではなく××にしてみた
→上記と同じ結果になった

(b) ソースプログラムの○○をやめて、××にした
→以下のようなコンパイルエラーになった

【エラーメッセージのコピー＆ペースト】




# ヤバくなる前にアラートをあげよう
アラートは、手の施しようがなくなる前(ヤバくなる前)にあげましょう。

# 公式ドキュメントを読もう
公式ドキュメントは確かに情報量が多く、読みにくいものもありますが、
適切に読めるとすぐに問題解決に繋がります。

開発の自走力を高めたいのであれば、
公式ドキュメントを読むのが近道だと思います。
コンストラクタの代わりに staticファクトリメソッドを検討する

# これは何？
Effective Java 第3版を読んで自分なりにかみ砕いた内容を記事に落としていきます。
良いコードを書くための選択肢の一つになれば最高なので、頑張ります。
※読み進める中で知識のアップデート等あれば都度更新いたします。


# 概要
クラスのインスタンスを得るために public のコンストラクタを作成するのではなく、
**public の static ファクトリメソッドを作成するというもの**
・例 (Booleanクラス)
boolean基本データ値をBooleanオブジェクト参照に変換している
    
~~~java
    public static Boolean valueOf(boolean b) {
         return b ? Boolean.TRUE : Boolean.FALSE;
    }
~~~

# メリット
## ①コンストラクタと異なり名前を持つこと
クラスは特定のシグニチャ(※1)を持つコンストラクタを1つしか持てません。
→型の順序を変えて対応は可能ですが、コンストラクタを利用する際に間違ったコンストラクタを呼んでしまう可能性があります。

static ファクトリメソッドはメソッド名を持つため適切な名前を付けておけば読みやすく使いやすいコードになります。

良くない例

~~~java
    class Hoge {
        public Hoge (String a, String b, String c, int d, int e) {
            //処理を書く パターンA
        }

        public Hoge (int f, int g, String h, String i, String j) {
            //処理を書く　パターンB
        }
~~~
良いない例

~~~java
    class Hoge {
        public static A getパターンAのインスタンス(String a, String b, String c, int d, int e) {
            //処理を書く パターンA
        }

        public static B getパターンBのインスタンス(int f, int g, String h, String i, String j) {
            //処理を書く　パターンB
        }
~~~

※1.コンストラクタの引数の型やその順序などのこと

## ②呼び出しごとに新規オブジェクトを生成する必要がないこと
☑あらかじめ生成されたインスタンスを使用する
☑オブジェクトが生成されたときにインスタンスをキャッシュする
⇒重複したオブジェクトを生成しないようにします。

~~~java
public final class Boolean implements java.io.Serializable {
 
    public static final Boolean TRUE = new Boolean(true);
    public static final Boolean FALSE = new Boolean(false);
 
    /**
     * 上で生成したTRUEとFALSE以外のインスタンスは生成しません
     */
    public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }
~~~

static ファクトリメソッドが何度呼び出されても同じオブジェクトを返すため、どの時点でどんなインスタンスが存在するか把握できる。
このことを **「インスタンス制御されている」** といいます。
→クラスをシングルトンやインスタンス化不可能にできます。

## ③メソッドの戻り値として任意のサブタイプオブジェクトを返すことができる

インスタンス生成時に返すオブジェクトの型を柔軟に選択可能になります。

※ここについて、あまり理解できていないです
※TODO：改めて修正する

## ④returnされるオブジェクトのクラスを、入力パラメータの値に応じて呼び出しごとに変えられる

例えば、EnumSetクラスの場合
enum型が64個以下のときと、それより大きいときで返すサブクラスが違う。(RegularEnumSetとJumboEnumSet)

※あまりメリットが実感できていないが、使い分けられることでパフォーマンス上のメリットがあるそう

## ⑤returnされるオブジェクトのクラスは、staticファクトリメソッドを含むクラスが書かれた時点で存在する必要がない

※ここについて、あまり理解できていないです
※TODO：改めて修正する

#デメリット

##①publicあるいはprotectedのコンストラクタを持たないクラスのサブクラスを作成できない

このことから継承ではなく、コンポジションを使う必要がある。
→後の項で登場するのでその時改めて

##②staticファクトリメソッドを見つけるのが難しい

クラスに任意の名前を付与できるので、コンストラクタと比較して目立ちにくい
→命名規則を遵守することである程度回避できる
webpack5.x対応loaderの作り方

# 動機
* htmlは静的なものを使うんだけど、ejsのincludeが使いたい。
* できればdejsでも同じejsを処理したい（`<%-await include()%>`)
。。。deno移行する時のための準備。denoって有望なんでしょうかね？
* ~~バッチでejsコマンドとwebpack呼べばいいだけなんだけど~~webpackで完結したい

# どうするか
npmで「ejs loader」で検索すると、、、、
たっくさん出てくる。

でも、いくつか使ってみようとしても動かない

# とりあえず、自分で作ってみる
* `module.exports = function (content, map, meta)`の形で書けば良いらしい
* webpackで設定したoptionsは`require("loader-utils").getOptions(this)`で取れるらしい
* `await include`するためには
  + ejs
    1. ejs.render()を非同期呼び出し（`await ejs.render()`)
    1. ejs.render()の第三引数に`{"async":true}`が必要
  + webpack
    1. callback関数を取得（`const callback = this.async()`）
    1. 非同期処理終了後に`callback(error, ejs.renderの戻り, map, meta)`

ということを調べて作ってみたけど
「getOptionsはないよ！」
と言って、怒られる。

## 原因はこれ
[loader-utilsのchangelog](https://github.com/webpack/loader-utils/blob/master/CHANGELOG.md)
抜粋
``` text
3.0.0 (2021-10-20) 
⚠ BREAKING CHANGES
...
removed getOptions in favor loaderContext.getOptions (loaderContext is this inside loader function), note - special query parameters like ?something=true is not supported anymore, if you need this please do it on loader side, but we strongly recommend avoid it, as alternative you can use ?something=1 and handle 1 as true
...
```
loaderの中のthisにgetOptionsが生えてるから、それ使ってねってことですね。
__他にも色々変わってますが、基本、this使えってことらしいです。__

``` javascript
const getOptions = (ctx) => {
	return ctx.getOptions
		? ctx.getOptions()
		: require("loader-utils").getOptions(ctx);
};

module.exports = function ejsLoader(content, map, meta) {
	const options = getOptions(this);
// ~~~~
}
```
最終的には、こうやって、webpack4でも5でもoptions取ってこれるようにしてみた。

# npmに公開してみた
[@coneyware/ejs-loader](https://www.npmjs.com/package/@coneyware/ejs-loader)
でもね。。。ejs loaderで検索すると山ほど出てくるってことは、
みんな、それぞれ自分で作るんだろうなぁと思って作った時にハマったところをココに書いておく。
「拡張Eメール」およびEmailMessageオブジェクト




# 内容
+ 拡張電子メール機能を有効にする  と、Salesforceから送信された電子メールは電子メールメッセージおよびタスクとしてログに記録されます。
+ 編集可能なタスクオブジェクトとは異なり、電子メールメッセージはユーザーインターフェイスまたはAPIを介して編集できません。
+ 新しい電子メールメッセージのカスタムレポートをつくるとレポートにできるようです。
　[Email Message Reporting](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000G3dRtSAJ)



# 参考にしたHelp記事

+ [「拡張Eメール」およびEmailMessageオブジェクトについて学ぶ](https://help.salesforce.com/s/articleView?id=000313606&type=1)
+ [Learn More with Email Reporting](https://help.salesforce.com/s/articleView?id=release-notes.rn_sales_productivity_email_reports.htm&type=5&release=232)


# フローから使えそう

+ [EmailMessageオブジェクトはレコードトリガーフローでも呼び出せます。](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000O4o9)
GoogleAppEngineからCloud SQLへ接続できない場合はリージョンとゾーンを確認する

メモ代わりの記事です

# やりたかったこと
App EngineからCloud SQLに接続したかった


# 要約
接続にあたり特に設定は必要はないはずだった
別のアプリをデプロイしたときは特段設定はしていなかった
"リージョン"は同じだったが"zone"が違ったので接続できなかったと思われる
https://cloud.google.com/sql/docs/mysql/connect-app-engine?hl=ja


zoneの確認のためにconfigリストを確認する
```
gcloud config list
```

```
[compute]
region = asia-northeast1
zone = asia-northeast1-b
[core]
account = ***
disable_usage_reporting = True
project = ***
```

zoneのconfigを設定しなおしてデプロイしなおす
https://cloud.google.com/sdk/gcloud/reference/config/set
```
 gcloud config set compute/zone asia-northeast1-b
 gcloud app deploy
```

# 環境
SQLをasia-northeast1-aに配置したつもりがbだった
App Engineのリージョン表記はasia-northeast1だった
サフィックスがないからasia-northeastなら接続できるのかと思った(zoneが表記されていなかった)
cscの作法 その67

# 概要
cscの作法、調べてみた。
mdbにsqlを発行してみた。

# コンパイル手順

```
>csc sql0.cs /platform:x86

```

# サンプルコード

```
using System;
using System.Data.OleDb;
using System.Data;
using System.IO;
using System.Text;
using System.Collections.Generic;

public static class Program {
	public static void Main(params string[] args) {
		OleDbConnection con = new OleDbConnection();
		con.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=mydb.mdb;";
		con.Open();
		//string sSQL = "CREATE TABLE テスト(コード INT, 商品名 TEXT)";
		string sSQL2 = "CREATE TABLE sisyutu(sID AUTOINCREMENT CONSTRAINT PrimaryKey PRIMARY KEY, 年月日 DATE, 項目 TEXT(50), 金額 INTEGER, 備考 TEXT(55))";

		OleDbCommand cmd = new System.Data.OleDb.OleDbCommand(sSQL, con);
		cmd.ExecuteNonQuery();
		Console.WriteLine("ok");
	}
}
```

以上。
Blenderでジグソーパズル風のパズルのアドオン

## Blenderでジグソーパズル風のパズル

Blender3.1で、ジグソーパズル風のパズルを遊べるアドオンをPythonで作成したので紹介します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/0567dc42-2a5b-343f-5944-3c8b45db5a35.png" width="300">


## やり方

- [Blender Add-on: Jigsaw](https://github.com/SaitoTsutomu/Jigsaw)の画面にしたがってインストールしてください。
    - アドオンのチェックでは「テスト中」を選んでください。
- サイドバーの編集タブの「Puzzle」を開いてください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/d3ab43df-16d4-0e3a-6684-509645ec1274.png" width="300">

- 横と縦の分割数を`num_x`、`num_y`に設定してください。
- パズルを作成するには、「Make Puzzle」を押してください。
    - 画像の選択画面が出るので、画像を選んでください。
- 下図のように、選んだ画像を分割したブロックと枠が作成されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/ee3d867d-1e1e-5218-e7e7-d316278eb385.png" width="300">

- パズルを遊ぶには「Start」を押してください。ブロックがバラバラになります。
    - ブロックを枠内に収めると、枠が黄色になって終了です。
- 途中でやめるときは、「Finish」を押してください。「Finish」を押すと、完成したかどうかの判定を行いません。

## しくみ

ブロックのUVを適切に作成するのは、手間がかかります。
そこで、1つのグリッドに画像のマテリアルを設定し、そのグリッドを辺分離モディファイアーでバラバラにします。
さらに、ブロックにするために、編集モードで押し出しをします。これをオブジェクトとしてバラバラにするために、構造的に分離したパーツで分離します。
このままだと、ブロックの原点で正解位置がばれるので原点をジオメトリに変えます。
「Start」を押すと、開始位置を覚えて、バラバラにし、タイマーで定期的に位置をチェックし、位置が正しければ終了します。

### Pythonのコード

https://github.com/SaitoTsutomu/Jigsaw/blob/main/__init__.py

以上
シェルコマンドをPythonから実行して結果をリアルタイムに標準出力に出す方法

# 概要

Python の [subprocess](https://docs.python.org/ja/3.9/library/subprocess.html) を使うことでシェルコマンドを実行可能だが、実行結果をリアルタイムに標準出力へとパイプする方法（かつエラーハンドリングが正しく行われる方法）がわかりづらいのでメモしておく。

ちなみに `subprocess.run` ではリアルタイムなパイプはできなかった。


# 方法

```py
import subprocess
import sys


def run_shell(cmd):
    print(f'cmd: {cmd}')
    with subprocess.Popen(cmd, encoding='UTF-8', stdout=subprocess.PIPE, stderr=subprocess.PIPE) as p:
        for line in p.stdout:
            sys.stdout.write(line)
        p.wait()
        for line in p.stderr:
            sys.stdout.write(line)
        print(f'return: {p.returncode}')
        if p.returncode:
            raise Exception(f'Error! {cmd}')
```

- エラー出力もリアルタイムに出したいなら、`stderr=subprocess.PIPE` を `stderr=subprocess.STDOUT` とするのが手軽。


```py:asyncio版
import asyncio
import sys

async def run_shell(cmd):
    print(f'cmd: {cmd}')
    process = await asyncio.create_subprocess_shell(
        cmd,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.STDOUT,
    )

    async for line in process.stdout:
        sys.stdout.write(line.decode('UTF-8'))
    
    returncode = await process.wait()
    
    print(f'return: {returncode}')
    if returncode:
        raise Exception(f'Error! {cmd}')

# asyncio.run(run_shell('your-command-here'))
```
Python で非 async な IO 処理を並列したい場合

# 概要

Python で並列処理したい場合は [asyncio](https://docs.python.org/ja/3.9/library/asyncio.html) が便利だが、EventLoop が設定しづらかったり、IO自体が async 対応してなかったり（つまりIO終わるまで制御を握ってしまう）などの場合、純粋に並列処理したい場合がある。
その場合の方法をメモしておく。

# 方法

```py
from concurrent.futures import ThreadPoolExecutor

def main():
    target_file_list = [
        'file1.dat',
        'file2.dat',
    ]
    # 平行して呼び出し
    with ThreadPoolExecutor() as executor:
        threads = [
            executor.submit(hoge.some_io_process, target_file)
            for target_file in target_file_list
        ]
        results = [
            th.result()
            for th in threads
        ]
    return results
```

## 注意点：`executor.submit` に `lambda` を渡してはいけない。

下記のように `lambda` を渡すと `target_file` がループにより変わってしまい、
`lambda` が実行する段階では後半の（タイミング次第ではすべての）実行で
最後のファイルを参照することになってしまう。


```py:NGの例
            executor.submit(
                lambda: hoge.some_io_process(target_file)
            )
            for target_file in target_file_list
```
Pythonを使ってPDFの改行無しの翻訳をDeepLで実行する

# 目的
ショートカットキーを使って簡単に改行無しのPDFの翻訳を行う。

# 環境
windows 10
python 3.10

# コード
## パッケージのインストール
今回使うパッケージをインストールします。
```python
pip install keyboard pyautogui pyperclip
# keyboard: ショートカットキーの受け取りに使う
# pyautogui: 画面の操作に使う
# pyperclip: クリップボードの取得に使う
```

## パッケージのインポート
必要なパッケージをインポートします。
```python
import keyboard
import pyautogui
import pyperclip
import re #　改行の削除
import time
import os # DeepLを開く
```
## メイン
```python
def main():
    # 　現在選択されているテキストをコピーする
    pyautogui.hotkey("ctrl", "c")
    # 　DeepLを開く
    os.system("DeepL.exeのパス")

    # 　コピーされたテキストを取得し改行を削除したテキストをクリップボードに保存する。
    text = pyperclip.paste()
    text = " " + text
    text = re.sub(r"\r\n|\r|\n", " ", text).replace("  ", " ")
    pyperclip.copy(text)

    # 0.075秒待つ。DeepLが開いてDeepLに移動するまで少し時間がかかるため少し待つ
    time.sleep(0.075)

    # DeepLの入力欄をクリックし以前のテキストをすべて選択し、上書きペーストする
    pyautogui.leftClick(x=121, y=185)
    pyautogui.hotkey("ctrl", "a")
    pyautogui.hotkey("ctrl", "v")
```

## 実行
```python
if __name__ == "__main__":
    #ショートカットキーを押すとmain関数を実行する
    keyboard.add_hotkey("ショートカットキー", main)
    #　escを押すとプログラムが終了する
    keyboard.wait("esc")
```

## ファイル全体
このスクリプトを保存しファイルを実行すれば終了するまでショートカットキーを押せば改行無しで翻訳をすることができる。
```python
import keyboard
import pyautogui
import pyperclip
import re #　改行の削除
import time
import os # DeepLを開く

def main():
    # 　現在選択されているテキストをコピーする
    pyautogui.hotkey("ctrl", "c")
    # 　DeepLを開く
    os.system("DeepL.exeのパス")

    # 　コピーされたテキストを取得し改行を削除したテキストをクリップボードに保存する。
    text = pyperclip.paste()
    text = " " + text
    text = re.sub(r"\r\n|\r|\n", " ", text).replace("  ", " ")
    pyperclip.copy(text)

    # 0.075秒待つ。DeepLが開いてDeepLに移動するまで少し時間がかかるため少し待つ
    time.sleep(0.075)

    # DeepLの入力欄をクリックし以前のテキストをすべて選択し、上書きペーストする
    pyautogui.leftClick(x=121, y=185)
    pyautogui.hotkey("ctrl", "a")
    pyautogui.hotkey("ctrl", "v")

if __name__ == "__main__":
    #ショートカットキーを押すとmain関数を実行する
    keyboard.add_hotkey("ショートカットキー", main)
    #　escを押すとプログラムが終了する
    keyboard.wait("esc")
```
Zoomで自動文字起こし・字幕を有効にして利用する + 日本語で聞き取る

# ZoomのWebサイトから字幕機能を有効にする


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/7bd19915-10fd-ac85-b0c2-9d624de9d249.png)

URL:
https://zoom.us/profile/setting

# Zoomミーティングを起動して、ライブ文字起こしを有効にする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/1207c272-670b-e6bb-a161-debc868d50d0.png)

# 結果

英語やん

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/e314040c-1aaa-1a52-1016-f879e2c3b825.png)

2022/03/28 現在日本語未対応…

# サードパーティーツール

「UDトーク」アプリを利用した例
APIトークンをUDトークに入力して利用した

- zoomのライブ文字起こしを無効にしておく
- UDトークアプリをスマホで起動して会話モードにしておく
- zoomのAPIトークンをUDトークの設定からUDトークに渡す

するとzoom画面でも字幕が表示された
zoomへの音声入力を翻訳してくれるのではなく、音声聞き取りはスマホアプリ側でやる仕様のようだ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/4f52793a-78e6-61c4-fdaf-fd4b0bdb6758.png)



# 参考

https://itxdancer.com/tech/zoom-subtitile/#toc4











<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Teamsのステータスを自動で変更する

# 困っていたこと

集中力のゴールデンタイムは誰にも邪魔されたくないのに、チャットで「ちょっといいですか？」とメンションが入ると集中できない。

Teamsのステータスを**応答不可**にすれば通知に気づかなくて済むのですが、
こまめにステータスを切り替えることを**忘れがち**。

#### 朝のこの時間帯だけはなんとしても守りたい。

というわけで毎日同じ時間になれば、Teamsのステータスを変えるスクリプトを作ってみた。

## 環境

Windows10
Teams
Python3.10

## まずは手作業でやってみる

### 1 Teamsを起動する

Windowsキーを押してから、「teams」と打てばこんな感じになる。

![2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75217/8b648238-184d-6f01-2dec-880931253f41.png)

この後Enterキー叩けば起動される。（起動済みの場合は最前面にくる）

### 2 Teamsの検索に移動
Teamsのショートカット（Ctrl + e)で検索窓にフォーカスを充てられる。
![2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75217/d2c25a06-3757-db97-bba4-3a9c26562c5f.png)
### 3 応答不可にするコマンド実行
Teamsのコマンド（/dnd）で応答不可にする
![2-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75217/5a69fa13-54b5-f122-70b0-71f9205c25aa.png)


## 自動化してみる

### Python準備する

pyautoguiをインストールする

```cmd:コマンドライン
python -m pip install pyautogui
```


```changestatus.py
import pyautogui
import time

## 1 Teamsを起動する
pyautogui.press('win')
# 次の入力処理までに1秒ぐらい待っておく。
time.sleep(1)
# 「teams」と打ってEnterキー叩いて起動する
pyautogui.write('teams', interval=0.25)
pyautogui.press('enter')
# 起動して次のことするまでとりあえず5秒ぐらい待ってみる。
time.sleep(5)
## 2 Teamsの検索に移動
pyautogui.keyDown('ctrl')
pyautogui.press('e')
pyautogui.keyUp('ctrl')
### 3 応答不可にするコマンド実行
# 次の入力処理までに1秒ぐらい待っておく。 
time.sleep(1)
# 「/dnd」と打ってEnterキー叩いてコマンド実行する
pyautogui.write('/dnd', interval=0.25)
pyautogui.press('enter')

```

### 実行してみる

```cmd:コマンドライン
python changestatus.py
```

### 自動実行

先ほどのコマンドラインをbatファイルにして
Windowsなんでタスクスケジューラに登録。
自分のゴールデンタイムに合わせてトリガーを登録すればOK。

## 注意点
PC操作中に起動するといきなり誤動作し始めたのかとちょっとびっくりする。
ちょっと手をとめてオートメーションを眺めているとよいです。

IMEがONの状態だと、コマンドが「・ｄんｄ」になってしまう。
解決には[ここ](https://teratail.com/questions/328041)が参考になる



## 参考

https://support.microsoft.com/ja-jp/office/teams-%E4%B8%8A%E3%81%AE%E7%8A%B6%E6%85%8B%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B-ce36ed14-6bc9-4775-a33e-6629ba4ff78e

https://support.microsoft.com/ja-jp/office/teams-%E3%81%A7%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B-88f61508-284d-417f-a53d-9e082164050b
【Rails】ENV[]とENV.fetch() {}の違い【Ruby】

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

## `ENV[]`と`ENV.fetch() {}`の違い
`ENV[]`と`ENV.fetch() {}`の違いは指定した環境変数が存在しない場合に`nil`を返すかデフォルト値を返すかの違いです。

例えば、以下の場合には、`RAILS_MAX_THREADS`、`DB_USER_NAME`、`DB_USER_PASSWORD`が存在しない場合にはnilとなります。
```detabase.yml

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV["RAILS_MAX_THREADS"] %>
  username: <%= ENV["DB_USER_NAME"] %>
  password: <%= ENV["DB_USER_PASSWORD"] %>
  host: db

```

以下のように記述すると`RAILS_MAX_THREADS`、`DB_USER_NAME`、`DB_USER_PASSWORD`が存在しない場合には{}内に記述したデフォルト値となります。

```detabase.yml

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV.fetch("DB_USER_NAME") { root } %>
  password: <%= ENV.fetch("DB_USER_PASSWORD") { rootpass } %>
  host: db


```
2022/3/28主にITとかセキュリティの記事

「Chrome」や「MS Edge」にゼロデイ脆弱性 - アップデートがリリース
https://www.security-next.com/135186

金融庁、金融機関にサイバー対策の強化を再要請(3/25)
https://jp.reuters.com/article/fsa-cyber-security-measures-idJPKCN2LM0AK

「Kajit」は誰だ――匿名性が生んだランサムウェア攻撃者間の疑心暗鬼(3/26)
https://techtarget.itmedia.co.jp/tt/spv/2203/26/news01.html

データなどの複製、外部保管の病院は2割弱　セキュリティ予算、年500万円未満が半数超(3/25)
https://www.cbnews.jp/news/entry/20220325183009

メルカリ、詐欺メール対策でSMSに「認証理由」(3/25)
https://www.watch.impress.co.jp/docs/news/1397983.html

米通信情報機関が「Quantum」プラットフォームを構築し量子技術でサイバー攻撃(3/25)
https://www.recordchina.co.jp/b891479-s12-c100-d0189.html

英警察、サイバー攻撃関与容疑で7人逮捕　米オクタなど標的(3/25)
https://jp.reuters.com/article/britain-cyber-lapsus-idJPKCN2LM05H

外交部 米国の量子攻撃を批判(3/25)
https://www.recordchina.co.jp/b891475-s12-c100-d0189.html

IWI、「サプライチェーン攻撃」を解説するホワイトペーパーを無料公開(3/25)
https://www.jiji.com/sp/article?k=000000029.000084379&g=prt

アメリカがロシアKGB後継組織の職員3人を原子力発電所など重要インフラに対するハッキングで起訴(3/25)
https://gigazine.net/news/20220325-russian-officials-charged-energy-sector-hacks/

ウクライナにハッカー30万人が加勢　メッセージアプリ通じ世界が連携(3/25)
https://www.newsweekjapan.jp/stories/world/2022/03/30-59_1.php

ゼレンスキー大統領、演説中にWiki改変される？　真っ黒画面に「中止せよ」警告文(3/23)
https://news.yahoo.co.jp/articles/82694c89f9f9ed837efce37919cfee147d396606

経済産業省「工場セキュリティガイドライン」を活用して工場設備の生産性を向上(4/15開催)
https://japan.zdnet.com/info/event/fortinet/202204/?utm_source=zdnet&utm_medium=banner&utm_campaign=2204_fortinet&utm_content=rect-info?tag=ztop

相模原市、個人情報流出か　委託業者のＰＣがウイルス感染(3/26)
https://www.kanaloco.jp/news/government/article-885724.html

「Trust Wallet」アップストアから一時的に削除(3/25)
https://coinchoice.net/apple-temporarily-removes-trust-wallet/

「FinTech実証実験ハブ」支援決定案件の実験結果について(3/25)
https://www.fsa.go.jp/news/r3/sonota/20220325/20220325.html

米、ロシアのサイバー大手「安保脅威」　中国2社も認定(3/26)
https://www.nikkei.com/article/DGXZQOGN25E8F0V20C22A3000000/

鳥銀ネットバンキング不具合(3/25)
https://www.nnn.co.jp/today/220325/20220325125.html
gormについて調べているときに調べたDB周りのこと。

# gormについて調べているときに調べたDB周りのこと。

## DSN
データ・リソース・ネーム
データベースの接続情報に付けられる識別用の名前。また特に決まりはないようなので使用するライブラリによって書き方は変わる。
多分ある程度の知見がある人が具体例の方がわかりやすいと思う。
### gorm&mysqlの例
```gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local```

### gorm&postgresの例
```host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai```

## プリペアドステートメント
プリペアドステートメントとは、プログラム上で動的にSQL文を生成する必要があるとき、可変部分を変数のようにしたSQL文をあらかじめ作成しておき、値の挿入は処理系に行わせる方式。実行効率を向上させ、SQLインジェクションを防止する効果がある。

## コネクション関連
gormでは最大接続数、最大アイドル接続数、最大ライフタイムをコネクション設定の例で使っていた。そのときにアイドル接続数と最大接続数の関係について認識が曖昧だったので調べた。
最大接続数は文字通り最大なので実際にある接続の数は0でも10でもいい。
また最大アイドル接続数に関しては、まず接続にはアイドルな接続とオープンな接続がありその違いはその接続を使って処理を行なっているかどうかである。最大アイドル接続数は維持できるアイドル接続の数を設定している。
上記の設定を変更する意味については[こちら](https://tutuz-tech.hatenablog.com/entry/2020/03/24/170159)にわかりやすく載っていた。

## Upsertサポートの部分を見ていて生成されたSQLがわからなかった。
生成されるSQL
INSERT INTO `users` *** ON DUPLICATE KEY UPDATE ***; MySQL
https://qiita.com/Yuki_Oshima/items/2a73cf70ccbf67bd5215
ここに詳細が載っている。

## PreloadとEagerload
Preloadは関連１つずつに対して別のクエリを発行しその値をキャッシュする。
EagerloadはJoinを使ってクエリを発行し関連を取得する。

## ロック
https://medium-company.com/%E5%8D%A0%E6%9C%89%E3%83%AD%E3%83%83%E3%82%AF-%E5%85%B1%E6%9C%89%E3%83%AD%E3%83%83%E3%82%AF/

## オプティマイザヒント
https://qiita.com/mkyz08/items/9dfa4a5ea636238afc3e
独自ヘルパ関数追加で階層のあるsessionを作ってみた。

# これは何？

Laravelは独自ヘルパ関数を作れます。

https://readouble.com/laravel/7.x/ja/helpers.html

今回は、独自ヘルパ関数で、sessionをラップした形のものを作り、
階層つきsessionを作成しました。

# どういうとき使うの？
id付きのページ
```/hoge/{id}```
にアクセスし、これを起点にsessionを保ちながらアクセスせざるを得ない場合使います。

例えば、
```
/hoge/10
↓
/fuga
↓
/piyo
```
の遷移

```
/hoge/20
↓
/fuga
↓
/piyo
```
の遷移

があるとします。

もし、sessionの値をそれぞれ、
```/fuga```や```/piyo```
と何かしら使うとしたらどうでしょうか？

今回は下記のようなケースを想定しました。
```
/hoge/10
↓
/fuga
↓
ここで別タブで
/hoge/20
↓
/fuga
↓
ここで元のタブに戻り
/fuga
↓
/piyo
```
ここのpiyoのsessionの値は10関連と20関連
どちらでしょうか？
これは20ですよね。10経由にも関わらず別タブで操作した時、sessionを書き換えているため20になります。
この問題を解決したいなぁと思いました。

# やり方
どこでも良いですが、自分はHelperディレクトリに作成しました。
```app/Helper/HogeSession.php
<?php
if (! function_exists('hoge_session')) {
    /**
     * 多階層セッションの独自ヘルパ関数
     *
     * sessionヘルパ関数を利用して、hogeのセッションをidごとに多階層で管理する
     *
     * 引数がnullだと、現在のhogeセッションをゲット、
     * 引数にarray入れると現在のhogeセッションに値をセット、
     * 引数にstringを入れると現在のhogeセッションからキーに対応する値をゲット
     *
     * @param null|array|string $key
     * @return mixed
     */
    function hoge_session($key = null)
    {
        $hoge_id = session('hoge_id');
        $hoge_session = session('hoge_session') ?? [];

        // 現在のhogeセッションをゲット
        if (is_null($key)) {
            if (array_key_exists($hoge_id, $hoge_session)) {
                return $hoge_session[$hoge_id];
            }
            return $hoge_session;
        }

        // 現在のhogeセッションに値をセット
        if (is_array($key)) {
            if (array_key_exists('hoge_id', $key)) {
                $hoge_id = $key['hoge_id'];
            }
            if (!array_key_exists($hoge_id, $hoge_session)) {
                $hoge_session[$hoge_id] = $key;
            } else {
                foreach ($key as $k => $v) {
                    $hoge_session[$hoge_id][$k] = $v;
                }
            }

            return session([
                'current_hoge_id' => $hoge_id,
                'hoge_session' => $hoge_session,
            ]);
        }

        // 現在のhogeセッションからキーに対応する値をゲット
        return $hoge_session[$hoge_id][$key] ?? null;
    }
}
```
ファイルをオートローダーで読み込む
```composer.json
	"autoload": {
		"classmap": [
          ...
          ..
		],
        ...
        ..
        .
		"files": [
			"app/Helper/HogeSession.php",
		]
	},
```

```
$ composer dump-autoload
```

HogeSession.phpを任意のコントローラーなどで使います。
```app/Http/Controllers/HogeController.php

public function fuga(Request $request)
{
    $hoge_id = $request->input('hoge_id');

    // リクエスト確定した段階でhogeセッションのcurrent_hoge_idをリクエスト値に変更
    hoge_session([
       'hoge_id' => $hoge_id　←例えば、10だったとする
    ]);

    $test = hoge_session('test');  ←10に関連する値

    hoge_session([
       'nantoka' => $request->input('nantoka'),　←10に関連する値として更新
       'kantoka' => $request->input('kantoka'), ←10に関連する値として更新
    ]);
}

```
これにて、requestにhoge_idを持たせれば、欲しいsessionの値が取得できます。
```
/hoge/10
↓
/fuga
↓
ここで別タブで
/hoge/20
↓
/fuga
↓
ここで元のタブに戻り
/fuga
↓
/piyo
```
上記の場合でもpiyoにて10に関するsessionを取得、更新できるようになりました。
Python で Windows で ctypes で OptiX を呼び出したいメモ

OptiX を Python で呼んでちょっとしたテストとか Windows でぺろっとやりたい.
OptiX のコードビルドとかめんどい...
SDK も regist しないと落とせないし...

ctypes でコンパイル不要で頑張ってみます.

## dll のありか

標準では PATH が通っていないようです.

OptiX のコードを見るとレジストリ探索とかしてたりします.
Python で winreg でレジストリ探索してもよいですが,
Windows だと(バージョンにもよるかも), 以下のところにありました.
 
```
from ctypes import *

dllpath='C:\\Windows\\System32\\DriverStore\\FileRepository\\nv_dispsig.inf_amd64_145fe9c72c40de0a\\nvoptix.dll'

optix = cdll.LoadLibrary(dllpath)
print(optix.optixQueryFunctionTable)
```

ハッシュは PC ごとに変わるようですので, Python で `C:\\Windows\\System32\\DriverStore\\FileRepository\\nv_dispsig.inf_amd64_*` で glob でみつけるとよいでしょう.
(`nv_dispsig` なフォルダは 1 個だけ)

## optixInit?

これもコードみるとわかりますが関数として用意はされておらず, optix SDK header のみにあります. 内部では上のように nvoptix.dll を読んでいます.

## 各種 optix 関数?

上で得た optixQueryFunctionTable に関数テーブルがあるようです!

## TODO

OptiX のヘッダーを見て各種呼び出しできるようにする.
(ライセンス的にヘッダーは MIT なので copyright 表記などしておけば問題ないでしょう)
コマンドラインで R を使って要約統計量を算出するワンライナー

### 入力用数列生成 (例)

- 一様乱数

  ```sh
  $ Rscript -e 'cat(runif(10), sep="\n")' > runif10.txt
  ```

### 統計量算出

- 算術平均や中央値等の要約 (Min., 1st Qu., Median, Mean, 3rd Qu., Max.)

  ```sh
  $ Rscript -e 'summary(as.numeric(readLines("stdin")))' < runif10.txt
  ```

- 標準偏差

  ```sh
  $ Rscript -e 'sd(as.numeric(readLines("stdin")))' < runif10.txt
  ```

- 分位点

  ```sh
  $ Rscript -e 'quantile(as.numeric(readLines("stdin")))' < runif10.txt
  ```

### CSV 出力

[readr](https://readr.tidyverse.org/) の `readr::format_csv()` (TSV なら `readr::format_tsv()`) を使う.

- 要約

  ```sh
  $ Rscript -e 'cat(readr::format_csv(tibble::enframe(summary(as.numeric(readLines("stdin")))), col_names = F))' < runif10.txt
  ```

- 分位点

  ```sh
  $ Rscript -e 'cat(readr::format_csv(tibble::enframe(quantile(as.numeric(readLines("stdin")))), col_names = F))' < runif10.txt
  ```
お絵描き伝言ゲームのgifファイルをmp4動画に変換する方法

# はじめに
お絵描き伝言ゲーム([Gartic Phone](https://garticphone.com/ja))では、
みんなで振り返りするときにみんなの回答と絵をgifファイルとして保存できます。
保存したGifをTwitterなどにそのまま投稿できますが、
(面白すぎて)厳選できなかったので1つの動画にしたいなと思ったのがきっかけです。

# 前提条件
* 動作環境はWindows
* FFmpegをインストールしておく

# 処理手順
1. 保存したgifファイルを1つのフォルダに格納
1. gifファイルをmp4ファイルに変換
1. mp4を1つに結合

```gif2mp4.cmd
rem gifファイルの保存先フォルダ
SET INDIR=D:\dengongame\20220328
rem mp4一覧のファイル
SET LISTFILE=D:\dengongame\20220328\mylist.txt
rem 出力するmp4動画のパスとファイル名
SET OUTFILE=D:\dengongame\20220328output.mp4
rem FFmpegの実行ファイルのパス
SET FFMPEGEXE=C:\ffmpeg\bin\ffmpeg.exe

rem カレントディレクトリを移動
CD /D "%INDIR%"

rem フォルダのgif->mp4に変換
for /r "%INDIR%" %%f in (*.gif) do (
"%FFMPEGEXE%" -i %%f -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" %%f.mp4
)

rem フォルダ内のmp4フォルダを一覧に出力
TYPE NUL > "%LISTFILE%"
FOR %%I in (*.mp4) DO (
    ECHO file '%%~FI' >> "%LISTFILE%"
)

rem 一覧のフォルダを1つのmp4ファイルに結合
"%FFMPEGEXE%" -f concat -safe 0 -i "%LISTFILE%" -c copy "%OUTFILE%"
```

# 解説
### 実行時のパス設定
SETコマンドで実行時のフォルダやパスを指定しています。
mylist.txtはgifからmp4に変換したmp4一覧を出力するために使用します。
```gif2mp4.cmd
rem gifファイルの保存先フォルダ
SET INDIR=D:\dengongame\20220117
rem mp4一覧のファイル
SET LISTFILE=D:\dengongame\20220117\mylist.txt
rem 出力するmp4動画のパスとファイル名
SET OUTFILE=D:\dengongame\20220117output.mp4
rem FFmpegの実行ファイルのパス
SET FFMPEGEXE=C:\ffmpeg\bin\ffmpeg.exe
```


### カレントディレクトリの移動
/Dオプションを使いドライブ変更も行っています。
```
rem カレントディレクトリを移動
CD /D "%INDIR%"
```

### gifファイルをmp4に変換
フォルダ内のgifファイルでループし、FFmpegにオプション指定しながらmp4に変換しています。
-i %%f　：入力ファイル
-movflags faststart　：メタデータを動画ファイルの先頭に
-pix_fmt yuv420p　：動画フォーマット
 -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" %%f.mp4　：おまじない[^1]
```
rem フォルダのgif->mp4に変換
for /r "%INDIR%" %%f in (*.gif) do (
"%FFMPEGEXE%" -i %%f -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" %%f.mp4
)
```


### mp4を1つに結合
フォルダ内のmp4ファイルを%LISTFILE%(mylist.xt)に出力し、
出力したmp4ファイルを1つのファイルに結合します。
```
rem フォルダ内のmp4フォルダを一覧に出力
TYPE NUL > "%LISTFILE%"
FOR %%I in (*.mp4) DO (
    ECHO file '%%~FI' >> "%LISTFILE%"
)

rem 一覧のフォルダを1つのmp4ファイルに結合
"%FFMPEGEXE%" -f concat -safe 0 -i "%LISTFILE%" -c copy "%OUTFILE%"
```

### コマンド実行
gif2mp4.cmdをダブルクリック

# 改善点
* 保存フォルダのドラッグ＆ドロップにする
* 作業完了したmp4ファイルを削除する

# おわり
変換した動画はyoutubeにアップできます。
これでいつでもどこでも思い出し笑いができますね:joy:

# 参考リンク
[^1]:動画変換時のエラー対応

https://qiita.com/genchi-jin/items/90078b6ec751fdacbc9e
Vueへの配列の渡し方

# 目次
[1.ブログ編集画面に、編集前記事の配列を表示させたい](#1-ブログ編集画面に編集前記事の配列を表示させたい)
[2.map関数](#2-map関数)

Laravel + Vue.js で、Vue側に配列を渡す処理をアウトプットとして書いてみました。

# 1. ブログ編集画面に、編集前記事の配列を表示させたい

今回実装させたかった機能は、
**ブログ編集画面で、編集前の記事のカテゴリを、編集画面のカテゴリ入力フォームに表示させたい！**
ということです。

![スクリーンショット 2022-03-28 1.27.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267102/7b5d681c-d81f-1473-1906-f0275b355bbe.png)


Laravel 単体だと、

```php5:edit.blade.php
<div class="form-group">
    <label for="exampleInputEmail1">カテゴリ</label>
    <input
    type="text"
    class="form-control"
    name="tagCategory"
    value="@foreach ($post->tags as $tag){{ $tag->tag_name }} @endforeach"
    />
</div>
```
こんな感じで value に foreach 文を書くことで実装できると思いますが、
今回はブログ編集画面に Vue を使っているためこのようにはできません。

# 2. map関数

**そこで使うのが、map 関数！**

まずは、v-bindを使いコントローラから Vue 側にカテゴリの配列を渡します。

``<edit-component    v-bind:tags="{{ ($post->tags) }}">  </edit-component>``

**`this.tags `自体はオブジェクトの連想配列になっているため、
`tag_name`だけを取り出した配列にしてあげないといけません。**

ここで map 関数を使います！

```vuejs:EditComponent.vue

<script>

name: "EditComponent",

props: {      
    tags: { type: Array },
},

data(tags) {
    const category = this.tags.map((item) => "#" + item.tag_name );
    const tag_category = category.join("");

    return {
        tagCategory: tag_category,
    };
},

```

そして編集画面のカテゴリ入力画面を、`v-model="tagCategory" で指定して
`
```vuejs:EditComponent.vue
<div class="form-group">
    <label for="exampleInputEmail1">カテゴリ</label>
    <input
    type="text"
    class="form-control"
    name="tagCategory"
    v-model="tagCategory"
    />
</div>
```

実際の画面がこんな感じです！
編集前の記事で使われていたカテゴリがちゃんと表示されました！
これでわざわざカテゴリを書き直す必要もありません。

![スクリーンショット 2022-03-28 1.18.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2267102/7b92ca11-1126-d29b-18f6-f0b8d1dee8f2.png)

こんな便利なものがあったんだなぁ。
もっと勉強頑張りますっ！
[Power BI]スナップショットABC分析を実装する② ～TREATAS関数や中間テーブルを使うぞ編～

# はじめに

スネップショットABC分類についての続編です。

前の記事はこちら。

https://qiita.com/hanaseleb/items/cce730320af2fe25b84c

また、別記事にて静的ABC分類をまとめています。

https://qiita.com/hanaseleb/items/b80e28459096e40c3808

元ネタはみんな大好き、[DAX Patterns](https://www.daxpatterns.com/)です。

https://www.daxpatterns.com/

## ABC分類ごとに売上を表示する

前回記事の最後に年ごとにABC分類をクラス分けされているスナップショットテーブルを作成することができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/d7c9cbf1-631f-be7d-ea9f-f0a03ee0f834.png)

### ABC分類別に年ごとの売上を表示するマトリクスビジュアルを作成

マトリクスビジュアルを作成すると、全て同じ売上金額が表示されてしまい、期待した数字ではありません。
これは作成した **「年」** 列が、日付テーブルとリレーションの関係がなくなってしまっているのが原因です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/28b8790a-7ced-4a2b-06d6-ebcbb9e7cde6.png)

### TREATAS関数

この状態を解消するためには、`TREATAS`関数を使用します。

https://docs.microsoft.com/ja-jp/dax/treatas-function

:::note
- 指定する列の数は、テーブル式の列数と一致するとともに、同じ順序である必要があります。

- テーブル式で返された値が列に存在しない場合、その値は無視されます。 たとえば、TREATAS({"Red", "Green", "Yellow"}, DimProduct[Color]) では、列 DimProduct[Color] に対して、3 つの値 "Red"、"Green"、および "Yellow" を使用してフィルターが設定されます。 DimProduct[Color] に "Yellow" が存在しない場合、有効なフィルター値は "Red" と "Green" になります。

- テーブル間にリレーションシップが存在しない場合の使用に最適です。 関連するテーブル間に複数のリレーションシップがある場合は、代わりに USERELATIONSHIP を使用することを検討してください。
:::

`ABC by Year`テーブルは、下図の項目・順番で並んでいることを確認した上で、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/4bb37f9c-fc44-b1a4-f690-acc9de00c9eb.png)

下記のようなDAX式を記述します。

```dax
ABC Sales Amount = 
var RemapFilterABC = 
    TREATAS(
        'ABC by Year',
        'Products'[商品ID],
        '日付テーブル'[年_yyyy年],
        'ABC by Year'[ABC Class]
    )
VAR Result =
    CALCULATE (
        [受注額],
        KEEPFILTERS ( RemapFilterABC )
    )
RETURN
    Result
```

このメジャーで算出した売上を使用してマトリクスビジュアルを作成すると、
期待通りの数字が出ていることが確認できます:smiley:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/95d33591-468b-588e-5840-9a84f5f6df85.png)

## モデリングの工夫

`TREATAS`関数は強力な関数である一方、概念がわかりにくいところがあります:sweat_smile:
今度は中間テーブルを作成してDAX式をよりシンプルにしていく方法を模索します。

### 中間テーブルの作成

先程`TREATAS`関数で関連付けた **「年」** の中間テーブルを作成します。
年のみを抽出したテーブルを下記のDAXで記述していきます。

```新しいテーブルを作成.dax
Years = DISTINCT ( '日付テーブル'[年_yyyy年] ) 
```

そして、リレーションをこのように設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/7cca43ad-782d-4df9-dc78-f703f0ea63fd.png)

ここまで下準備をおこなっておけば、売上を算出するDAXは下記のようにシンプルになります。

```
ABC Sales Amount Opt = 
CALCULATE (
    [受注額],
    'ABC by Year'
)
```

このDAXを使用してマトリクスビューを作成すると、こちらも期待した数値になりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/5a769233-187f-7846-e4e0-a67eeb7a843e.png)

## まとめ

TREATAS関数を使ったり、モデリングの工夫でDAXをシンプルにしたりと、スナップショットABC分類を読み解くのは勉強になるなぁ:relaxed:
業務に応用をきかせやすい考え方なので、マスターしたい:muscle:
主なブラウザのバッテリー消費量の比較

# はじめに
僕が高専に入学するにあたってノートPCを購入しました。そのPCの電池を長持ちさせるために、どのアプリが電力を消費しているか調べたところ、ブラウザが一番消費していました。
そのため、なるべく消費電力を抑えるために、主なブラウザにおける消費電力を図ってみることにしました。

# せっかちな人のために結論
Youtube再生時はVivaldiが一番バッテリー消費量が少なかった。
ページの読み込みの繰り返し(GoogleMapのスクロール)では、OperaとEdgeがバッテリー消費量が少なかった。
総合的にみると、Operaがバッテリー消費量が少なかった。

# 実験
## 実験環境
メーカー製の管理アプリの機能を用いて、PCの充電を80%ピッタリまで充電したうえで、ディスプレイ等を表示した通常の状態と同じような状態で行いました。
また、バックグラウンドで動作する機能やアプリ等を極力排除するため、シークレットウィンドウを用いたうえで、できる限りバックグラウンドアプリも閉じました(後述の例外除く)。
さらに、音量や画面の明るさといった端末の設定は全ブラウザで同じに設定し、ブラウザの設定は初期設定で同期のためのログイン等は行わずに実験しました(Operaは省電力モード有効)。


PCのスペックは以下の通りです。
・CPU 11th Gen Intel® Core™ i7-1165G7
・SSD PCle Gen3 x4対応 1TB SSD
・GPU Intel® Iris® Xe Graphics
・ディスプレイ 4K OLED タッチ対応
## 実験方法
ストリーミング時の消費電力、ページ読み込み時の消費電力の2つの分野の測定を行いました。
### ストリーミング時の計測
Youtubeの動きと音声がある動画を流し、1時間経った時のバッテリー残量を計測しました。
### ページ読み込み時の計測
Google Mapにおいて自宅から西にずっとスクロールしていき、30分立った後のバッテリー残量を計測しました。LogicoolのG HUBアプリと対応マウスを用いて、左キーを長押しするマクロを組んで行いました。その関係で、G HUBアプリがバックグラウンドで起動した状態で行いました。

# 結果
以下の表はバッテリーの消費量を示しています。
| ブラウザ名  | 動画ストリーミング |ページ読み込み|
|:-----------|:------------:|:------------:|
| Firefox       | 32%        | 23%         |
| Chrome     | 29%      | 22%       |
| Edge       | 29%        | 21%         |
| Opera         | 28%          | 21%           |
| Vivaldi      | 25%       | 27%       |

# 考察
Firefoxはよく言われるように、全体としてバッテリー消費量は多かったです。近年Firefox離れが起きている中で、改善が必要な部分の一つかもしれません。
ChromeとEdgeに関しては、以前はEdgeのほうが少ないといわれていましたが、Googleの努力の結果Chromeが追い付いてきたのかほぼ同等の消費量となりました。
また、Operaは全体の中でも安定してバッテリー消費量が少なく、省電力モードもあることからバッテリーの持ちがよいブラウザといえそうです。
Vivaldiは、Youtubeの再生に関しては群を抜いて良い成績であるものの、ページ読み込みのパフォーマンスは低くなっています。この実験の誤差である可能性はあるので、実際に使ってみて試してみるのがいいかもしれません。

# リンク
Chrome

https://www.google.com/intl/ja_jp/chrome/

Firefox

https://www.mozilla.org/ja/firefox/new/

Edge

https://www.microsoft.com/ja-jp/edge

Opera

https://www.opera.com/ja/browsers/opera

Vivaldi

https://vivaldi.com/ja/
【React】「wojtekmaj/react-datetime-picker」を使用して日付と時間の入力ボックスを実装する

## 概要
日付と時間が入力できるinputをどう実装すれば良いかなと思って、[wojtekmaj/react-datetime-picker](https://github.com/wojtekmaj/react-datetime-picker)というライブラリを見つけたので、試してみました。
実装のサンプルと、導入にあたっての留意点などを記載します。

## 実装サンプル
ライブラリのGitHubの実装サンプルそのままですが、以下のような実装で表示はできます。
細かい設定については[User guide](https://github.com/wojtekmaj/react-datetime-picker#user-guide)を参照ください。

```react
import React, { useState } from 'react';
import DateTimePicker from 'react-datetime-picker';

function MyApp() {
  const [value, onChange] = useState(new Date());

  return (
    <div>
      <DateTimePicker onChange={onChange} value={value} />
    </div>
  );
}
```

日付のカレンダーは、以下のように選択形式で表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32098/3994b0c9-1bd7-c62d-03d5-fe806fe2d37e.png" width=300 />
時刻入力はテキストになりますが、時計のイメージが表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32098/53a4dbd4-652e-b395-e966-21d0e11c3050.png" width=250 />

## 導入にあたり留意点

### 1. wojtekmaj/react-calendarのインストール
CSSについて関連ライブラリの[wojtekmaj/react-calendar](https://github.com/wojtekmaj/react-calendar)のものを使ってるので、併せてインストールが必要です。私が試した時の`package.json`の設定は以下の通りです。

```json:package.json
"dependencies": {
    "react-calendar": "^3.7.0",
    "react-datetime-picker": "^3.5.0",
}
```
### 2. transpileの設定（Next.jsを使用している場合のみ）
Next.jsを使用している場合は、transpileの設定が必要です。詳細は[Next.js + Fullcalendar v5 を攻略する](https://qiita.com/yk2220s/items/8ed4d781412f6c4e9c45)の記事を参考に、`next-transpile-modules`をインストールします。
そして、`next.config.js`を以下の通りに設定します。（webpackは5の前提です）

```js:next.config.js
const withTM = require("next-transpile-modules")([
  "react-calendar",
  "react-datetime-picker",
]);

module.exports = withTM({
  future: {
    webpack5: true,
  },
});
```
array.map(&:method)の【&:】の部分ってなに？

## mapメソッド
``mapメソッド``は、要素の数だけ繰り返しブロックを実行し、ブロックの戻り値を集めた配列を作成して返す。

```rb
array = ["a", "b", "c"]
array = array.map {|item|  item.upcase }

=> ["a", "b", "c"]
```

## 何をしているのか
``array.map(&:メソッド名)``の型をし、配列の要素１つ１つに``(&:メソッド名)``で与えられたメソッドを呼んでいる。

```rb
['a' ,'b'].map(&:upcase) #=> ["A", "B"]
```

``&``はそのメソッドをブロックとして展開することを意味する。
この時、呼び出すオブジェクトは各要素として呼び出す。

例えばメソッドを``id``とした場合、
・``map(& )``はブロック``map{|x| }``に展開
・その中身は``:id``のメソッド``.id``

``array.map(&:id)``は以下と同義になる。

```rb
array.map{|x| x.id}
     ||
array.map(&:id)
```

## 参考記事
[Railsでよく見る arr.map(&:id) の意味](https://qiita.com/s_tatsuki/items/869af9c0c33d9d650f3f)
[【Ruby】array.map(&:method)を理解する](https://qiita.com/k-penguin-sato/items/420d7487b28b5d58cac4)
AsciiDocのファイルを結合して表示する

# はじめに

- `AsciiDoc`でマニュアルを書いていましたが、最終的にユーザー毎に利用する内容（章立て）に合わせて提供したいという話があったので、最初、すべての内容を纏めて記載していたが、慌てて章立て単位にファイルに分割して、ユーザー単位に出力しなければならなくなった。
- 章立てを認識させるために、どうすべきかを考えたときに`leveloffset`を使えば、うまくいくことを聞いて、修正することになった

# やったこと
- 最初は、以下のように一つのファイルに纏めて記載していた（一部抜粋）
　　　<img width=75% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518581/6cc0c2e9-910d-8f5d-90c9-a4c9ff117b45.png">

- 次にファイル分割を行いました
    - まずは`all_JapaneseMap.adoc`ファイルの26行目以降を切り取り、北海道・東北地方の内容を別ファイル`tohoku.adoc`に移動します。
        - `:imagesdir: ./images`は、各ファイルに残しておくことで、先々、当該ファイル別にフォルダ作成する際などに利用できるので入れておいた方が良いと思い、ここだけは残しました。+
    - <img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518581/e6fd7d89-4aea-5130-15ef-3458e65cc4aa.png">
    - 作成した`tohoku.adoc`を読込むために、`include`して、`tohoku.adoc`に`leveloffset=+1`を渡すことで、1章目から開始されていきます。
    - <img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518581/16aa83c3-625b-12dc-4fe1-89bf2204618a.png">

 - 最後に`tohoku.adoc`ファイルでセクションタイトルを"=="として指定していましたが、このファイルの中では、最初になるので、インデントを一つ全体的に上げてみました。
    - 結果、やりたいことが崩れずに、実現できたので、これを最終形態としました。
    - <img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518581/6473599c-9d0e-2dfd-90e6-155c82e3d837.png">
    - `include`した``ファイルの表示結果は、変わらなかった
    - <img width="75%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518581/d1ed5970-62ee-baf7-3bce-8025441368e8.png">


# 解釈したこと
- セクションタイトルに`leveloffset=+1`とインクリメントした場合、該当ファイル内で最初始めるセクションタイトルに対して`leveloffset`の値がそのまま渡され表示される
    - つまり、最初の状態も`==`としていたが、`=`が存在しないため、**1.**と解釈されたのだと推察した
    - そのままでも良いのかもしれないが、先々、さらに分けたい要素などが出た場合などを考えるとファイル内でセクションタイトルは`=`から初めておいた方が他のファイルとの関連性を意識しなくて済むので良いと理解しました。
可変幅のボックス（レスポンシブデザインの練習）

# レスポンシブデザインの基本
レスポンシブの基礎となる「可変幅のボックス」をいろいろ試す記事です。

CodePenで埋め込んだので、
`EDIT ON CODEPEN`で編集し結果を見比べてみてください！

## １カラムの可変レイアウト
### 基本の1カラム
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="xxpqore" data-preview="true" data-editable="true" data-user="yutaka_pg" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yutaka_pg/pen/xxpqore">
  Untitled</a> by ゆたか (<a href="https://codepen.io/yutaka_pg">@yutaka_pg</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### 最大幅固定の1カラム
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="QWapXmQ" data-preview="true" data-editable="true" data-user="yutaka_pg" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yutaka_pg/pen/QWapXmQ">
  HTML+CSS L01-02</a> by ゆたか (<a href="https://codepen.io/yutaka_pg">@yutaka_pg</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### フルードイメージ
<p class="codepen" data-height="1000" data-default-tab="html,result" data-slug-hash="wvpJVLZ" data-preview="true" data-editable="true" data-user="yutaka_pg" style="height: 100px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yutaka_pg/pen/wvpJVLZ">
  HTML+CSS L01-03</a> by ゆたか (<a href="https://codepen.io/yutaka_pg">@yutaka_pg</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 複数カラムの可変レイアウト
### flexをつかった2カラム
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="XWVRmXB" data-preview="true" data-editable="true" data-user="yutaka_pg" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yutaka_pg/pen/XWVRmXB">
  HTML+CSS L01-04</a> by ゆたか (<a href="https://codepen.io/yutaka_pg">@yutaka_pg</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
Troubleshooting for updating to Windows 11

When I try to update my pc to windows 11, I got a error of this. 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51455/a2422ec5-93b6-1f34-a170-b8dcf1b55dd2.png)

At the beginning I think that my pc may not able to update to windows 11. 
But after a little bit searching I found a way to check the detailed reason from [here](https://docs.microsoft.com/en-us/answers/questions/703180/windows-11-upgrade-error.html). My case is that my default browser is IE....


- Open this folder C:\$WINDOWS.~BT\Sources\Panther
- Locate the largest file which ends with "... APPRAISER_Human_Readable.xml"
- Open this file with Notepad or some other text editor.
- Search "This PC can't be upgraded".
- A few lines above of the line found, you will see the reason with headed with Property Name="SdbAppName" Value="The detailed reason..."
基本情報技術者試験対策　17日目

基本情報技術者試験勉強　17日目
-
この記事の目的
-
今年の5月に基本情報技術者試験を合格するために、過去問で間違えた箇所をただまとめる自分のための記事

プロフィール
-
・文系大学の３年生
・ITパスポートは保有
・ウェブアプリやサイト作成を個人で行ったことがある程度
・猫好き

今日の目標
-
50問中40問は正解する。

間違えた箇所
-
1、バウンジングサービス
顧客のサーバや送信機器を設備するために、事業者が所有する高速回線や耐震説が整った施設を提供
ストラテジ系 » システム戦略 » ソリューションビジネス

2、IPアドレスクラス
クラスA → 0 ~ 127
クラスB → 128 ~ 191
クラスC → 129 ~ 223
クラスD → 224 ~ 239

3、CHAP（Challenge Handshake Authentication Protocol）
チャレンジレスポンス方式で相手を認証するプロトコル

4　、
　　　　        　　　　　　　インターネット
　　　　　　　　　　　　　↓　↑
　　　　　ファイヤーウォール　　←→　内部セグメント　→　DBサーバ　
　　　　　　　　　　　　　↓　↑
　　　      　　　　　　　DMZ → WEBサーバ

5、EDI（Electronic Data Interchange)
異なる組織に設置されている端末感で、通信回線を介して取引のためのメッセージを交換する

レベル１　情報伝達規約
ネットワーク回線や伝送手順など、文字通り情報をやり取りするための取り決め

レベル２　情報表現規約
データの構造やデータ項目など、表現法のルールなど情報データをお互いのコンピュータで理解できるようにするための取り決め

レべル３　業務情報運用規約
どんな情報をやり取りするか、情報の訂正方法やエラーの扱いなどの業務やシステムの運用に関する取り決め

レベル４　取引基本規約
検修時期、支払い時期、支払い方法などをEDIにおける取引の法的有効性を確立するための取引

6、バイオメトリクス認証
本人拒否率（False Rejection Rate (FRR))
他人受入率（False Acceptance Rate（FAR))
トレードオフの関係

7、ライトスルー方式
主記憶の更新と同時にキャッシュメモリの更新を行う

8、ライトバック方式
新しい情報をキャッシュメモリに取り出すとき、キャッシュ状では不要になった情報を主記憶に書き込む

9、ディスクキャッシュ
主記憶のアクセス時間と磁気ディスクのアクセス時間とのギャップを補う

10、メモリインタリープ
主記憶をいくつかの区画に分割し、メモリのアクセスを高速化する

振り返り
-
テクノロジ系だと、やはりコンピュータシステムと基礎理論の範囲の正答率が低い、反対に、開発技術は得意な法である。
ストラテジ系だと、経営戦略の部分ができていなく、4割程度の正答率で、記号と法務の正答率は8割と高かった。
マネジメントは、比較的高く、7割は取れていた。
次回も、引き続き、テクノロジ系のコンピュータシステムと基礎理論をメインに取り組む。

>引用
基本情報技術者試験ドットコム
https://www.fe-siken.com