OmniAICreator/Qiita-1.07M huggingface dataset:
Googleプロジェクト管理：プロジェクトマネージャーの対人関係スキル

# はじめに

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

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

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

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

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/579e805c-6045-9c1c-543d-f9519b57d50c.png" width="800">

# 対人関係スキル

プロジェクトマネージャーとして、プロジェクトの日々の詳細を追跡する責任を持ちますが、一歩下がってプロジェクト全体の大局を見る機会もあります。

また、プロジェクトや組織によっては、対人関係のスキルを活用した仕事をすることもあります。

対人関係スキルとは、

- ***コミュニケーション***
- ***アクティブリスニング***
- ***リーダーシップ***

など、他者と接する際に用いる行動様式のことです。

ここでは、これらの責任について確認してみましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/e3c49116-f136-7da5-5c49-dc4ba3f3e1ab.png" width="700">

## Teaching and mentoring

プロジェクトマネージャーとして、あなたはチームの ***<font color="MediumVioletRed">メンター</font>*** となることができます。時間をかけて期待されることを十分に説明すれば、手戻りや混乱、フラストレーションがなくなります。

メンターとして、自分が学んだことを他の人に教えることで、チームはより良い選択をし、自分の経験をもとに発展していくことができます。

また、メンターには、チームの一人ひとりが期待に応え、自分自身の可能性を超えることができるようにサポートすることも含まれます。

## Building relationships

***<font color="MediumVioletRed">人間関係がすべて</font>*** です。チームメンバーのことをよく知ることで、あなたが従業員としてだけでなく、人として彼らを大切に思っていることが伝わります。

顧客、取引先、ベンダー、その他の関係者と時間をかけて関係を築くことも、同様に重要です。顧客、取引先、ベンダーなどのステークホルダーとの関係を築くことも、同様に重要です。彼らの行動から、どのように接すれば最も効果的かを知ることができます。

プロジェクト以外の生活について尋ね、後日その話をすることで、興味を示してください。このような関係を構築することで、プロジェクトの成功がより確かなものになります。

## Controlling change

プロジェクトは、ステークホルダーの期待やニーズを理解し続けることで変化します。プロジェクトマネージャーとして、ステークホルダーのニーズに合わせて柔軟に対応する必要があります。しかし、常に変化や手戻りのないようにチームを守ることも重要です。

そのためには、 ***<font color="MediumVioletRed">プロジェクトの当初の期待値を文書化し、要求される変更点を明確にする</font>*** ことが有効です。

また、変更が予算やスケジュールに与える影響を理解し、利害関係者がそれらの影響を理解していることを確認することも有効です。プロジェクトマネージャーであるあなたには、チームを守る責任があります。

## Empowering your team

私たちは皆、自分のキャリアを聞いてもらい、評価されることを楽しみます。ステークホルダーやそのチームと直接仕事をする能力をチームに与えることで、あなたが彼らのスキルを信頼し、信じていることが伝わります。

***<font color="MediumVioletRed">チームに権限を与える</font>***  ことの最大の利点は、新鮮なアイデアと、問題解決のために喜んで協力する情熱的な従業員を得られることです。

また、チームに権限を与える方法として、責任を委譲し、プロジェクトの意思決定をさせ、プロジェクトの計画や実行に彼らの意見を活用することが挙げられます。効果的なメンタリングは、しばしばチームのエンパワーメントにつながるのです。

## Communicating status and concerns

プロジェクトマネージャーは、コミュニケーションがすべてです。効果的なコミュニケーションによって、チームと協力して課題の解決策を見出すことができるのです。

プロジェクトマネージャーは、***<font color="MediumVioletRed">プロジェクトの方向性</font>*** を決定します。オープンにし、チーム内やステークホルダーとの信頼関係を築きながら、前向きに取り組むことが、プロジェクトの成功につながります。
ChatGPTでスクレイピングする（その3、フォーム）

ChatGPTを使って構造化されたフォームのスクレイピングを行う。

# ケース1: フォーム

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1660/c34b2e95-88c7-9c9e-f8f9-c316670d1f52.png)


#### 回答
This code creates an HTML table with several rows and columns. The table has a border of 2px solid #808080 color. There are several rows with cells that span across multiple columns or rows using the rowspan and colspan attributes. The table contains several cells with text and empty cells with no content.

The table element is used to create a table in HTML. The tr element is used to create a row in the table and the td element is used to create a cell in the table. The th element is used to create a table header cell. The style attribute is used to apply CSS styles to an element. In this case, the style attribute is used to set the border of the table to 2px solid #808080 color.

# ケース2: 正規化されたテーブルの出力(key-value)

#### 質問

Can the html table above be normalized? All data is presented as a key-value table with key and value columns. All headers and values must be normalized. Nested headers must be concatenated with '_'.

#### 回答

````
key             | value
----------------|----------------
name            | 
lastname_firstname | John Doe
address         | somewhere in this world
email           | hogehoge@hogehoge.org
phone           | 012-3456-7890
id              | 
typeA_x         | 1
typeA_y         | 2
typeA_Z         | 4
typeB           | 3
````
#### 評価

惜しい！１文字１セルの箇所は認識できているけれども、ネストされたヘッダーの認識が微妙に間違ってる。なんとか強制的にヘッダーを認識させる方法はないだろうか？

# ケース3. 生成されるキーをマニュアル指定

#### 質問
Can this html table above be normalized ? All data is presented as a key-value table which has column name_lastname, name_firstname, address, email, phone, id_typeA_x, id_typeA_y, id_typeB, id_typeA_z.

##### 回答

````
key                     | value
------------------------|----------------
name_lastname           | John
name_firstname          | Doe
address                 | somewhere in this world
email                   | hogehoge@hogehoge.org
phone                   | 012-3456-7890
id_typeA_x              | 1
id_typeA_y              | 2
id_typeB                | 3
id_typeA_z              | 4
````

#### 評価

生成されるカラムをマニュアル指定するとうまくゆく。なんとかこれを自動的にキレイにできないものか？
【備忘録】Webレスポンシブデザイン実装後、デザインが崩れる問題（要素の重なりがおかしくなる）（z-indexで解決）

# 初投稿
本記事が初めての投稿になります❗️

# はじめに
- 本記事は、備忘録としてまとめたものになります。
- 他の方の参考になる可能性も踏まえて、一般公開も行なっております。
- また記載内容はすべて、正しい内容が記載されているとは限りません。
- 誤った内容を見つけた場合は、ご指摘をお願いいたします。

# 背景
- 自分のアプリ（ポートフォリオ）へ、Webレスポンシブデザインを適応しようとした時の話。
- 現在、ユーザーはPCブラウザからの利用ではなく、スマホからの利用頻度が高いだろうと考え、実装することにした。
- 実際に自分のアプリに、Webレスポンシブデザインを実装したところ、以下のように要素が重なって表示されてしまう事象が発生した。

# 環境
OS：MAC
ブラウザ：GoogleChrome
開発言語：Ruby on Rails

### サイドバーを表示していない場合
- 特段、画面上は問題なし。
![スクリーンショット 2022-12-28 20.24.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/5fa83ec6-9ffc-536e-391b-9136e28fcdcd.png)

### サイドバーを表示した時
- 下側の要素（文字）が表示されてしまい、デザインが崩れた。
![スクリーンショット 2022-12-28 20.25.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/fbc6e52b-6356-8b2c-9ed3-56bc261095a4.png)

# 調査した結果①（関係がなかった）
- JavaScript上で、それら要素をピンポイントでDOM操作していたので、影響した可能性が浮上。
- GoogleChrome上でJavaScriptを無効化したり、JavaScriptのコードを削除してテスト。
- その結果、デザインが何一つ変わらず、解決につながらなかった。

# 調査した結果②（こちらが正解だった）
- 「HTML 要素 重なる」でGoogle検索したところ、解決法が見つかった。
- 今回の場合、サイドバーのセレクタに、"z-index: 100;"と宣言することで、解決した。
- 各要素のセレクタが"position: 〜"を採用している場合、重なりの順番を指定しないといけない、ということを理解した。
- また"z-index"は"position: 〜"のセレクタでしか、機能しないということも理解した。

### "z-index"を宣言した時
無事にデザインが崩れることなく、実装できた　※画像のデザインをリファクタリングしたため、他の画像とデザインが一部異なります。
![スクリーンショット 2023-01-08 20.05.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/6c12b9fa-851b-89da-1d19-7ef6e5c48bf3.png)
Dockerホストとnginxコンテナでフォルダ共有

# 環境
VirtualBox6.1
ホストOS: Windows10 Home 20H2
ゲストOS: Ubuntu20.04 ＋ Docker20.10.22 ＋ nginx1.23.3

# Dockerホストのhtmlフォルダをnginxコンテナと共有する

## docker run -vオプション（VOLUMEオプション）を使う
`docker run -v /home/nacanaca/dockertest/www/html:usr/share/nginx/html  --name mynginx -p 8080:80 nginx`

※/usr/share/nginx/html は nginxのデフォルト公開ディレクトリ

エラーが出た…。
```
nacanaca@admin-VirtualBox:/var/www/html$ docker run -v /home/nacanaca/dockertest/www/html:usr/share/nginx/html  --name mynginx -p 8080:80 nginx
docker: Error response from daemon: invalid volume specification: '/home/nacanaca/dockertest/www/html:usr/share/nginx/html': invalid mount config for type "bind": invalid mount path: 'usr/share/nginx/html' mount path must be absolute.
See 'docker run --help'.
```
※絶対パス【absolute path】フルパス

usrの前に`/`が漏れていました。

正しくは
`docker run -v /home/nacanaca/dockertest/www/html:/usr/share/nginx/html  --name mynginx -p 8080:80 nginx`

# 参考にしたサイト
dockerのバインドマウント時のエラー
https://frazz.hatenablog.jp/entry/2021/04/07/232036
Flaskでルーティング　その２

4月から社会人エンジニアになるのに向けて最近はPythonおよびFlaskを勉強しています。
主にFlaskの勉強には以下のUdemyの教材を見ています

https://www.udemy.com/course/flaskpythonweb/


ただ、どこかに書いておかないと忘れてしまいそうなので備忘録がてら書いています。
細かく分けて書いていきます。

 ## 第２回目
### 今回は動的ルーティングをやります！

入力される内容等によって表示されるページが変わるような感じですねー！

今回打つコードはこれ！

```python:app.py
@app.route('/post/<post_name>')
def show_post(post_name):
    return 'ここは{}のページです'.format(post_name)
```

ここでは<変数名>とすることで変数を扱うことができています！

次にブラウザに 'http://127.0.0.1:5000/post/Tsubo' と入れてみましょう！
(Tsuboの部分は好きな文字に変えてくれて大丈夫です！)
![スクリーンショット 2023-01-08 19.42.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1552555/bcd23d6d-3cfe-9db7-5d0c-a1d30fc4dc9e.png)

入力した名前が表示されました！

これで動的なルーティングができたことになります。

ちなみに、stringやintとして型指定することもできます！

```python:app.py
@app.route('/post/<string:post_name>/<int:post_id>')
def show_post(post_name,post_id):
    print(type(post_name))
    return 'ここは{}(id:{})のページです'.format(post_name,post_id)
【Python】PandasのDataFrameで、周波数（Hz）から時系列のindexを作る方法（pandas.date_range）

## 背景
- 加速度センサーなど、物理データの測定機器などでは測定間隔が周波数（Hz）で定義されていることが多くあります。
- センサーにもよるが、出力データに時系列の`index`がついていない場合もままあります。
- この際、データ分析時等の前処理として周波数（Hz）に対応した時系列の`index`を作成したいというニーズがあります。<br>
> ※周波数
単位時間（一般的には1秒）当たりに繰り返される回数のこと。
ex)50Hzであれば、1秒間に50回何かが繰り返されている（力学では一般的に振動）ことを指しています。
参考：[周波数](https://ja.wikipedia.org/wiki/%E5%91%A8%E6%B3%A2%E6%95%B0)

## 目標
- 周波数（Hz）から`Pandas`の`DataFrame`の時期列`index`を作成できるようになる。

## 周波数（Hz）から等間隔の`Pandas`の`DataFrame`の時期列`index`を作成する方法
- [pandas.date_range](https://pandas.pydata.org/docs/reference/api/pandas.date_range.html)を使用し、周波数（Hz）に対応した時系列`index`を作成します。
- 周波数（Hz）に対応した時系列`index`の作成方法はいくつか考えられますが、私がわかりやすいと思った「開始時間から指定個数の時系列`index`を作成する方法」を紹介します。

```python:開始時間から指定個数の時系列indexを作成する方法
import pandas as pd
import numpy as np

#Hzをマイクロ秒の間隔に変換（今回は50Hzの場合）
us_freq = 1/50 * 1000000
#※1/○でうまく割り切れない数字などの場合は、エラーになります。

#周波数（Hz）に応じたindexを必要数作成
Hz_index = pd.date_range(start='2023-01-01', periods=10, freq= str(us_freq) + 'us')

print(Hz_index)
#DatetimeIndex([       '2023-01-01 00:00:00', '2023-01-01 00:00:00.020000',
#               '2023-01-01 00:00:00.040000', '2023-01-01 00:00:00.060000',
#               '2023-01-01 00:00:00.080000', '2023-01-01 00:00:00.100000',
#               '2023-01-01 00:00:00.120000', '2023-01-01 00:00:00.140000',
#               '2023-01-01 00:00:00.160000', '2023-01-01 00:00:00.180000'],
#              dtype='datetime64[ns]', freq='20000U')
```
- 以下に上記コードの解説をします。
    - まず、`us_freq`という変数に、指定の周波数（Hz）に対応したマイクロ秒数を算出し、代入します。
    - 周波数（Hz）は1秒あたりの繰り返し回数なので、1を周波数で割り1振動にかかる秒数を算出します。
    - 算出した値は秒（s）なので、マイクロ秒に変換するために、1000000を乗じ、マイクロ秒に変換します。
    - なお、ここでは50Hzなので、$1/50 = 0.02s$となり$0.02s × 1000000 = 20000us$という値になります。

    $f = \frac{1}{T}$

    $f：周波数$
    $T：周期$

    - 上記で算出した値を`pd.date_range`の第3引数の`freq`に`str`型として単位の`us`と結合し渡します。
    - これにより、指定時間から`periods`で指定した個数の時系列の`index`が作成されます。
    

- 上記で作成した、周波数（Hz）の`index`を使用し`df`を作成します。

```python:上記で作成した、周波数（Hz）のindexを使用しdfを作成する。
#上記で作成した、周波数（Hz）のindexを使用しdfを作成する。
df = pd.DataFrame(np.arange(10).reshape(10, 1), columns = ['data'], index = Hz_index)

print(df)
#                       data
#2023-01-01 00:00:00.000     0
#2023-01-01 00:00:00.020     1
#2023-01-01 00:00:00.040     2
#2023-01-01 00:00:00.060     3
#2023-01-01 00:00:00.080     4
#2023-01-01 00:00:00.100     5
#2023-01-01 00:00:00.120     6
#2023-01-01 00:00:00.140     7
#2023-01-01 00:00:00.160     8
#2023-01-01 00:00:00.180     9
```

## 参考資料
https://pandas.pydata.org/docs/reference/api/pandas.date_range.html

https://ja.wikipedia.org/wiki/%E5%91%A8%E6%B3%A2%E6%95%B0

https://qiita.com/takuma-1234/items/2bb734ec4d562149b4b9

## 個人ブログ

https://takuma-tech.com/2023/01/19/380/
NixOS(Parallels未対応のlinux distro)にparallels-toolsを入れる

nixos userならmitchellh氏のパッケージを利用するだけでok

https://github.com/mitchellh/nixos-config/blob/main/pkgs/parallels-tools/default.nix

他のdistroも↑を見ながらやればできそう(知らんけど)
AtCoder Beginner Contest 284 A〜C問題をPythonで解いてみました

ABC284(AtCoder Beginners Contest 284)
A〜C問題をPythonで解いてみました。

- コードは雑めです。ゆるしてー
- 競技プログラミングの勉強一切したこと無いので、テクニックは知らないよ。ごめんねー

## [A問題](https://atcoder.jp/contests/abc284/tasks/abc284_a)(diff=10)
[提出コード](https://atcoder.jp/contests/abc284/submissions/37874969)
```python
n = int(input())
s = []
for i in range(n):
  s.append(input())
 
for i in range(n-1,-1,-1):
  print(s[i])
```
- n個分文字列を受け取って、逆順でprintするだけの問題です
- range()を工夫すれば簡単に解ける問題ですね


## [B問題](https://atcoder.jp/contests/abc284/tasks/abc284_b)(diff=14)
[提出コード](https://atcoder.jp/contests/abc284/submissions/37875108)
```python
t = int(input())
for ti in range(t):
  tn = int(input())
  tests = list(map(int,input().split()))
  odd_count = 0
  for tnum in tests:
    if (tnum%2)==1:
      odd_count += 1
  print(odd_count)
```
- t個分テスト文字列を受け取って、奇数をカウントしてprintするだけの問題です
- ２重ループ使ってます


## [C問題](https://atcoder.jp/contests/abc284/tasks/abc284_c)(diff=193)
[提出コード](https://atcoder.jp/contests/abc284/submissions/37877141)
```python
n, m = map(int,input().split())

graph_vertices = [False]*n
graph_edges = [[False]*n for i in range(n)]

for i in range(m):
    e1, e2 = map(int,input().split())
    e1 -= 1
    e2 -= 1
    graph_edges[e1][e2] = True
    graph_edges[e2][e1] = True

def depthFirstSearch(i):
    graph_vertices[i] = True
    for i2 in range(n):
        if graph_edges[i][i2] and not graph_vertices[i2]:
            depthFirstSearch(i2)

count = 0
for i in range(n):
    if graph_vertices[i] == False:
        depthFirstSearch(i)
        count += 1

print(count)

```
- [深さ優先探索](https://ja.wikipedia.org/wiki/%E6%B7%B1%E3%81%95%E5%84%AA%E5%85%88%E6%8E%A2%E7%B4%A2)です。
- 学生の頃に作ったすごろくゲームで実装したの懐かしい。StackOverflowしたのは良い思い出です。
- (追記)私のようにゴリゴリ実装しなくてもライブラリ呼び出すだけで解けるそうなので、[「python 連結成分」](https://note.nkmk.me/python-scipy-connected-components/)などで検索されると良いと思います。

# 感想
C問題ちょっと難しかったかな？
でもこの問題でdiff200行かないんですね。難しくなりましたねぇ。
文字列同士の比較できたー！（strcmp関数）

# 読んで欲しい人
・1時間前の私。
・文字列同士の比較をしたい人。
・プログラミングを教えている人、詳しい人。(間違えてたら教えてください)
・Atcoderのabc166のaの問題を解いた人。
# 注意
・Atcoderのabc166のaの問題をこれから解く人。
# strcmp関数とは
文字列を文字列で比較する関数。[strcmp関数の参考にした記事](https://www.geekpage.jp/programming/c/strcmp-1.php)
# ACしたコード
```c
#include <stdio.h>
#include <string.h>				//strcmp関数を使うときに必要なやつ

int main()
{
	char	s[4];

	scanf("%s",s);
	// printf("s=%s\n",s);

	char str[4] = "ABC";		//ここを定義していなかった
	// printf("str=%s\n",str);	
	char str1[4] = "ARC";
	// printf("str1=%s\n",str1);

	if (strcmp(s, str) == 0){
		//printf("sとstrが一緒だったら%s\n",str1);
		printf("%s\n",str1);
	} else {
		printf("%s\n",str);
	}
	return (0);
```
# 実行結果
```c
ARC
```
# 間違えたコード
```c
#include <stdio.h>
#include <string.h>

int main()
{
	char	s[4];

	scanf("%s",s);
	// printf("s=%s\n",s);

	char str[4] = "ARC";
	printf("str=%s\n",str);

	if (strcmp(s, str) == 0){
		// printf("sとstrが一緒だったら%s\n",str1);
		printf("%s\n",str);
	} else {
			printf("%s\n",str);
	}
	return (0);
}

```
# 実行結果
```c
ARC
```
そうです。同じ結果でした。
実行結果が同じだから間違えている箇所を見つけられなくて詰みました。
# 学んだこと
例えば
与えられる文字列sが"ARC"、定義した文字列strが"ARC"だけの場合、間違えたコードだと
与えられる文字列sが"ABC"の時にしか対応しないことに気づいたので
今回の文字列の比較の問題は文字列 "ABC" と "ARC" を宣言する必要があることを学びました。
# まとめ
・文字列同士の比較は比較したい文字列を全部定義する。
# 追記（先輩方に教えてもらったこと）
1、strcmp関数は比較したい文字列をダブルクォーテーションで囲めば比較できる。
```c
if (strcmp(s, "ARC") == 0){
printf("ABC\n");
} else {
printf("ARC\n");
}
```
[Man page of STRCMP](https://linuxjm.osdn.jp/html/LDP_man-pages/man3/strcmp.3.html)見てみたけどちょっとわからなかった。

2、Atcoderでいろんな解答をストックしてみる。
[与えられる文字列と判定する文字列を変数にする場合](https://atcoder.jp/contests/abc166/submissions/35076814)(私と似てるコード)
[添字で判定①](https://atcoder.jp/contests/abc166/submissions/33885152)
文字列 ABC と ARC の B か R で判定して Bの場合はR、Rの場合はB を代入する方法。
[添字で判定②](https://atcoder.jp/contests/abc166/submissions/36597192)
文字列 ABC と ARC の B か R で判定して出力する方法。
# 教えて頂いた方に感謝
[FLASH1N](https://twitter.com/FLASH1N)さん
[nekoti10chome](https://twitter.com/nekoti10chome)さん
@fujitanozomuさん

コードの訂正や、コードのいろんな書き方を教えてくださりありがとうございます！
また、よろしくお願いします！
# 過去の自分に助けてもらった回数
1回目:2023/01/17　
Atcoderの[B - Judge Status Summary](https://atcoder.jp/contests/abc173/tasks/abc173_b)
Ubuntu20.04の端末でコピペ

# 端末でコピペ
CTRL+CとCTRL+Vではコピペできない。
範囲指定して右クリックでやっていたけど不便なのでググったところ
コピー 　　　　　　　`Shift` + `Ctrl` + `C`
貼り付け（ペースト） `Shift` + `Ctrl` + `V`
とのことでした。

※　端末 → 設定 → ショートカットで変更可
[UE5][UE4] UE5.1でandroid向けにビルドするためNDKを更新するとUE4.27でビルドが通らない

# はじめに
これまでUE4.27とUE5.03でandroid向けにビルドするため(自分はMetaQuestで実行するためにビルドしています)にNDKのバージョン21.1.6352462を使用していたのですが、UE5.1ではこのままではエラーが発生するようになっていました。
UE5.1でビルドを通すためにNDKのバージョン25.1.8937393をインストールして、UEのプロジェクトのAndroid SDKの設定を変更したところ、UE5.1でビルドは成功するようになりました。
しかし、UEのプロジェクトのAndroid SDKの設定変更は全プロジェクトに影響してしまうため、既存のUE4.27のプロジェクトがビルドが通らなくなる問題が発生しました。
そこで、今度はUE4.27で通すためには再度Android SDKの設定変更が必要でした。
(現状はUE4.27とUE5.1で切り替えてビルドする毎に設定変更が必要です・・・）

(2023/1/31追記)
記事を書いた後、別のUE4.27のプロジェクトでビルド失敗することがありましたので、本記事の方法で確実にビルドが通るわけではないようです。UE4.27の環境が必要な場合は、UE5.1は入れないほうが良いのかもしれません・・・

# 環境
Windows11
UnrealEngine 4.27及び5.1
NDK 21.1.6352462及び25.1.8937393

# UE5.1のプロジェクトでのAndroid SDKの設定
UE5.1でビルドを通したとき、以下の画面の設定でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/365ad199-42c3-9434-852d-cbfdd06c6e1c.png)

# UE4.27のプロジェクトでのAndroid SDKの設定
再度UE4.27でビルドが通るようにしたとき、以下の画面の設定でした。
NDKのパスとSDK APIレベル、NDK APIレベルの変更が必要でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/78d4b720-d80e-2fab-edf5-129707f902a3.png)

# 参考資料
・[Error: UAT: ld.lld: error: undefined symbol: __aarch64_swp8_acq_rel UE5.1](https://forums.unrealengine.com/t/error-uat-ld-lld-error-undefined-symbol-aarch64-swp8-acq-rel-ue5-1/693154)
UE5.1でNDKの変更が必要なことをこちらで知りました。
Pythonでの音声信号処理 (2) 読み込んだ情報を可視化する

## やりたいこと
ファイルから読み込んだ音声データを見える化すること。

## やってみる
ファイルから読み込んで、表示してみる。

```p2.py
from pydub import AudioSegment
import numpy as np
import matplotlib.pyplot as plt


def main():
    dt_raw = AudioSegment.from_mp3("data.mp3")
    dt_arr = np.array(dt_raw.get_array_of_samples())

    ch1_y = dt_arr[::2]
    ch1_x = np.arange(len(ch1_y))

    plt.plot(ch1_x, ch1_y)
    plt.show()


if __name__ == '__main__':

    main()
```

実行結果
![P02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850619/471a64bd-5dc6-74f3-771a-803ff20fc97f.png)

詰まっていて詳細が見づらいので、次回以降、修正（予定）。
[Flutter][iOS] nfc-manager を使ってNFC タグを読み込む

Flutterで作成した　iOS アプリから NFCタグを読み込むのに、 [nfc-manager](https://pub.dev/packages/nfc_manager) パッケージを利用してみました。

読み込むタグの種類としては両方のOSで読み込むことができる　NDEF(NFC Data Exchange Format)を対象としました。

nfc-manager の説明によると、
- Near Field Communication Tag Reader Session Formats Entitlements を追加
- NFCReaderUsageDescription を Info.plist　に追加
- com.apple.developer.nfc.readersession.felica.systemcodes と com.apple.developer.nfc.readersession.iso7816.select-identifiers を Info.plist に追加（必要なら）

と書いてあります。
今回は NDEF のみが対象なので、３つ目は不要かと思っていましたが、これが無いと　NFCタグ読み込みのポップアップが表示されません。

# 実装のポイント
## Entitlements
com.apple.developer.nfc.readersession.formats を .entitlements ファイルに追加するのですが、xcode UI からは複数の選択肢があります。
今回は　NDEFが対象なので、"NDEF" を値として設定すれば良いかと思ったら、読み込みポップアップが表示せず・・・ "TAG" を値として設定しなければならないようです。
以下の　Apple のサイトを見ると、有効な値は "TAG" しか書かれてません。。。
https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_nfc_readersession_formats

ということで　com.apple.developer.nfc.readersession.formats　には　”TAG” を指定しましょう！

## com.apple.developer.nfc.readersession.* の　Info.plist への追加
色々と検索すると、felica.systemcodes　と　iso7816.select-identifiers　を追加しないといけないと書かれています。それぞれのキーには多くの値が書かれていて、意味もよくわからないので、本当に必要か疑問でした。
様々なフォーマット（タグ？カード？）に対応するのであれば、その対応する値を書かないといけないようなのですが、今回対応したいのは　NDEF　のみです。
調べた結果、　felica.systemcodes　キーのみ、かつ値も１つあれば読み取ることができるとわかりました。（対象のNFCタグによっては不足する可能性は高いですが・・・）
```Info.plist
    <key>com.apple.developer.nfc.readersession.felica.systemcodes</key>
    <array>
      <string>12fc</string>
    </array>
```
ちなみに、値の　"12fc" は、[ソニーのドキュメント](https://www.sony.co.jp/Products/felica/business/tech-support/)によると
NFC Forum が規定する NFC Data Exchange Format (NDEF)が格納されたシステム
とのこと。ただ、それ以外の値でも問題なさそうでした。
このキーがあることが必要なのかもしれません。

ということで、NDEFを読み込むだけであれば、最低条件として　com.apple.developer.nfc.readersession.felica.systemcodes　キーを追加。値は最低一つ。となりました。

# 後記
Android では割とすんなりと読み込めましたが、iOS は手こずりました。
対応するNFCの種類によって、色々と対応が異なるようで難しいですね。

# 追記（2023/1/9）
実装のポイントで書いた２点は、nfc-manager パッケージの中で NFCTagReaderSession を使っているためのようです。

com.apple.developer.nfc.readersession.formats　に "NDEF" を指定した場合は、多分　NFCNDEFReaderSession　を使うのではないかと。
piyopiyo.exの裏舞台　〜勉強会で登壇環境　リアルアバターを捨てる〜

piyopiyo.ex（Elixir初心者向け勉強会）の裏舞台を紹介したいと思います

対象：ゆるふわに登壇したい方


# インストール会の攻略方法

・必ず事前検証を行う
　　・１月前に動いたものは当日動かないことはあります
　　・事前検証はKVMを使ってスナップショットを使ってます
　　・macの場合はTime Machineを使ってOSをいつでも戻せるようにします

### KVMでUbuntuやWindowsのスナップショットを作る
　　・検証は何度か実行します
　　　　途中でなにか失敗した時は、成功時にいちから再検証します
　　　　何故かと言うと途中での作業が成功、失敗の影響を与えていることがあるからです


![Screenshot from 2023-01-08 18-08-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/f5683f45-533d-ae42-fdb4-767d09429693.png)

![Screenshot from 2023-01-08 18-09-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/42419a76-a541-1a08-794f-4b649a47d0d1.png)

こんな感じでいくつかスナップショットを作っています
例えば、インストール前、ライブラリー等をインストールした後

どうしてこんな事をしているか？
　もし、通信回線があまり調子よく無い時の為に「三分クッキング方式」でインストール後から途中で再現できます

### Macの場合は詳しくは書きません、ざっくりイメージ（私はMacは疎いので…）
　・勉強会用にUSB SSDにmacOSをインストールします
　・インストール後　`tmutil snapshot` でスナップショットを取る
　・検証後元に戻す時は 電源長押しで起動して、目的のスナップショットに戻す
　※検証で使ってるのはM1　mac mini 8GBです

　MacはVNCで接続して、画面共有して表示しました

# リアルアバターを捨ててキャラクターで登壇する
　・NeosVRを使う
　　　鏡を使います
　　　![Screenshot from 2023-01-08 18-21-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/93599ebe-6736-b58e-2473-40bbb2eccf38.png)
　　　いい感じに合わせます
　　　![Screenshot from 2023-01-08 18-21-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/40d43dc7-a0ed-726c-656f-4285ce0ed97d.png)

　・OBSの仮想カメラを使う
　　・ソースをNeosVRの画面を選択する
　　　　表示している内容を反転させておくと良い
　　・仮想カメラ開始をクリックしておく

　　![Screenshot from 2023-01-08 18-23-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/6e587145-b4ec-2f8d-9452-4aa88c45dab4.png)
　　
　・Zoomに仮想カメラを指定
　　OBS Virtual Cameraを指定します
![Screenshot from 2023-01-08 18-26-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/51976e43-6023-af7d-4828-c5431fd75817.png)

これで、リアルアバターを捨てることができました

## それなりのマイクとオーディオインターフェースを買ってくる
![P_20230103_235647.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/67416ef7-7591-36e8-6663-c806182d0217.jpeg)

私はの環境は
　・オーディオインターフェース　YAMAHA AG06
　・マイク マランツ 888M

オーディオインターフェースはミュートが手元で使えると便利

## Zoomあるあるトラブル
Input Volumeが勝手に変えられてる時がある
![Screenshot from 2023-01-08 18-52-44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/8c148970-f411-ac5d-2e57-cf68fdd0a6a2.png)

たぶん、Automatically adjust mixrophone volumeにチェックが入っていると悪さするかも…

Ubuntu側のボリューム設定も勝手に変えられている時もありました…　ここも要注意
![Screenshot from 2023-01-08 18-55-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/271c45df-abd2-9e51-7e79-3945ca927755.png)


## どのくらいのマシンスペックいる？
・メモリ 64GB以上（私は最終的に128GB積みました）
　Zoom + NeosVR + KVMで一つOSを立ち上げると32GBとだとカツカツですので64GB以上はあったほうがいいかも
・CPUはRyzen7 5800Xでも耐えてます
・GPUはアバター表示するなら積んでいた方がよいです、私はRTX 3060を使ってます


## 周りの人に協力してもらう
・環境トラブルもあるかもしれないので念の為に誰かにバックアップ環境をお願いしておくとよい
・周りとゆるふわに練習をしておく
　当日マジに例外で焦るので…
Office 365 ユーザーコネクターを利用する際におけるパフォーマンス観点での注意点と対策について


# はじめに

前回、Office 365 ユーザーコネクターの活用方法について紹介しました。
今回は、Office 365 ユーザーコネクターを利用する際におけるパフォーマンス観点での注意点とその対策について紹介します。

https://qiita.com/Takashi_Masumori/items/92f4772a73d7f05e6690

# アプリ例

今回は、以下のように、勤務状況を共有するアプリを例に説明します。
こちらのアプリでは、組織内の複数のユーザーの情報を表示しているため、
アプリの作り次第では、表示させたいユーザー数分、Office365ユーザーコネクターで情報取得を行う必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/3184c1c9-4e31-e091-4f96-7861abb05aee.png)

# パフォーマンス観点での注意点

実際にはこのような実装ではありませんが、各ユーザーの表示名を以下のような感じで取ってくるようにしたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/f260620e-4ac4-fa18-0343-d5694a1076d3.png)

```
Office365ユーザー.UserProfileV2(ThisItem.cr841_userupn).displayName
```

通信の中身を以下のモニターを使って見てみたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/7d4056a8-68f7-58a7-f4cb-153644bbe44a.png)

まず、上記ページをロードした際の通信です。
ユーザーごとに情報を取得していることがわかります。応答のサイズや期間 (ミリ秒) が結構大きいことがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/4b8d063a-e24f-8632-d45b-1cb1516aab51.png)

応答の詳細を見てみると、すべてのプロパティを取得していることが分かります。
今回、欲しいのは、"displayName" だけなのでちょっと余分な通信ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/a91134de-801b-4bed-968d-7a453e3171fa.png)


# 対処策

確実に "displayName" だけ取得する場合、以下のような書き方になります。

```
Office365ユーザー.UserProfileV2(
    ThisItem.cr841_userupn,
    {'$select': "Displayname"}
).displayName
```

再度モニターツールでみてみます。
応答のサイズや期間(ミリ秒)が小さくなったことが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/a0bb9218-1a4e-2585-d7f9-949a0eb81b57.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/04fdface-741b-459b-7922-9939c52a1eb1.png)

また、複数の属性を取得する場合は、以下のような書き方になります。

```
Office365ユーザー.UserProfileV2(
    ThisItem.cr841_userupn,
    {'$select': "Displayname,Mail"}
).displayName
```

# まとめ

今回は、Office 365 ユーザーコネクターを利用する際のパフォーマンス観点での注意点およびその対策として特定の属性のみ取得する方法を紹介しました。

個人的に、Office 365 ユーザーコネクターを利用する際は (特に、モバイル向けアプリや、ギャラリー内で利用する際)、出来るだけ最低限必要な情報を取得して通信量を軽くしてあげることをお勧めします。

また、上記のようなアプリの場合、Office 365 ユーザーコネクターで毎回情報を取得せず、アプリ内の DB に情報を保存しておいてそちらから情報を取得する、または、一旦コレクションに格納し、リフレッシュしない限りはそちらを参照するような方法を検討しても良いかと思います。
Pythonでの音声信号処理 (1) ファイルの読み込み

## やりたいこと
音声ファイルを読み込むこと

## やってみる
音声ファイル（ここではmp3）を読み込んでみる。
```p1_1.py
from pydub import AudioSegment

sd = AudioSegment.from_mp3("data.mp3")
print(sd.duration_seconds)
print(sd.frame_rate)
print(sd.channels)
```

音声信号部分を取り出してみる。
```p1_2.py
from pydub import AudioSegment
import numpy as np

sd = AudioSegment.from_mp3("data.mp3")
sr = np.array(sd.get_array_of_samples())

ch1 = sr[::2]
ch2 = sr[1::2]

for i in map(hex, ch1):
    print(i, end=", ")
```
【JavaScript】論理演算子のtruthyな値、falsyな値のまとめ

## falsyな値とは
真偽値に変換した場合にfalse(偽)とみなされる値のこと

## truthyな値とは
falsy以外の値のこと（trueになる値）

## falsyになる値
```
false
null
0(数字)
""（空文字）
undefined
Nan
0n (big int)
```

 ## 論理積 (&&)
論理積は左側からfalsyな値を探して、見つかったら変数等に格納します
falsyな値がなければ一番右側の値が格納されます

```Javascript
例
//result1には""が格納される
const result1 = "" && "aaa";

//result2には0が格納される
const result2 = 5 && 1 && 0 && 10;

//result3には2が格納される
const result3 = "bbb" && 2; 

```
 ## 論理和 (||)
論理和はtruthyな値を見つけたら変数等に格納します
truthyな値が複数ある場合は左側の値を変数等に格納します
```Javascript
例
//result4には"aaa"が格納される
const result4 = "" || "aaa";

//result5には5が格納される
const result5 = null || 5 || undefined;

//result6には4が格納される
const result6 =  4 || 6; 
```
RHEL7とRHEL8でのローカルリポジトリの違い

# 概要
ローカルリポジトリを使用する際に作成するrepoの記載方法がRHEL7とRHEL8とで異なっているため、それぞれの違いを記載する。
(CentOSやOracle Linuxにおいても同様の差異があります。)

# OS
Red Hat Enterprise Linux 7.6
Red Hat Enterprise Linux 8.6

# 設定内容
### RHEL7の設定内容
■ローカルリポジトリ(/etc/yum.repos.d/local.repo)
[local]
name=localrepo
enabled=1
gpgcheck=0
baseurl=file:///mnt

■isoメディア
ls -l
合計 974
dr-xr-xr-x 3 root root   2048  9月 18  2020 EFI
-r--r--r-- 1 root root   8266  9月 18  2020 EULA
-r--r--r-- 1 root root  18092  9月 18  2020 GPL
dr-xr-xr-x 2 root root   2048  9月 18  2020 LiveOS
dr-xr-xr-x 2 root root 946176  9月 18  2020 Packages
-r--r--r-- 1 root root   3375  7月 14  2020 RPM-GPG-KEY-redhat-beta
-r--r--r-- 1 root root   3211  7月 14  2020 RPM-GPG-KEY-redhat-release
-r--r--r-- 1 root root   1796  9月 18  2020 TRANS.TBL
dr-xr-xr-x 4 root root   2048  9月 18  2020 addons
-r--r--r-- 1 root root   1455  9月 18  2020 extra_files.json
dr-xr-xr-x 3 root root   2048  9月 18  2020 images
dr-xr-xr-x 2 root root   2048  9月 18  2020 isolinux
-r--r--r-- 1 root root    114  9月 18  2020 media.repo
dr-xr-xr-x 2 root root   2048  9月 18  2020 repodata

### RHEL8の設定内容
■ローカルリポジトリ(/etc/yum.repos.d/local.repo)
[InstallMedia-BaseOS]
name=Red Hat Enterprise Linux 8 - BaseOS
metadata_expire=-1
gpgcheck=0
enabled=1
baseurl=file:///mnt/BaseOS/

[InstallMedia-AppStream]
name=Red Hat Enterprise Linux 8 - AppStream
metadata_expire=-1
gpgcheck=0
enabled=1
baseurl=file:///mnt/AppStream/

■isoメディア
ls -l
合計 48
dr-xr-xr-x. 4 root root  2048  4月 21 01:40 AppStream
dr-xr-xr-x. 4 root root  2048  4月 21 01:40 BaseOS
dr-xr-xr-x. 3 root root  2048  4月 21 01:40 EFI
-r--r--r--. 1 root root  8154  4月 21 01:39 EULA
-r--r--r--. 1 root root 18092  4月 21 01:39 GPL
-r--r--r--. 1 root root  1669  4月 21 01:39 RPM-GPG-KEY-redhat-beta
-r--r--r--. 1 root root  5135  4月 21 01:38 RPM-GPG-KEY-redhat-release
-r--r--r--. 1 root root  1796  4月 21 01:40 TRANS.TBL
-r--r--r--. 1 root root  1455  4月 21 01:39 extra_files.json
dr-xr-xr-x. 3 root root  2048  4月 21 01:40 images
dr-xr-xr-x. 2 root root  2048  4月 21 01:40 isolinux
-r--r--r--. 1 root root   103  4月 21 01:38 media.repo

pwd
/mnt/AppStream
ls -l
合計 1234
dr-xr-xr-x. 2 root root 1259520  4月 21 01:40 Packages
dr-xr-xr-x. 2 root root    4096  4月 21 01:40 repodata

pwd
/mnt/BaseOS
ls -l
合計 304
dr-xr-xr-x. 2 root root 309248  4月 21 01:40 Packages
dr-xr-xr-x. 2 root root   2048  4月 21 01:40 repodata

### 差異
![localrepository.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510919/44d71ca2-db80-21b7-a39f-01f1f1674028.png)

baseurlが異なっており、RHEL7用ローカルリポジトリでyumを実行しようとすると失敗します。

以上、知っておくと少しだけ役に立つ知識でした。
VirtualBox＋Ubuntu20.04＋Docker＋nginx

Dockerでホストとコンテナでフォルダ共有（ボリューム設定）を試してみようと思ってWebサーバーを起動してみたら、そもそもVirtualBoxのホストOSから見れるような設定をしていなかった。

# 環境
VirtualBox6.1
ホストOS: Windows10 Home 20H2
ゲストOS: Ubuntu20.04 ＋ Docker20.10.22 ＋ nginx1.23.3

# Dockerでnginxコンテナを起動
`docker run --name mynginx -p 8080:80 nginx`

```
nacanaca@dmin-VirtualBox:~/dockertest/DockerFileBase$ docker run --name mynginx -p 8080:80 nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/01/08 08:46:45 [notice] 1#1: using the "epoll" event method
2023/01/08 08:46:45 [notice] 1#1: nginx/1.23.3
2023/01/08 08:46:45 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6) 
2023/01/08 08:46:45 [notice] 1#1: OS: Linux 5.15.0-57-generic
2023/01/08 08:46:45 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2023/01/08 08:46:45 [notice] 1#1: start worker processes
2023/01/08 08:46:45 [notice] 1#1: start worker process 29
2023/01/08 08:46:45 [notice] 1#1: start worker process 30
```
start worker process 30でプロンプトが戻ってこないので失敗したのかと思ったらこの状態で大丈夫でした…。

" ブラウザで確認
`localhosut:8080`

![VirtualBox_Ubuntu20.04_Docker_nginx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611568/e4083603-1e6b-e622-f761-4a1282d7ae70.png)

# ホストOS(Windows10)から確認
と、ここで、ん？ゲストOSのIPアドレスって？
そもそも見れるように設定が必要なのでは？と気付く。

~~今後、試しながら、加筆予定。~~

VirualBox → 設定 → ネットワーク → アダプター1タブ
高度 → ポートフォワーディング

名前：HTTP(任意)
プロトコル：TCP
ホストIP：空欄
ホストポート：8080（任意：0から1023以外）
ゲストIP：空欄
ゲストポート：8080（dockerでnginx起動時に指定したポート）

Windows10のブラウザで確認
`localhosut:8080`

# 参考にしたサイト
他のPCやスマホからVirtualBox(ゲストOS)のWebサーバに接続する
https://qiita.com/OharanD/items/bcf5cff7096179641691
Atcoder Beginner Contest284 D問題解説(Pythonコード付き)

# はじめに　
　本記事はPythonでAtcoderにチャレンジしているけど、Pythonはコード例がないため解説がわかりにくい！と感じている方を対象としています。 
　私自身大してレートも高くないので、不備等あるかもしれませんがご了承くださいm(_ _)m
　質問や指摘などもコメント等に書いてくださったら対応していきたいと考えていますのでどしどしコメントしてください。(内容がわかりにくいぞ！みたいな文句でもオールオッケーです笑)
## Atcoder Beginner Contest284 D問題
　問題のURLはこちらです。[Atcoder Beginner Contest284 D問題](https://atcoder.jp/contests/abc284/tasks/abc284_d)
## 使う手法
　今問題ではnを素因数分解する必要があります。
　今回は素因数分解のメジャーな手法である**試し割り法**を使ってnを素因数分解していきます。
　わざわざ名前を冠しているので複雑な手法なのかな？と思うかもしれませんが、単純に2,3,4,5・・・・と割っていって、余りがゼロになる値を調べていく方法です。
　ただし、素因数の捜索範囲に少し留意しなければなりません
　先ほど述べたように、単純に2,3,4,5・・・nと探していくと考えて実装すると、nの値が大きい場合にTLEしてしまいます。
　従って、一般的な試し割り法における素因数の捜索範囲は$\sqrt{n} $までとなっています。　
　AtcoderのD問題くらいので出てくるような値は大体この範囲で対応できる気がします。（今回は少し工夫しないといけませんが・・・・）
## 考え方　
　先程$\sqrt{n}$で対応できると言いましたが、今問題におけるNの範囲は$1\leqq N \leqq 9×10^{18}$となっているため、捜索範囲を$\sqrt{n}$として試し割り法を実装してもTLEになります。
　そこで、本問題のもう一つの制約である$N=p^2q$という制約を生かして、試し割り法に**一つ素因数を見つけた段階で処理を終了する**という処理を加えます。
　問題の制約からNは2種類の素因数しか持たないため、1種類でも素因数を見つけることができれば、もう1種類は簡単に計算できます。
## 実装例　
```python
import math
from decimal import Decimal
#素因数分解する関数 
def p_func_re(n):
  """
  素因数を格納するリスト「arr」と、nをDecimal型に直した「temp」を作成する。
　(nをint型のまま扱うと、大きな値の際に有効数字の関係で誤差が生まれるため。)
  """
  arr = []
  temp = Decimal(n)
  #試し割り法を行う
  for i in range(2,int(math.sqrt(n))+1):
    if temp%i==0:
      #見つけた素因数がpなのかqなのか判定する。
      if temp%i**2 == 0 :
        l = Decimal(i)
        arr.append(l)
        arr.append(temp/l**2)
        break
      else :
        l = Decimal(i)
        arr.append(Decimal(math.sqrt(temp/l)))
        arr.append(l)
        break
  return arr
t = int(input())
 
for _ in range(t):
  n = int(input())
  arr = p_func_re(n)
  p = arr[0]
  q = arr[1]
  print(str(p) + " " + str(q))
```
## 計算量に関する記載
　公式解説では試し割り法の捜索範囲を$\sqrt[3]{N}$とすることで計算量の削減を図っていましたが、今回実装した方法でも実行することができました。(最大の実行時間は結構ギリギリでしたが笑)
　理由としては、pかqのどっちかが大きければ大きいほど、もう片方は桁数が小さくなるので早くループを抜けることができるからだと考えられます。
以下にNが最大桁数である18桁だった際の$p$ $p^2$　$q$の取りうる桁数を示します。
(ざっくりと考えたので間違ってたらすみません汗)
| $p$ | $p^2$ | $q$ |
|:-:|:-:|:-:|
| 1桁  | 1~2桁  | 17~16桁  |
| 2桁  | 3~4桁  | 15~14桁  |
| 3桁  | 5~6桁  | 13~12桁  |
| 4桁  | 7~8桁  | 11~10桁  |
| 5桁  | 9~10桁  | 9~8桁  |
| 6桁  | 11~12桁 | 7~6桁  |

　この表通りに考えると、pまたはqの桁数が6桁程度の際に最大時間となりそうです。
## 最後に　
　今回の記事で、数式周りで変な改行が入っており、少し見にくくなっていてすみませんm(_ _)m
　数式埋め込みを初めて使ったこともあり、現在修正方法を探しています。　
　もしご存知の方がいらっしゃいましたら、コメントで教えていただけるとありがたいです。
Pythonでdatetime.datetime.now()を使った日付計算をする際の注意

# 概要

datetime.datetime.now()を使って**日付**を計算しようとしたときに意図しない結果になる場合がある。

# datetime.datetime(YYYY, mm, dd)とdatetime.datetime.now()を使って日数の差分を取得したい場合

## 事例

datetime.datetimeオブジェクトは時刻を省略して日付のみで作成することも出来る。
この場合、**時間**と**分**は0となる。

```Python:datetime.datetime
>>> datetime.datetime(2023, 1, 8)
datetime.datetime(2023, 1, 8, 0, 0) # 時刻には0が入る
```

datetime.datetime.now()を実行すると、現在の日付と時刻が取得される。

```Python:datetime.datetime.now()
>>> datetime.datetime.now()
datetime.datetime(2023, 1, 8, 17, 20, 37, 109800)
```

この状態で日付同士の差分を求めようとすると、各項の順番によって値が変わる。

```Python:日付差分（2023年1月8日に実施）
>>> datetime.datetime(2023, 1, 8) - datetime.datetime.now()
datetime.timedelta(days=-1, seconds=23888, microseconds=735007)  # 期待した値はdays=0

>>> datetime.datetime(2023, 1, 9) - datetime.datetime.now()
datetime.timedelta(seconds=23623, microseconds=392751)  # 期待した値はdays=1

>>> datetime.datetime.now() - datetime.datetime(2023, 1, 8) 
datetime.timedelta(seconds=62520, microseconds=388495)  # 期待した値はdays=0

>>> datetime.datetime.now() - datetime.datetime(2023, 1, 9) 
datetime.timedelta(days=-1, seconds=62759, microseconds=391388)  # 期待した値はdays=-1
```

datetime.datetime.now()関数は現在時刻を持っているため、datetime.datetime(YYYY, mm, dd)で宣言した値と時刻分の差が出来てしまう。

## 解決策

datetime.datetime.now()からdateime.datetime(YYYY, mm, dd)を引く。
DockerとDocker composeのバージョン確認方法について

# Dockerまわりのバージョン確認方法について

## Docker
* `docker -v`:dockerのバージョンのみ表示
* `docker version`:dockerのクライアントやサーバーの情報など詳細表示

## Docker compose
* `docker compose -v`:docker composeのバージョン表示
* `docker compose version`:docker composeのバージョン表示（上記同様）
FreeCADによる三点曲げと四点曲げの梁（はり）の曲げ応力の計算

# はじめに
遅ればせながら、最近CAEの勉強を始めました。趣味でやっているため、CADには無償の[FreeCAD](https://www.freecadweb.org/index.php?lang=ja)を使っています。このFreeCADはCAEもできる優れものです。
今回は勉強がてら、矩形断面の三点曲げと四点曲げの梁について、FreeCADを使って曲げ応力とたわみを計算しました。

# 梁の寸法と荷重位置
図1と図2に示します。材料は鋼（ヤング率210GPa、ポアソン比0.30）とします。

<img width="600"  alt="3点曲げ.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/9bba56db-ea4a-929c-33fd-ecd323921daf.jpeg">

図1　三点曲げ梁の寸法と荷重位置

<img width="600" alt="4点曲げ.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/2a8f3ef5-d907-3e01-eb4a-b4d7c8b1fc12.jpeg">

図2　四点曲げ梁の寸法と荷重位置

# FreeCADで作成した1/4モデル
計算は、幅と長さをそれぞれ半分とした1/4モデル（幅20mm、厚さ20mm、長さ500mm）により行いました。図3と図4に作成したモデルと境界条件を示します。図において、長さ方向はX方向、幅方向はY方向、厚さ方向はZ方向になります。
図4においては、モデルの上面を面分割して、分割位置で荷重を加えられるようにしています。面分割は[FreeCAD 平面を複数の面に分割する](https://www.xsim.info/articles/FreeCAD/HowTo/Divide-a-face-into-multiple-faces.html#:~:text=%E3%83%A2%E3%83%87%E3%83%AB%E3%83%84%E3%83%AA%E3%83%BC%E4%B8%8A%E3%81%A7%E3%80%8C%E5%88%86%E5%89%B2,%E9%9D%A2%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%EF%BC%89%E3%80%82&text=%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E3%81%A8%E5%B9%B3%E9%9D%A2%E4%B8%8A,%E9%A0%98%E5%9F%9F%E3%81%8C%E4%BD%9C%E6%88%90%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82)を参考にして行いました。
1/4モデルのため境界条件には少し工夫が必要です。分割面に垂直方向の変位は0とし、支点での反力と釣り合う荷重を加えます。
三点曲げ、四点曲げとも、メッシュは最大サイズ5mm、細かさ中程度の条件で分割しました。

<img width="600" alt="スライド3.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/711085ae-fe0e-0f62-7a0b-c204842a6f78.jpeg">

図3　三点曲げ梁の1/4モデルと境界条件


<img width="600" alt="スライド4.JPG" src ="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/e49cdb3a-19e8-2636-231b-df5cd3c08a77.jpeg">

図4　四点曲げ梁の1/4モデルと境界条件

# 計算結果
三点曲げと四点曲げのX方向の垂直応力（sx）の計算結果をそれぞれ図5と図6に示しました。
三点曲げは、Z変位の最小値が-1.86 mm（下方向に最大値）、X軸方向の応力の最大値が46.74MPaとなりました。材料力学による理論値は変位が1.86mm、応力値が46.87MPaですので、理論値とほぼ一致した結果が得られました。ただし、X軸方向の応力の最小値は-49.84MPaとなっており、理論値-46.87MPaに比べて絶対値でやや大きい値となっています。
四点曲げは、Z変位の最小値が-2.56 mm（下方向に最大値）、X軸方向の応力の最大値が47.02MPaとなりました。材料力学による理論値は変位が2.56mm、応力が46.87MPaですので、こちらも理論値とほぼ一致した結果が得られています。ただし、X軸方向の応力の最小値は-50.04MPaとなっており、こちらも理論値-46.87MPaに比べて絶対値でやや大きい値となっています。
なお、図5と図6において、X軸方向の応力値の最小値が理論値に比べて絶対値でやや大きくなっている理由は、[PrePoMaxによる三点曲げと四点曲げの梁（はり）の曲げ応力の計算](https://qiita.com/_Moony/items/e9ccaa349077006bdd40)で書いたように、これらの応力値は荷重点で生じているため、応力集中によるものと考えられます。

<img width="600" alt="スライド20.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/7a6cc5a3-76f6-b8cd-3c43-6af7767d12c5.jpeg">

図5　三点曲げ梁の1/4モデルのX軸方向の垂直応力の計算結果

<img width="600" alt="21.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/18dc0854-024e-db76-e390-f8b8d00164b1.jpeg">

図6　四点曲げ梁の1/4モデルのX軸方向の垂直応力の計算結果

# 終わりに
四点曲げの荷重位置の設定に多少難儀しましたが、X軸方向の最大応力値については、理論値とほぼ一致する結果が得られました。
ppt で使える Azure アイコンの一覧とダウンロード

# はじめに
Azure のシステム構成図などを作成する際、最新の Azure Icon が欲しくなります。Powerpoint や、Excel で利用可能な SVG 形式で、最新の Azure Icon を一覧表示し、ダウンロードする方法をご紹介します。

# 目次
- [はじめに](#はじめに)
- [目次](#目次)
- [Amazing Icon Downloader](#amazing-icon-downloader)
- [Azure アーキテクチャ アイコン](#azure-アーキテクチャ-アイコン)
- [参考文献](#参考文献)

# Amazing Icon Downloader
Google Chrome の拡張機能で、[Amazing Icon Downloader](https://chrome.google.com/webstore/detail/amazing-icon-downloader/kllljifcjfleikiipbkdcgllbllahaob) というものがあります。
これをインストールして、Azure Portal を表示した状態で使います。(Azure Portal 以外は利用できません。)
表示している Azure Portal のソース コードを辿って SVG アイコンを引っ張っているようです。
必要なアイコンだけダウンロードすることができます。

# Azure アーキテクチャ アイコン
Microsoft Learn にて、[Azure アーキテクチャ アイコン](https://learn.microsoft.com/ja-jp/azure/architecture/icons/) の利用方法とダウンロード リンクが紹介されています。こちらでは、zip ファイルにまとめてダウンロードすることができます。
<br>以下、推奨事項に従って利用しましょう。

> 推奨
> - アイコンを使用して製品がどのように連動するかを示す。
> - ダイアグラムでは、アイコンの近くに製品名を含めることが推奨される。
> - アイコンは Azure 内に表示されるそのままの形で使用する。
> 
> 非推奨
> - アイコンをトリミング、反転、回転しない。
> - どのような形でもアイコン図形を変形、変更しない。
> - 自社の製品またはサービスを表すために Microsoft 製品アイコンを使用しない。


# 参考
- [Amazing Icon Downloader](https://chrome.google.com/webstore/detail/amazing-icon-downloader/kllljifcjfleikiipbkdcgllbllahaob)
- [Microsoft Azure アーキテクチャ アイコン](https://learn.microsoft.com/ja-jp/azure/architecture/icons/)
Eclipseでサーブレットのプロジェクトをインポートするとエラーだらけになる

久しぶりに書きたくなったので約半年ぶり記事書きます！

最近Eclipseでサーブレットを使っているんですが、ローカルでプロジェクト保存してインポートしたり、Githubのリポジトリからインポートしたりした際に大量のエラーが吐かれて「なんじゃこりゃ！」ってなりました…。

調べてもなかなかこのような解決策が出てこなかったので、同じような人の助けになれば幸いです！

プロジェクトは、**スッキリわかるサーブレット&JSP入門**に載っている**dokoTsubu**プロジェクトを使用しています。
[スッキリわかるサーブレット&JSP入門の商品サイト](https://sukkiri.jp/books/sukkiri_servlet2)

## 開発環境
Windows11 home
Eclipse 2022
Java17
Tomcat9

Mac版のEclipseでも同様の手順で解決できます。

## エラーの症状


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2712147/61960a19-f23e-44c6-bd52-6c5f3eeca981.png)

```
# エラー内容
HttpServletRequest を型に解決できません
HttpServlet を型に解決できません
RequestDispatcher を型に解決できません
ServletContext を型に解決できません
WebServlet を型に解決できません
インポートされた javax.servlet は見つかりません
メソッド getServletContext() は型 Main で未定義です
```

## 原因
インポートした際にJREシステム・ライブラリーがアンバインドされていることが原因見たいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2712147/29379a42-85e6-cafa-b002-a74d5d676ec7.png)


## 解決策
- Javaのビルド・パスにて
    - アンバインド済みのJREシステム・ライブラリーを除去
    - モジュールパスにJREシステム・ライブラリーの追加

## 方法
プロジェクトの上で右クリック→プロパティを開く
左の一覧から**Javaのビルドパス**を選択する

JREシステム・ライブラリー(アンバインド済み)を選択し、右側の除去を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2712147/f1cbfcd5-7549-d472-a8ff-b9cf08557624.png)


モジュールパスを選択し、右側の**ライブラリーの追加**を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2712147/ffeedb74-5442-8c5d-c420-3a286d1bed67.png)

**JREシステム・ライブラリー**を選択して次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2712147/df25065e-d568-b874-81bc-470da7a00039.png)

特に変える必要が無ければ**ワークスペースのデフォルトJRE**を選択して完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2712147/f3346733-edf3-d1c9-1df7-97d5be9b562b.png)

選択したら、完了を押して、適用するとこんな感じでエラーは無くなると思います！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2712147/3496582a-4636-3a57-3bc1-2a944d777390.png)

## 動作確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2712147/c3b18d82-56ea-bd2f-b025-6c3c50a70efc.png)


ちゃんと動きました！

是非参考になってくれたらうれしいです！
Javaのオーバーロード

## オーバーロードとは
一つのクラス内に同じ名前で引数の型や数が違うメソッドを複数定義する事を**オーバーロード**という。
同じ名前で定義するだけなのでメソッドの内容（処理）は違う内容にする事が出来る。
オーバーロードするメリットは
・同じデータを設定する為のメソッドなので同じ名前にする事でプログラム自体がわかりやすくなる。
・同じ名前を付けていいので名前をつけるのが楽になる。
・メソッド名が変わらないので呼び出す際に使いやすい。
などがある

```:例文
class Student{
  String name;
  int engScore;
  int mathScore;

  void setData(String n){
    name = n;
  }
  void setData(String n, int e, int m){
    name = n;
    engScore = e;
    mathScore = m;
  }
}
```
上記のStudentクラスではsetDataメソッドを二つ定義（オーバーロード）している。
片方のsetDataメソッドではString型の引数一つを、もう片方ではString型の引数一つとint型の引数二つ持ったsetDataメソッドになっている。
呼び出す側でどちらのsetDataメソッドを呼び出すかは**名前と引数の型、数**の組み合わせで決めている。
```:実行用クラス
 public static void main(String[] args){
    Student stu = new Student();
    stu.setData("菅原");
    stu.setData("菅原", 75, 100);
　　　　　　　　　　　　　　　　　　　　　　　　　　　：
  }
}
```
呼び出す側で名前と引数の組み合わせが合うものがなけれがコンパイルエラーになる。
**戻り値の型は違っていても呼び出せる**

### 例文
```:実行用クラス
class StuSample2{
  public static void main(String[] args){
    Student2 stu1 = new Student2();
    Student2 stu2 = new Student2();

    stu1.setData("菅原");
    stu1.setScore(90, 80);
    stu1.display();

    stu2.setData("田仲", 75, 100);
    stu2.display();
  }
}
```
```:設計図クラス
class Student2{
  String name;
  int engScore;
  int mathScore;

  void setData(String n){
    name = n;
  }
  void setData(String n, int e, int m){
    name = n;
    engScore = e;
    mathScore = m;
  }
  void setScore(int e, int m){
    engScore = e;
    mathScore = m;
  }
  void display(){
    System.out.println(name + "さん");
    System.out.println("英語" + engScore + "点・数学" + mathScore + "点");
  }
}
```
```:出力結果
菅原さん
英語90点・数学80点
田仲さん
英語75点・数学100点
```
Student2クラス内にはString型を一つ受け取って変数に代入する６行目のsetDataメソッドとString型一つとint型二つを受け取って代入する９行目のsetDataメソッドがオーバーロードされている。

StuSample2クラスではStudent2クラスから二つのオブジェクトを生成している。
StuSample2クラス内の６〜９行目でStudent2クラス内の６行目のsetDataメソッドとsetScoreメソッドに値を格納してdisplayメソッドで出力している。
StuSample2クラス内の10~11行目でStudent2クラス内の９行目のsetDataメソッドにそれぞれ("田仲", 75, 100);という値を格納しdisplayメソッドで出力している。

## 参考記事
https://www.youtube.com/watch?v=F31uBm7T8k4&t=622s
Javaのコンストラクタ

## コンストラクタとは
オブジェクトやフィールドの初期化（変数の宣言と同時に適切な値を格納することで「最初から有効な値が入っている」状態にする）の為に使われる特殊なメソッド。
オブジェクトの生成（インスタンスの生成）とともに自動的に呼び出され、クラスのオブジェクトを生成するタイミング(new クラス名 ())で動作する。

**インスタンスの生成と同時に値が代入できるメリットがある。**
またインスタンス生成時に自動的に呼び出されるので、最初に変数を定義しておくことが出来、初期化のために別のメソッドを呼ぶ必要がなくなるので、その分コードが簡単になる。

コンストラクタもメソッドの一種なのでオーバーロード（同じ名前のメソッドを複数定義する事）が出来る。
```:コンストラクタのオーバーロード
class Student{
        :
  Student(String n){
        :
  }
  Student(String n, int e, int m){
        :
  }
}
```

**コンストラクタを定義するには**
・名前がクラス名と同じにする。（クラス名と同じなので大文字で名前がスタートする）
・戻り値を持たない（voidも書かない）。
**コンストラクタを呼び出す際には**
・オブジェクトを作る際に記述する「new クラス名　()」の（）内にコンストラクタへの引数を記述する事でコンストラクタを呼び出す事が出来る。

```:コンストラクタの定義側
publec class Student{
        :
  Student(String n){
        :
  }
  Student(String n, int e, int m){
        :
  }
}
```
```: コンストラクタの呼び出し側
public static void main(String[] args){
    Student stu1 = new Student("菅原");
    Student stu2 = new Student("田仲", 75, 100);
           :
           :
```
呼び出し側でオブジェクトstu1の引数に("菅原")を渡した場合は定義側ではStudent(String n)のコンストラクタが、オブジェクトstu2の引数に("田仲", 75, 100)を渡した場合はStudent(String n, int e, int m)のコンストラクタが呼び出されて変数に設定される。

クラス内にコンストラクタを記述しない場合はコンパイラが自動的に引数なしのコンストラクタを作成してくれる（コード自体が変わる訳ではない）。これを**デフォルトコンストラクタ**と呼ぶ。

### 例文
**コンストラクタ前**
```:実行用クラス
class StuSample3{
  public static void main(String[] args){
    Student3 stu1 = new Student3();
    Student3 stu2 = new Student3();

    stu1.setData("菅原");
    stu1.setScore(90, 80);
    stu1.display();

    stu2.setData("田仲", 75, 100);
    stu2.display();
  }
}
```
```
class Student3{
  String name;
  int engScore;
  int mathScore;

  void setData(String n){
    name = n;
  }
  void setData(String n, int e, int m){
    name = n;
    engScore = e;
    mathScore = m;
  }
  void setScore(int e, int m){
    engScore = e;
    mathScore = m;
  }
  void display(){
    System.out.println(name + "さん");
    System.out.println("英語" + engScore + "点・数学" + mathScore + "点");
  }
}
```
**コンストラクタ後**
```:実行用クラス
class StuSample3{
  public static void main(String[] args){
    Student3 stu1 = new Student3("菅原");
    Student3 stu2 = new Student3("田仲", 75, 100);

    stu1.setScore(90, 80);
    stu1.display();
    
    stu2.display();
  }
}
```
```:
class Student3{
  String name;
  int engScore;
  int mathScore;

  Student3(String n){
    name = n;
  }
  Student3(String n, int e, int m){
    name = n;
    engScore = e;
    mathScore = m;
  }
  void setScore(int e, int m){
    engScore = e;
    mathScore = m;
  }
  void display(){
    System.out.println(name + "さん");
    System.out.println("英語" + engScore + "点・数学" + mathScore + "点");
  }
}
```
```:出力結果
菅原さん
英語90点・数学80点
田仲さん
英語75点・数学100点
```
コンストラクタ前だとオブジェクトを生成してから値の代入をしているので、変数の中身が設定されていない（データが空っぽ）タイミングが発生してしまう場合がある。
データが空っぽの状態は良くないとされているのでインスタンスの生成と同時に値が代入できるコンストラクタは便利で安全なコードになり、どの値がどのメソッドやオブジェクトに入っているか見やすいコードになる。


## 参考記事
https://www.youtube.com/watch?v=WoCfOOpFc6A&t=749s
Ubuntu20.04でIPアドレスを調べる

# 「端末」を開く
以下のような方法で「端末」を開く
・「アクティビティ画面」から開く
・「アプリケーション画面」から開く
・[Ctrl]+[Alt]+[T]を押す

# IPアドレスを調べる
端末で
`ip -br -4  address`
git initのデフォルトブランチ名をmasterからmainに変更する

[GitHubではデフォルトブランチ名がmasterからmainに変更](https://github.blog/changelog/2020-10-01-the-default-branch-for-newly-created-repositories-is-now-main/)になっているし、`git init`をすると以下のように警告される。

```shell
% git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint: 	git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint: 	git branch -m <name>
Initialized empty Git repository in /Users/.../.git/
````

毎回、`git init -b main`で指定することもできるが、素直に`init.defaultBranch`を設定することにする。

```shell
% git config --global init.defaultBranch main
```

`git config -l`で確かめると

```shell
% git config -l
・・・・・
init.defaultbranch=main
・・・・・
```

となっており、試しに`git init`してみると、`hint:`は表示されなくなった。

```shell
% git init
Initialized empty Git repository in /Users/.../.git/
````
【portfolio】 化粧品販売システム

<!-- wp:heading -->
<h2>本記事について</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>ポートフォリオを閲覧頂く方が理解しやすいよう</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>motoyaが作成した【化粧品販売システム】について関連する情報を整理した内容となっております。</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>解説リンク集</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3>本システムのソースコード</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><a href="https://github.com/motoya0118/cosme_system_public" title="Github">Github</a></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>要件定義・基本設計についての解説</h3>
<!-- /wp:heading -->

<iframe width="560" height="315" src="https://www.youtube.com/embed/4vIj4XW7RQs" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

<!-- wp:paragraph -->
<p>動画で使用した資料は<a href="https://docs.google.com/presentation/d/1sEbYq2mtv9p2DoYqVBTj2zaqPRKjD057/edit?usp=sharing&amp;ouid=103039355251707559990&amp;rtpof=true&amp;sd=true" title="こちら">こちら</a>から閲覧可能です。</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>解説記事が見当たらず自力で解決した部分を解説した投稿</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><a href="https://qiita.com/motoya0118/items/651478c574d1247a1f86" title="①Python gspread でGoogle スプレッド シートをデータベース利用する際の注意点">①Python gspread でGoogle スプレッド シートをデータベース利用する際の注意点</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><a href="https://qiita.com/motoya0118/items/99cdb84e4e3b296157b9" title="②pythonで注文APIを使う方法(ヤフーショッピング,Qoo10,au pay マーケット)">②pythonで注文APIを使う方法(ヤフーショッピング,Qoo10,au pay マーケット)</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->