OmniAICreator/Qiita-1.07M huggingface dataset:
複素数を用いたジャンケン実装

# 最初にコード全体

```python
import cmath

_2pi = 2 * cmath.pi
ROCK = 1
SCISSORS = complex(cmath.cos(_2pi/3), cmath.sin(_2pi/3))
PAPER = complex(cmath.cos(-_2pi/3), cmath.sin(-_2pi/3))


def judge(one, another):
    arg = cmath.phase(another / one)
    if arg == 0:
        return "あいこ"
    elif arg > 0:
        return "勝ち"
    else:
        return "負け"
```

<details><summary>テストコード</summary><div>

```python
def test():
    assert "勝ち" == judge(ROCK, SCISSORS)
    assert "勝ち" == judge(SCISSORS, PAPER)
    assert "勝ち" == judge(PAPER, ROCK)
    assert "負け" == judge(SCISSORS, ROCK)
    assert "負け" == judge(PAPER, SCISSORS)
    assert "負け" == judge(ROCK, PAPER)
    assert "あいこ" == judge(ROCK, ROCK)
    assert "あいこ" == judge(SCISSORS, SCISSORS)
    assert "あいこ" == judge(PAPER, PAPER)
```

</div></details>

# 解説

そもそも複素数を導入したモチベは、円上に✊✌✋を配置すれば三つ巴の強弱関係をうまいこと表現できるのではと思ったからである。

`complex`型（複素数）で定義している`ROCK, SCISSORS , PAPER`（それぞれ ✊, ✌, ✋）を複素平面上に図示すると下図のようになる。

```math
\begin{align}
\text{ROCK} &= 1 \\
\text{SCISSORS} &= \cos\left( \frac{2\pi}{3} \right) + i \sin\left( \frac{2\pi}{3} \right) \\
\text{PAPER} &= \cos\left( -\frac{2\pi}{3} \right) + i \sin\left( -\frac{2\pi}{3} \right)
\end{align}
```

<table>
  <thead><tr>
    <td>勝ち</td>
    <td>負け</td>
  <tr></thead>
  <tbody><tr>
    <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488916/bd54ded7-d2c9-f2ef-0fd5-7396ffd3d00b.jpeg"></td>
    <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488916/8f6766e4-7c92-c4ec-69bf-1e6704dc2fc7.jpeg"></td>
  <tr></tbody>
</table>

これを反時計回りすると「✊は✌に勝ち、✌は✋に勝ち、✋は✊に勝つ」という勝ちパターンが現れ、逆に時計回りすると「✊は✋に負け、✋は✌に負け、✌は✊に負ける」という負けパターンが現れる。

ここで、✊を反時計回りに120°ずらすと✌になるので、✊から✌への[偏角](https://ja.wikipedia.org/wiki/%E8%A4%87%E7%B4%A0%E6%95%B0%E3%81%AE%E5%81%8F%E8%A7%92)

$$ \arg \frac{\text{SCISSORS}}{\text{ROCK}}$$

は`+120°`である。逆に、✌から✊への偏角

$$ \arg \frac{\text{ROCK}}{\text{SCISSORS}}$$

は`-120°`である。
（一般的に、反時計回りはプラスの角度で、時計回りはマイナスの角度として扱われる。また、偏角の主値は $(-180°,~+180°]$ とする。）

つまり、以下の手順で分母にした変数の勝敗を知ることができる。

1. 対決させたい変数同士で割り算する。
1. 偏角をとる。
1. プラスかマイナスかゼロかを判別する。
PR-S300NEのポート開放で悩んでいる人へ。

# はじめに
静的IPマスカレード設定を追加したのにいつまでたってもポート開放できない！といった方へのTODO的な意味合いです。

# 結論
![74F1F871-52D5-4CB3-AC20-808851C6179A.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1596729/a5502925-a889-b4c1-0c96-bf427e69779e.jpeg)
「エントリ番号」の左のチェックボックスをONにして保存すること！！
当たり前すぎることなのにこれで僕は3年以上悩みました。(アホ)

# あとがき
これで家のパソコンでマイクラ鯖立てて開発継続できます…もしお手伝いするよって優しい人いたらTwitterのDMください。
`mix nerves.new hello_nerves` したときに作成されるプロジェクトの雛形って一体どこにあるの？

https://qiita.com/official-events/5cb794f7cb9ac194ed70

**one for all, all for one**

Advent Calendar 2022 11日目[^1]の記事です。
I'm ready for 12/25,**2022** :santa::santa_tone1::santa_tone2::santa_tone3::santa_tone4::santa_tone5:
I'm looking forward to  12/25,**2022** :santa::santa_tone1::santa_tone2::santa_tone3::santa_tone4::santa_tone5:
私の[Advent Calendar 2022 一覧](https://docs.google.com/spreadsheets/d/1HQvFjagQLRPjOYAjDVzWp9S4b8dKixxvvaz_TtbZWto/edit#gid=1723448955)。

[^1]: @kaizen_nagoya さんの「[「@e99h2121 アドベントカレンダーではありますまいか Advent Calendar 2020」の改訂版ではありますまいか Advent Calendar 2022 １日目　Most Breakthrough Generator](https://qiita.com/kaizen_nagoya/items/49ebebee3a0377f3b59b)」から着想を得て、模倣いたしました。 

# はじめに

[Elixir](https://elixir-lang.org/)を楽しんでいますか:bangbang::bangbang::bangbang:
[Nerves](https://www.nerves-project.org/)を楽しんでいますか:bangbang::bangbang::bangbang:

[nerves_bootstrap](https://github.com/nerves-project/nerves_bootstrap)の話をします。

# `mix nerves.new hello_nerves` したときに作成されるプロジェクトの雛形って一体どこにあるの？

気になったことがある方はいらっしゃいませんか？

2022/01/08 22:57現在、[ココ](https://github.com/nerves-project/nerves_bootstrap/tree/main/templates/new)にあります。

https://github.com/nerves-project/nerves_bootstrap/tree/main/templates/new

@mnishiguchi さん、即答でした :rocket::rocket::rocket:
すばらしい :tada::tada::tada:
感謝、感激です！！！

# [Nerves](https://www.nerves-project.org/)のバージョン追従はどうやるのがいいの？

**ナウでヤングでcool**でおなじみの[Nerves](https://www.nerves-project.org/)のバージョンがあがると、`mix nerves.new hello_nerves` をしたときに作成されるプロジェクトの雛形が変更されます。

どうやって自身のプロジェクトに取り込んで行くのがよいでしょうか。
私は、プロジェクトのルートにて

```bash
$ mix archive.install hex nerves_bootstrap
$ mix nerves.new .
```

としております。
細かいことは気にせずにこれが手っ取り早いかなあとおもっています。
とりあえず、Overrideに`Y`と元気よく答えて、`git diff`で差分をみながらどうするか決めるというやり方です。

`mix hex.outdated`というコマンドで一旦どんな状態なのか確認することができます。
@pojiroさんに教えてもらいました。

そももそも、`mix nerves.new hello_nerves` したときの雛形はどこにあるのでしょうか？　という疑問が生じまして、「[NervesJP #22 新年LT回](https://nerves-jp.connpass.com/event/234191/)」にて聞いた(|> きいた |> Qiita)内容をまとめた。

Qiitaは私の外部記憶装置です。いつもありがとうございます。

「[NervesJP #22 新年LT回](https://nerves-jp.connpass.com/event/234191/)」の模様は以下にまとめています。

https://qiita.com/torifukukaiou/items/d9f2a675c76c4962541c


# Wrapping up :lgtm::lgtm::lgtm::lgtm::lgtm:

Enjoy [Elixir](https://elixir-lang.org/):bangbang::bangbang::bangbang:
Enjoy [Nerves](https://www.nerves-project.org/):bangbang::bangbang::bangbang:
 
`mix nerves.new hello_nerves` したときに作成されるプロジェクトの雛形は、[ココ](https://github.com/nerves-project/nerves_bootstrap/tree/main/templates/new)にあります。

2022年に流行る技術予想 ーー それは、[Nerves Livebook](https://github.com/livebook-dev/nerves_livebook)です:rocket::rocket::rocket:

---

I organize [autoracex](https://autoracex.connpass.com/).
And I belong to [NervesJP](https://nerves-jp.connpass.com/).
I hope someday you'll join us.

[We Are The Alchemists, my friends!](https://www.youtube.com/watch?v=04854XqcfCY)
VScodeでPython docstringを作成する

備忘録として

### 環境
- ホストOS: indows11 
- ゲストOS: WSL2 Ubuntu20.04
- VScode1.63.2
- Python3.10.1

### 手順

1. 拡張機能「Python Docstring Generator」をインストールしてVScodeを再起動します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598747/934878ca-b4ff-b4f7-8a0a-db8189ac2b0d.png)

2. クラスや関数宣言箇所の直下で``` ctrl + shift + 2``` と入力するとdocstringが生成されます

※ ``` """ ``` (ダブルクォーテーション3つ)でも生成できますが、入力の手間を考えるとショートカットキーを使う方が良いでしょう


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598747/88135988-0293-011a-a1a2-74161e81a9ef.png)

あとは[sumary]や[description]欄に適宜関数や引数の情報を記述していきましょう。

### 備考

「Python Docstring Generator」ではdocstringに4通りのスタイルが利用可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598747/1ec69217-3e41-ca84-e7de-60cf3c0afed5.png)


#### ① docblockr

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598747/27eed0eb-1f1c-d1ae-c8ea-518caaf2af42.png)

標準的な形式です

#### ② google

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598747/0316c4a4-74fb-64ce-275f-576c8535a23e.png)

docblockrをよりシンプルにした形です。個人的にはこれが好みです

#### ③ sphinx

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598747/8f6cdd95-62bb-b376-f7f1-9179c90285a2.png)

パラメータの名前と型が縦に並んでいます。どうしてもdocstringが縦長になるので可読性が低くなります。

#### ④ numpy

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598747/0492ad03-9cb2-e6ad-f456-0d58ea2643fa.png)

②と③のあいの子みたいな感じです。

#### どれを使うか

関数の動作に影響しないので、個人開発では好み・チーム開発ではチームのルールに合わせれば良いでしょう。
私はgoogleがシンプルで好みです。(デフォルトの設定もgoogleになっています)

### 注意点

[Python for VSCode](https://marketplace.visualstudio.com/items?itemName=tht13.python&ssr=false#review-details)という拡張機能が有効になっている場合、戻り値の型が指定されているとdocstringが正しく表示されません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598747/9d05eb2b-1a20-f17a-dcb4-fa270662bd77.png)

詳しい原因は分かりませんがPython for VSCodeが有効化されていると、シンタックスハイライトに影響するようです。

差支えなければ無効にするかアンインストールしてしまってよいでしょう。
(レビューも低評価が多いですね...)

### 参考資料

[VSCodeの拡張機能でPython docstringを生成する](https://gri-blog.hatenablog.com/entry/2021/06/17/153000#docstring%E3%81%AE%E7%94%9F%E6%88%90)
[ Python for VSCode - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=tht13.python&ssr=false#review-details)
[VSCode Python Docstring Generator](https://marketplace.visualstudio.com/items?itemName=njpwerner.autodocstring)
[pythonシンタックスハイライト崩れ問題 in VSCode](https://qiita.com/nkg/items/d2ccadfdbb5d9f378609)
[[python] syntax highlighting breaks on function annotations #138](https://github.com/MagicStack/MagicPython/issues/138#issuecomment-403543253)
ハッカソンで「強強エンジニア」が言っていた有用な情報

前回の『初心者でも、これだけやればなんとかなるハッカソン！！』に続いてハッカソンに関する内容の記事になります。
# 0.はじめに
先日、サポーターズ主催の『【オンライン開発合宿vol.12】思わずニヤッとするアプリケーションを作ろう！』という、ハッカソンに参加させていただきました。

ハッカソン終了後には、懇親会なるものが、zoom上で行われます。その時にランダムでブレイクアウトルームが作られるのですが、偶然にも3回中2回メンターさんや、強強学生エンジニアの方と当たり、<strong>良い話</strong>(個人的に"おぉ"と思ったもの)を聞けたので、備忘録として残しておこうと思いました。

# 1.若者の特権とエンジニアとしての成長
この話は一つの質問から始まりました。
**『成人したら何か成長した感覚ってやっぱりあるものなんですか？』**
これに対して強強エンジニアさんはこう言いました。
以下、結構お酒入ってるエンジニアさんの話になります。

「ないよ。でもね、人って何かの拍子に変わるもんじゃないんだよね。」

「変わりたくて、変わる。それしかない。そのために、常にアンテナを張って、自分が求めているものと関連したものに参加、挑戦する。」

「今自分が技術的にできるものはさっさと終わらせて、ハッカソンとかそういう機会を見つけて、できないことに挑戦する。」

「もしそこで失敗したとしても、若いからやり直せるので、全然OK！これが若者の1番の特権だと思う。」

「で、また挑戦する。このサイクルを短くして、結果的に長スパンで成長する。」

こう言う風に学生エンジニアには成長していってほしいなと思います。

**深い…**

# 2.プログラミング力を高めるには？

「結局は地道に書き続けるしかない。
最初はコードの一部を書き換えたりして学ぶ。その次は自分で考えたものを作る。もしくは他の人のコードを真似して作る。そうすることでプログラミング力は高くなると思います。」
**近道はないようです。**

# 3.学生エンジニア界隈でも隣の芝は青く見える。でも…
ハッカソンには大抵、
情報系専攻の国立学生エンジニアと専門学生エンジニアが参加します。

両者の言い分が食い違っているらしいのです。

専門学生は「プログラミングのアカデミックなことをやっているアイツらには、勝てねぇわ」
国立学生は「専門の奴ら、手めっちゃ動かせれるしコード書けるし勝てねぇだろ」

このように言える人たちはそもそも、自分と少し土俵が違う人をハッカソンといった機会に交流を通して知っているので、その時点で凄いのですが、、、

プログラミングは結局、自分でキャッチアップしないといけないので、どちらの領域においても
**やる子がやる世界**
だそうです。

# 4.技術力が追いつかない件について
とある審査員の方が僕に投げかけた質問です。
「君は何でプログラミングを始めたの？？」

僕「そりゃぁ、自分のアイデアを形にできて、今作りたいものがあるからです。」
Tさんはこの返答が意外だったのか、驚いた表情で、「それめっちゃエンジニア向いてるよ！！」

僕「いや、でもそれに対する技術力が伴わなくって、、、」
Tさん「伴わなくて当たり前なの！！今実装したい機能を勉強してやったとしても、あれを追加したい、やっぱ最新の技術に変更しようとなって、結局は技術力なんて一生追いつくことはないんだよ。」

**僕は「技術力がないこと」を理由に開発をしない口実を作っていただけなのかもしれません。**
これを聞いてからは吹っ切れて、個人開発を進めています
（まぁキャッチアップしながらなので、苦戦を強いられてはいますが笑）

# 5.強強エンジニアが注目している技術
1. クバネティス
『Dockerなどのコンテナ仮想化ソフトウェアを管理、および自動化するためのオープンソフトウェア(OSS)のこと』
ちょっとよく分かりませんが、テスト期間終わったらキャッチアップします。
[udemy](https://udemy.benesse.co.jp/development/system/kubernetes.html)
[カゴヤのサーバー研究室](https://www.kagoya.jp/howto/cloud/container/kubernetes/)

2. AWS
Amazon Web Serviceの略称で、Amazonが提供しているクラウドコンピューティングサービスの総称
[AWS公式](https://aws.amazon.com/jp/what-is-aws/)
3. GCP
AWSと同じくクラウドサービスの一つで、これはGoogleが提供しているもの。
[Google Cloud公式](https://cloud.google.com/gcp/?utm_source=google&utm_medium=cpc&utm_campaign=japac-JP-all-en-dr-bkws-all-all-trial-e-dr-1009882&utm_content=text-ad-none-none-DEV_c-CRE_514666343170-ADGP_Hybrid%20%7C%20BKWS%20-%20EXA%20%7C%20Txt%20~%20GCP%20~%20General_%20Core%20Brand-KWID_43700060620875331-aud-970366092687%3Akwd-87853815-userloc_1009524&utm_term=KW_gcp-ST_gcp&gclid=Cj0KCQiAieWOBhCYARIsANcOw0xs-BLJ8hZP6GqBOaEPQEPcZqTb9a-ZLhSTIlm9bsnT-Mqx4fkG3JgaAsR5EALw_wcB&gclsrc=aw.ds)

# 最後に
ハッカソン当日にメモしたことを頼りに今回、記事を書きました。ですが、あやふやな部分もあるかと思いますので、そこのところご了承ください。

最後まで読んで頂きありがとうございました。
次回は
**「僕が成長するきっかけになったJavaScriptの問題と全解説　~昔の僕のクソコードを添えて~」** でお会いしましょう！
ISO 8601（日付時刻表記法）の基本形式から拡張形式へ変換

こんにちは。
[ISO 8601](https://ja.wikipedia.org/wiki/ISO_8601)（日付時刻表記法）の基本形式から拡張形式へ変換しました。ただし処理ロジックが甘いです。

* 基本形式：　```20211225T000000.000+0900```
* 拡張形式：　```2021-12-25T00:00:00.000+09:00```

```javascript
const getDateTimeExtended = str => {
	const len = str.length;
	const Y =   str.slice(0, 4) + '-';
	const M =   str.slice(4, 6) + '-';
	const Dh =  str.slice(6, 11) + ':';
	const m =   str.slice(11, 13) + ':';
	const st =  str.slice(13, len-2)  + ':';
	const u =   str.slice(len-2, len);
	const str_extended = Y + M + Dh + m + st + u;
	return str_extended;
}
```
DockerでSORACOM Arcを使う (Ubuntu 20.04)

任意の IP ネットワークからSORACOMプラットフォームへ接続できる[SORACOM Arc](https://soracom.jp/services/arc/)。
Dockerで動かすときに少し詰まったので共有です。

**2022/2/25追記**
`Dockerfile`を使ったより簡単なセットアップ方法を追記しました。
[このリポジトリ](https://github.com/tsmiyamoto/soracom_arc_on_docker)のREADMEに従ってコンテナを作成することですぐにDockerでSORACOM Arcを使用できます。

# 環境
- Windows 11
- WSL2 (Ubuntu 20.04)
- CPU Architecture: x86_64
- Docker 20.10.11


# Dockerイメージを取得

今回は**Ubuntu 20.04**を使用しました。

```
$ docker pull ubuntu:20.04
```

[公式ドキュメント](https://users.soracom.io/ja-jp/docs/arc/soratun-overview/#%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E5%AF%BE%E8%B1%A1%E3%83%97%E3%83%A9%E3%83%83%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0)によると、サポート対象は次の通りです。
> 以下のプラットフォームをサポートします。
<dl>
  <dt>Linux amd64</dt>
  <dd>Ubuntu 20.04.2 LTS</dd>
  <dt>Linux arm (Raspberry Pi 32-bit)</dt>
  <dd>Raspberry Pi OS 2021-05-07</dd>
  <dd>Ubuntu 20.04.2 LTS
</dd>
</dl>
また、テストと開発用途として以下のプラットフォームで動作します。サポートはありません。
**macOS Big Sur 以降**


# コンテナの作成＆起動

```
$ docker run --cap-add NET_ADMIN -it ubuntu:20.04
```

`--cap-add` とはデフォルトで無効化されている capability を有効化するためのオプションです。
SORACOM Arcのトンネルを作成するには**NET_ADMIN**の権限が必要です（[参考](https://users.soracom.io/ja-jp/docs/arc/install-soratun/)）。

## capabilityとは？
>Linuxにはこのような場合に使える，rootが持っている絶対的な権限を細かく分け，必要な権限だけを与える仕組みが存在します。これがケーパビリティ（capability）です。

>引用元：[第42回　Linuxカーネルのケーパビリティ［1］LXCで学ぶコンテナ入門 －軽量仮想化環境を実現する技術　
](https://gihyo.jp/admin/serial/01/linux_containers/0042)

# パッケージのインストール
取得したDockerイメージはのちに使うパッケージがいくつかインストールされていないので、インストールしておきましょう。

```
$ apt update && apt install -y wget iputils-ping net-tools
```

# /dev/net/tunの作成
```
$ mkdir -p /dev/net
$ mknod /dev/net/tun c 10 200
$ chmod 666 /dev/net/tun
```

# soratun によるバーチャル SIM/Subscriber のブートストラップ
[公式ドキュメント](https://users.soracom.io/ja-jp/docs/arc/bootstrap-authkey/)の通りにやるとうまくいきました。
ただし、ステップ4の

```
soratun --config /path/to/arc.json up
```
を実行するとセッションが開始されます。これは生かしておく必要があるので、別のターミナルで

```
$ docker exec -it YOUR_CONTAINER_ID /bin/bash
```

をして

```
$ ping -c 3 pong.soracom.io
```
をすることで疎通確認ができます。


# 後記
soratunって名前かわいいな、と思ったら **sora**-com **tun**-nelのことなんですね。

# 参考サイト

- [soratun で SORACOM API の認証キーを使用してバーチャル SIM/Subscriber をブートストラップする](https://users.soracom.io/ja-jp/docs/arc/bootstrap-authkey/)
- [SORACOM ArcとDockerで作る仮想デバイス
](https://qiita.com/1stship/items/6410154c67d65d01e65c)
- [Docker内でTUN/TAPを使うときのメモ](https://flast-net.hateblo.jp/entry/2014/08/31/230736)
処理に名前をつけて使おう①　introduceメソッド

※初心者向け
※アウトプット練習の為

開発環境
rails 6.1.4.1
ruby 2.6.5

##問題内容1##
introduceメソッドを作成してください。

**メソッドの処理**
私の名前はRubyです。とターミナルに出力する。

##解答1##

```csharp
def introduce
  puts "私の名前はRubyです。"
end
```

##解説1##
メソッドを作成する場合には、以下のようにプログラムを書きます。

```csharp
def メソッド名
  # メソッドの処理
end
```
今回はメソッド名をintroduceにするため、メソッドの定義は以下のようになります。

```csharp
def introduce
  # メソッドの処理
end
```
メソッドの処理はdef メソッド名とendの中に記述します。今回はターミナルに文字を出力するのでputsメソッドを使います。

```csharp
def introduce
  puts "私の名前はRubyです。"
end
```

なお、問題の条件はメソッドを作成するのみなので、メソッドを呼び出す記述は不要です。もし自身のターミナルで挙動を確認したい場合は以下のように記述し、実行します。

```csharp
def introduce
  puts "私の名前はRubyです。"
end

# メソッドの呼び出し
introduce
```

##問題内容2##
doubleメソッドを作成してください。

**メソッドの処理**
処理1：ターミナルから数値を入力させる
処理2：入力した数値を2倍にした値を戻り値にする

##解答2##

```csharp
def double
  num = gets.to_i
  num * 2
end
```
もしくはreturnを使って

```csharp
def double
  num = gets.to_i
  return num * 2
end
```

##解説2##
まず、メソッドの定義をします。今回はメソッド名がdoubleなので定義は以下のようになります。

```csharp
def double
  # メソッドの処理
end
```
次にメソッドの処理を考えます。今回のメソッドの処理は大きく分けて2つあります。
**処理1：ターミナルから数値を入力させる**
**処理2：入力した数値を2倍にした値を戻り値にする**

**処理1：ターミナルから数値を入力させる**
まずターミナルから数値を入力させます。ターミナルに文字を入力するときはgetsメソッドを使います。

```csharp
def double
 num = gets
end
```
getsメソッドで入力した文字は全て文字列となります。そこで文字列を数値に変換するto_iメソッドを使って、getsメソッドで入力した文字を数値に変換します。

```csharp
def double
 num = gets.to_i
end
```

**処理2：入力した数値を2倍にした値を戻り値にする**
戻り値というのは、メソッドを呼び出したあとに取得される値です。メソッドでは、以下のどちらかの値が戻り値となります。
①メソッドの処理の最後に書かれた値
②return文を使って指定された値

まず①のようにメソッドの最後の値が基本的に戻り値になります。よって以下のようにnum * 2をメソッドの最後に記載すれば、numを2倍した値が戻り値になります。

```csharp
def double
  num = gets.to_i
  num * 2
end
```
もしくはreturn文を使っても良いです。return文はreturn 値とすれば、たとえメソッドの最後でなくても、その値を戻り値にできます。

```csharp
def double
  num = gets.to_i
  return num * 2
end
```

Rubyではreturn文を使わずに、単に戻り値をメソッドの最後に記載することが一般的です。
Power Automate: Teams に Remind 機能を

# 背景
一年半ほど前に実装してたのを思い出したので、記録用に公開。

# 概要
- 時間(hh:mm) や、カレンダー、固定周期での Remind が出来る

:::note warn
Power Automate の制限で、30日を超える指定をすると・・・動きません 😅
:::

## 制限について

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/f5c12a51-fdb8-ef82-800d-e187204d116b.png)

https://docs.microsoft.com/ja-jp/power-automate/limits-and-config#duration-limits

# GitHub
https://github.com/baku2san/TeamsReminder

# 使い方
1. Download "ZipFiles" and zip them<br>![ZipFiles.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/1ff11151-0b3d-dfea-1fa9-0cfb6b4fd59f.png)
1. インポート at [Power Automate](https://japan.flow.microsoft.com/)
1. Remind したいメッセージから、起動<br>![CallReminder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/c7a6fa99-c2b9-dcb1-792b-af5025b3fddc.png)
1. Remind 時期などを設定して、開始<br>![RemindMe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/436212b7-c9e6-7f35-584a-311ca6384d78.png)
1. 以下での実行結果例
    - 0:01 待ち
    - テストメッセージ　追加<br>![ExecuteSample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/4e67599b-626f-36c7-e2ae-3d84be6c4214.png)

# あとがき
はやくTeams内で実装してくれるとありがたい。

以下の用途でまだ使うことはあるんですよね。
- 30分後にきて、みたいな
- フォロー用にタスク作るほどでもないもの

# keyword
Implement reminder to Teams by Power Automate
Power Virtual Agents でチャットボットに画像を表示する【改定版】

#はじめに

この記事は[「Power Virtual Agents for Teamsでチャットボットに画像を表示する」](https://qiita.com/MiyakeMito/items/b89bdd723a0839e353bb)の
**完全上位互換**
になります。
Power Virtual Agents の応答メッセージに画像を表示する際は、こちらの手法をご利用ください。

#前提

Power　Virtual Agnets のメッセージや質問には、画像の埋め込みや、フォントスタイルの変更などのメニューは存在しません。（2022年1月時点）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480768/381ce4d1-eeb4-61d2-784b-f664f8da8fee.png)

ですが、実行環境ではHTMLタグを解釈が可能です。
よって、<img>タグなどを利用し、画像の表示を実現します。

#実現方法

メッセージや、質問の本文にHTMLタグを埋め込んでください。
（利用可能なタグについては今後調査していく予定です）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480768/6565e482-4166-e146-7378-9200aa80498d.png)

```
<img src="https://japaclip.com/files/tiger.png" alt="tiger">
```

今回は[「ジャパクリップ](https://japaclip.com/)さんの素材を利用させていただきました。ありがとうございます。

入力すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480768/f040cdcb-23c0-9c9f-c8f5-966b804f38e0.png)

すぐに見た目が空になりますが、問題ありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480768/9b58293e-d9f8-0bed-f95f-b566b9a7cf92.png)

トピックの保存後、[ボットのテスト]ペインにてトピックを呼び出すと、HTMLタグが解釈されずに表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480768/0c169fab-b025-bc38-c44e-008f0e20c85f.png)


イメージの表示の他、文字のスタイルも変更可能です。

```
<span style="color: red; font-family:'ヒラギノ明朝 ProN'; font-size: 23px;">roar!!</span>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480768/51d987c0-d1ed-3bc2-d386-17d32343525b.png)


作成したボットを[公開]し
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480768/671a6277-df99-2e72-4f8a-75a8bcf1ba5d.png)

公開環境からチャットボットを呼び出すと、HTMLの解釈が行われ画像が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480768/8d802cb7-47fb-4166-58af-ba809984953f.png)


#まとめ

PVAエディターの[ボットのテスト]ではHTMLタグが解釈されないため、まさかHTMLが記載可能とは気が付きませんでした。
この手法で、手軽にリッチな応答を表示するチャットボットが作成可能となります。

#余談

<img>タグのsrcに、base64エンコードした画像データを埋め込んで、応答メッセージを作成してみましたが、実行時にサイズオーバーのエラーとなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480768/f146caa3-abba-57e0-6eba-0eb3f2455305.png)
React 描写（レンダー）の性能向上方法

## shouldComponentUpdate

仮に、コンポーネントが一千個あるいはそれ以上ある場合、レンダーの性能が低下になりがちで、

レンダーが必要ないコンポーネントを制御するためには、「shouldComponentUpdate」を使えば済ませます。

### shouldComponentUpdate(nextProps,nextState)

　・戻り値：boolean。True→Not Update, False→Update.

　・トリガー：コンポーネントの更新時（forceUpdateを除く）

## PureComponent

PureComponentの使い方はReact.Componentと似ています。React.Componentの場所をReact.PureComponentに書き換えるだけで良いです。

両者の違いは、PureComponentは「shouldComponentUpdate」を実装しています。更新前後のProps、Stateの値を自動的に比較してくれます。ただし、その比較は浅く比較（shallow compare）だけです。

どういうことと言うと、**Value Types**の比較なら、それらの値を比較します。それに対して、**Reference Types**の比較なら、参照先だけを比較します、属性は比較しません。

### **Value Types** の比較

```jsx
let wallet = 0
let newWallet = wallet
newWallet = 2
console.log(wallet === newWallet) //false
```

### **Reference Typesの比較**

```jsx
const obj = { wallet: 0 }
const newObj = obj
newObj.wallet = 2
console.log(newObj === obj)  //true

//同じ参照先のため、新しいオブジェクトの属性をどう変えても、戻り値はTRUEになります。
```

### **Reference Typesの属性を比較させる方法**

**属性をそのまま修正するではなく、新しい属性を追加する。**

```jsx
const newObj = { ...state.obj, wallet: 2 }  //ES6のスプレッド構文
setState({ obj: newObj })

//配列の場合
//push，unshiftを使うではなく、concat，sliceなどで新配列を返す

this.setState({
    obj: [...this.state.obj, { newObj }]
})
```
Hot reload, Hot restart, Full restartまとめ


## Hot reload
- 変更したコードをVM(Virtual Machine)にロードして、Widget Treeを再構築(リビルド)する。
- UIのみ更新する。ログイン状態やNavigationの階層などアプリの状態は保持。
- main()やinitState()は実行されない。
- 例外を除き、ルートWidgetのbuild()より下流の変更には対応している。

#### Hot reloadが効かない例
- グローバル変数やstaticフィールドの変更(constは可)
- アプリのプロセスが終了している場合
- コンパイルエラーが起きている場合
- フォントの変更(フォント以外のassetsの変更にはほとんど対応)
- Kotlin, Java, Swift, or Objective-Cなど、ネイティブコードの変更

## Hot restart
- コードの変更をVMにロードしてアプリをリスタートする。
- アプリの状態は破棄される。
- ネイティブコード(Kotlin, Java, Swift, or Objective-Cなど)の変更にはFull restartが必要

## Full restart
- iOS, Andoid, Webのアプリがリスタートする。
- Java / Kotlin / ObjC / Swiftのコードをコンパイルし直すため、時間がかかる。
- Webでは、dartdevc(Chromeでアプリをデバックするためのツール)もリスタートされる。

---


##### 基礎的なことが無知すぎた...
面接の技術的な質問で、Hot reloadとHot restartの違いついて、うまく答えられず、浅学さを思い知らされました。開発をしているだけでは不十分なことには気づけたので、とりあえず、Hot reolad, Hot restart, Full restartについて記録しました。


#####参考
https://docs.flutter.dev/development/tools/hot-reload
https://dart.dev/tools/dartdevc
AWS ToolKit For Eclipseを利用してDynamoDBのテーブルを作成する


## もくじ

1. IAMユーザの作成+ロールの作成
2. EclipseマーケットプレイスでAWS ToolKit For Eclipseをインストール
3. プロジェクトを作成してjar実行
4. おわりに

## 1. IAMユーザの作成+ロールの作成

IAMユーザ、またはロールに`AmazonDynamoDBFullAccess`を付与します。

## 2. EclipseマーケットプレイスでAWS ToolKit For Eclipseをインストール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/2eaf5824-72db-07c7-bd74-e34cbc0ce761.png)

こちらをインストールします。

ここでCredential情報を聴かれるので、IAMユーザーの「アクセスキーID」と「秘密アクセスキー」を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/aebc5d03-133a-c108-1e4f-4719a0df4434.png)

## 3. プロジェクトを作成してJarの実行

新規AWS Javaプロジェクトより、DynamoDBSampleを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/fb63706e-dfa2-2f7f-a4e8-9daa690ca285.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/5d68173d-1549-7351-8c15-fd2ffb4ddc7c.png)

すると以下のプロジェクトが自動生成されます。
この中の`AmazonDynamoDBSample.java`を実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/0af09cc4-b1bc-26b3-ac36-41db5fb1554c.png)

## おわりに

リージョンを明記していない場合、オレゴンのDynamoDBに`my-favorite-movies-table`テーブルが作成されます。
Javaの記述と作成されたテーブルを見比べながら、SDKの学習していくのに使えそうです。
active_hashで保存した都道府県の検索機能について（ransack使用）

###ransackを用いた検索機能実装

今回は、現在作成しているSNSアプリでransackを使用して、登録されているユーザーの一覧ページから登録地域で絞り込みをする機能を作成していました。
その中で、色々エラーで躓いたため学習用に投稿しておこうと思います。


###gemのインストール
```
gem 'ransack'
```
###コントローラーの変更
```
class UsersController < ApplicationController

  def index
    @users = User.paginate(page: params[:page])  
     @q = User.ransack(params[:q])
     @users = @q.result(distinct: true)
     @user_prefecture_id = Prefecture.all
  end

end
```

###viewの設定
```
<%= search_form_for @q do |f| %>
  <%= f.label :prefecture_id, "活動地域" %>
 
  <%= f.collection_select :prefecture_id_eq, @user_prefecture_id,:id,:name,include_blank: '地域絞り込み' %>

  <%= f.submit %>
<% end %>
```
###フォームの記述
  <%= f.collection_select :検索したいカラム名,実際に表示したい配列データ,:表示する際に参照するDBのカラム名: 実際に表示されるカラム名 %>

フォームの記述は上記のようになっております。
ここで、どのテーブルにどのカラムを紐付けているかを把握していなければ、理解するのに時間がかかると思いす。（実際に自分がそうでした）


###最後に

今回は簡単な検索機能を実施しましたが、DBに保存したデータがうまく取り出せずに、3日ほど詰まっていましたが、無事に解決できました。
初学者の方で私のようなエラーで悩む方の役に立てばと思います。
AWS SysOps アドミニストレーター試験に合格したぞ！(SOA-C02)

# はじめに
2021年の7月からAWSの勉強を始め、 CLFとSAAをそれぞれ下記の通り取得してます。
•CLF ：2021年 8月
•SAA ：2021年 11月
AWS SysOps アドミニストレーター試験は2022年の1月に受験し、720ちょいの点数でギリギリ合格しました。
この記事はSOA試験の備忘録となります。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [取り組んだこと](#取り組んだこと)
1. [問題](#問題)
1. [試験ラボ](#試験ラボ)

<!-- 各チャプター -->
<a id="#取り組んだこと"></a>
# 取り組んだこと
以下の勉強をしました。

###①Wizlabs（AWS Certified SysOps Administrator Associate）
https://www.whizlabs.com/aws-sysops-administrator-associate/

海外のUdemyのようなサイトです。
すべて英語で記載されてますので、Google翻訳を用いて勉強しました。

問題は比較的基礎的な内容が多いと思ってますが、
Google翻訳を適用させると、「Auto Scalling」が「自動スケーリング」と翻訳されたり、
CloudFormationのテンプレートが部分的に翻訳された形で表示されたりするため、
元の単語等を知らないまま勉強してしまうと中途半端に翻訳されたままの単語を覚えてしまうと思います。

ハンズオンの講座もあるようですが、練習問題だけ購入してやりました。
正直練習問題と同じような問題は本番の試験ではあまり出なかったような気がします。
各問題を2回ずつやりそれぞれ85％以上はスコアを取れるようにしました。

### ②AWS Blacｋbelt Online Seminar

正直SysOpsの勉強では一番参考になったかなと思います。
以下のサービスの動画を見ました。
•Cloud Watch
•Trusted Advisor
•AWS Systems Manager (①と②があります)
•Cloud Formation
•EventBridge
•KMS

Cloud WatchはSOAを受験するなら必修の内容だと思います。
EventBridgeはCloudWatchと比較して、覚えるのが良いと思いました。

その他として、見てはいませんがVPCとCloudTrail、Config辺りは重要かなと思います。

### ③その他参考にした記事
SysOpsは参考文献が少ないような気がします。。。
以下の記事を2、3回読みました。
エラーの内容など非常に参考になりました。

- [【AWS認定資格】SOA-C02にアップデートされたぞぉぉぉ！！（途中なのでちょくちょく更新）](https://qiita.com/TS_Koike/items/77ff35af07aa275b25e7)

- [AWS Certified SysOps Administrator の試験勉強して「へぇ〜」って思ったものを列挙してる記事](https://qiita.com/atsushi586/items/fed6d4d69c9bc69b87e4)

<a id="#問題"></a>
# 問題
勉強する中でこれは覚えておいた方がいいなと思い、自分がメモしていたことを備忘録として記載します。
##・Cloud Watch
①Cloud Watchエージェントをインストールすることで何ができるようになるのか
→メモリ使用率、ディスク使用率

②メトリクスフィルター
→「Error」の文字列をロググループ、ログストリームから検索できる

③Cloud Watch Alarm
→評価のルール3つを覚えておく（期間、評価の期間、アラームを実行するデータポイント）

##・AutoScalling
①スケーリングのPolicy
→簡易スケーリング、ステップスケーリング、ターゲット追跡スケーリング

##・Trusted Advisor
何ができるかをよく確認しておく（基本的には使用しているリソースに対するアドバイスを提供）

##・Systems Manager
①Configと組み合わせて非準拠のリソースに対して修正を実行できる（非準拠のリソースを検出するのはConfig、修正を実行するのがSystems Manager）

②それぞれの機能について何ができるか覚えておく
•実行日時の定義：Change Callender
•ドキュメント定義：Document Builder、SSMドキュメント（定義済）
•ドキュメント実行：Automation、RunCommand
•定期実行：ステートマネージャー、メンテンナンスウインドウ

##・CloudFormation
•Dependon属性で処理を繋げることが可能（RDSインスタンスの作成が完了してからEC2インスタンスを作成するなど）
•Mapping属性でリージョンを指定可能(AMIとリージョンを指定して展開)
•Deletion Policyでスタックが削除される前にリソースの保持、バックアップ

##その他
•インスタンスタイプの変更にまつわるELB、AutoScalling辺りの挙動
•ハードウェアモジュールを利用した暗号化にはHSM
•EC2のプレイスメントグループ
•Route53のルーティング
•CloudFront、Route53で選択するレコード（エイリアスレコード、CNAMEレコードなどの違い）
•Aurolaのバックアップ
•IAMロール、バケットポリシーなどの権限管理

<a id="#試験ラボ"></a>
# 試験ラボ

2問出ました。
それぞれ回答に30分近く掛かりました。
AWSは実務経験なく、ハンズオンもあまりこなしてきませんでしたが、文章を読みながらで何とか構築することが出来ました。

各設定に関してはかなり試行錯誤しながら回答したため、回答までの過程も採点対象であれば、あまりいい結果とは言えませんでした(最終的な回答としては自分なりに納得行くものができました)。

試験ラボはかなり画面がカクカクし、画面のスクロールなどでストレスを感じます。
CLIも使えるようですが私はマネージメントコンソールのみで回答しました。

#終わりに

結果としてギリギリの合格でした。
1問取りこぼしていたらおそらく不合格ですので、復習が必要だと思いました。

試験ラボは簡単なインフラストラクチャの構成や静的なWebサイトホスティングの構築程度はしたことがあったので、
解答する際にその辺の知識が参考になったと思います。
個人的には試験ラボの対策はそこまで時間を掛けなくても良いと思いました。
（ただ私の場合選択問題は20問程度間違えていた気がするので、試験ラボで助けられた気もしますが笑）


以上
GiNZA sub_phrases で文節の依存関係を解析

## 環境
- Google Colaboratory 
- Python 3.7.12
- ginza-5.1.0

## ginza.sub_phrases

`ginza.sub_phrases`を使うと、文節の依存関係を解析できます。

```
!pip install ginza ja_ginza
```

```python
from collections import defaultdict

import spacy
import ginza

nlp = spacy.load("ja_ginza")

def analyze(text: str, phrase_func):
    ret = defaultdict(list)
    doc = nlp(text)
    for sentence in doc.sents:
        for token in ginza.bunsetu_head_tokens(sentence):
            for _relation, sub_phrase in ginza.sub_phrases(token, phrase_func):
                ret[sub_phrase].append(phrase_func(token))
    return dict(ret)
```

```python
analyze("焼肉を食べない日はない", ginza.phrase)
```

```
{'日': ['ない'], '焼肉': ['食べ'], '食べ': ['日']}
```

### 出力するフレーズ単位の制御
`ginza.sub_phrases()`の第2引数で、出力の形式を変更できます。[公式ドキュメント](https://www.megagon.ai/jp/blog/ginza-version-4-0/)には下記のように記載されています。

>トークンが属する文節を係り先とする文節を依存関係ラベルと共に返します。phrase_funcにはginza.bunsetuまたはginza.phraseを指定します。：

`ginza.phrase`を使った場合

```python
analyze("焼肉を食べない日はない", ginza.phrase)
```

```
{'日': ['ない'], '焼肉': ['食べ'], '食べ': ['日']}
```

`ginza.bunsetu`を使った場合

```python
analyze("焼肉を食べない日はない", ginza.bunsetu)
```

```
{'日+は': ['ない'], '焼肉+を': ['食べ+ない'], '食べ+ない': ['日+は']}
```

ところで、このsub_phrasesの[ソースコード](https://github.com/megagonlabs/ginza/blob/50ff8cb2306a8f72455cdc301d6fb57fb7a4ae09/ginza/__init__.py#L375-L387)は下記のようになっています。

```python

@sub_phrases.register(Token)
def _sub_phrases(
        token: Token,
        phrase_func: Callable[[Token], U] = _phrase,
        condition_func: Callable[[Token], bool] = lambda token: True,
) -> Iterable[Tuple[str, U]]:
    return [
        (
            t.dep_,
            phrase_func(t),
        ) for t in bunsetu_span(token).root.children if t.i in bunsetu_head_list(token.doc) and condition_func(t)
    ]
```

実際の第2引数は`phrase_func: Callable[[Token], U]`であり、`Token`を引数に取るような関数となっています。

例えば`ginza.lemma_`を渡すことで、原形を返り値として得ることができます。

```python
analyze("焼肉を食べない日はない", ginza.lemma_)
```

```
{'日': ['ない'], '焼肉': ['食べる'], '食べる': ['日']}
```

恒等写像`lambda x: x`を渡すことで、`Token`オブジェクトをそのまま受け取ることもできます。

```python
analyze("焼肉を食べない日はない", lambda x: x)
```

```
{焼肉: [食べ], 食べ: [日], 日: [ない]}
```

適当な独自定義関数を渡して動かすこともできます。

```python
def genkei(x: ginza.Token):
    return str(ginza.bunsetu(ginza.lemma_)(x))

analyze("焼肉を食べない日はない", genkei)
```

```
{'日+は': ['ない'], '焼肉+を': ['食べる+ない'], '食べる+ない': ['日+は']}
```

## 参考
- [GiNZA version 4\.0: 多言語依存構造解析技術への文節APIの統合 \- Megagon Labs \| リクルート AI研究機関](https://www.megagon.ai/jp/blog/ginza-version-4-0/)
- [GiNZA \- Japanese NLP Library \| Universal Dependenciesに基づくオープンソース日本語NLPライブラリ](https://megagonlabs.github.io/ginza/#%E8%A1%A81-ginza-v4%E3%81%A7%E8%BF%BD%E5%8A%A0%E3%81%95%E3%82%8C%E3%81%9F%E6%96%87%E7%AF%80api%E3%81%AE%E4%B8%80%E8%A6%A7)
ルーティングの優先度・順番

####ルーティングには上から順番に処理がされていくという規則があります。

例えば下記のようなコードの場合、



```php:web.php
Route::get('/picture/{id}', 'UserController@show')->name('shop.show');
Route::get('/picture/edit', 'UserController@edit')->name('shop.edit');
```

『～/picture/edit』のURIを表示しようとすると
先に記載されているRoute::get('/picture/{id}', 'UserController@show')->name('shop.show');
こちらの処理がされます。

URI『～/picture/edit』の画面に遷移した際、
{id}の中にeditが入ってしまいます。カラムにeditという値が存在しない為、エラーが表示されうまく画面遷移がされません。

##解決策
####パラメータのあるルーティングは下にする

```php:web.php
Route::get('/picture/edit', 'UserController@edit')->name('shop.edit');
Route::get('/picture/{id}', 'UserController@show')->name('shop.show');
```

こうすることで、
URIが『～picture/edit』に画面遷移が可能となり、editメソッドの処理が可能となります。
RSS とは

## 勉強前イメージ

いろんな媒体からのデータを集める系のやつ？
よくあるのがtech系の記事とかあるあるな感じする

## 調査

### RSS とは

Rich Site Summary の略で、webサイトの記事や更新情報を配信するデータフォーマットになります。
XMLベースのフォーマットで、更新された記事のタイトルやURLなどを記述することができます。

RSSでデータを取得するには、
取得したいwebサイトがRSSフィールド(更新情報等)を配信していることが前提です。
またRSSフィールドとはwebサイトの情報を配信する役割があり、
RSSリーダーという、巡回ツールが登録したサイトのフィールドを一覧にしてくれるものがあります。

RSSリーダーはページタイトル、アドレス、見出し、要約、更新時刻が表示されます。
複数のリーダーを登録できるので、興味がある分野の情報をすぐに取得することができます。

## 勉強後イメージ

大体イメージ通りだったw
リーダーが登録サイトを巡回して更新があったら知らせるって感じなのかな
XMLでデータを取ってきてるらしい

## 参考

- [RSSとは？基本の仕組みと便利な使い方](https://uxmilk.jp/44993)
- [RSS 【RDF Site Summary】 Really Simple Syndication / Rich Site Summary](https://e-words.jp/w/RSS.html)
Reactの環境構築 by create-react-app

#はじめに
これは、create-react-appの環境を構築したときのメモ。
自分のメモ用なので、見ないでくださいorz~~~。

##nodeをinstall
[ここ](https://nodejs.org/ja/download/)から自分のOSのアイコンを押してinstallする。

##コマンドプロンプトを開く
1. Windows + R
2. cmdと入力
3. Ctrl + Shift + Enter
4. Alt + y

以下はコマンドプロンプト上での作業
##node, npmの確認
下記のコマンドでバージョンが表示されればO.K.

```
node -v
npm -v
```
##yarnのinstall
npmは遅くて脆弱性があるらしいので、その改良版みたいなyarnを用いる方が良いらしい。

```
npm install -global yarn
```

##yarnのパス指定
パスが通っていれば必要なし。
以下のコマンドで得たパスを通す。環境変数を変更した後は、__再起動__した方が良いかも。

```
yarn global bin
```

##create-react-appのinstall
```
yarn global add create-react-app
```
##create-react-appの確認
下記のコマンドでバージョンが表示されればO.K.

```
create-react-app -v
```
##プロジェクトディレクトリに移動
```
cd [プロジェクトを入れるフォルダ]
```
##プロジェクトの作成
今回は my_app というプロジェクトを作成する。お好きな名前でどうぞ。因みに大文字の名前は不可だった。

```
create-react-app my_app
```

##プロジェクトに移動
```
cd my_app
```

##プロジェクトを開始
以下のコマンドを入力しブラウザが立ち上がりreactのマークが表示されれば完了！

```
yarn start
```
#参考文献
コマンド(2022/01/08)
* https://qiita.com/rubytomato@github/items/1696530bb9fd59aa28d8

パス(2022/01/08)
* https://kantaro-cgi.com/blog/nodejs/npm_and_yarn_global_install_path.html
三角関数を使って円を描く

# やったこと
学習用のプログラミングの問題をやっていて、三角関数がわからなくてプログラムが設計できなかったのが悔しかったので、数学を学びなおしています。

基本的な内容かもしれませんが、sinとcosを使えばx座標とy座標がわかるらしいので、円を描画するコードを作成しました。

``` python3
# coding: utf-8
import matplotlib.pyplot as plt
import numpy as np

angle = np.arange(0,360) #0~360の角度のリストを作成
x = np.cos(np.radians(angle)) #x座標のリスト
y = np.sin(np.radians(angle)) #y座標のリスト

plt.plot(x,y)
plt.axis('equal') #x軸とy軸のスケールを揃える
plt.show()
```

# 出力結果
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1359985/c53e4a97-d1fc-fd5d-3c71-6417265b27a2.png" width=50%>
【Rails】ファイル投稿ボタンをカスタマイズ（備忘録）

ファイルを投稿するボタンをカスタマイズする方法を残しておきます。

元の記述

```Ruby:new.html.erb
＃省略
    <div class="field">
        <%= f.label :画像 %>
        <%= f.file_field :image %>
   </div>
＃省略
```

変更後


```Ruby:new.html.erb
＃省略
<div class="label-box__inner">
    <label class="mealpicture">料理画像
        <%= f.file_field :image ,class:"input-default" %>
        <div class="boxFileSelect"></div>
    </label>
</div>
＃省略
```

```Ruby:SCSS
.label-box__inner{
 padding: 10px 20px 10px 20px;
  .input-default{
    display: none;
    width: 100%;
    height: 40px;
    margin: auto;
    padding: 10px 16px 8px;
    border-radius:4px;
    background: #fff;
    line-height: 1.5;
    cursor: pointer;
    outline-width: 2px;
   }
}
```

以上です。
お好みに合わせてCSSの値をいじったり、ラベルの文字をいじってください。
Unity  Hierarchy & Inspector を構成する際に気を付けていること【個人的規約】


#　基本
##パッと見てヒエラルキが見難かったら区切り線の名前を持つ空ゲームオブジェクトを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492471/4c7fbf05-ef06-c9ce-be79-106e2a999870.png)

## スクリプトは末尾Behaviorで命名しない．末尾Modelにする
理由：ファイが関数スクリプトに見えるので．オブジェクト指向であるように見えなくなる．

##2文字以上のゲームオブジェクト名は，スモールスネーク

```
gameObject
```

理由：インスタンスを持つオブジェクト名が大文字始まりだと気持ち悪い．大文字始まりはスクリプトクラス名で使いたい．

##2文字のゲームオブジェクトは大文字

```
BG
```

理由：見難い

# MVCモデルを使う場合
modelとviewを持つ構成になったとき初めて，
親の末尾にControllerをつける．
末尾Controllerは，MVCの構成になっていることが把握しやすい.

```
▽objectController
    ▽model（スクリプトをアタッチする）
    ▽view（子に可視オブジェクトを配置）
```

理由：
①コントローラは，modelとviewを知っているので親で良い．
②model，viewの兄弟にすると，スクリプトでgetComponentが使いづらい．

#Anchor,Pivotの基本構成
基本構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492471/ee1c03bb-ef13-7456-83f2-82337595298a.png)

```Unity.RectTramsform
Pivot:X=0
Pivot:Y=0
Anchor.Preset = left bottom
```
理由：
左下を原点とするUnityのギズモ座標系にする．
※ただし拡大縮小すると意図しない挙動となるので，
　拡大縮小する場合は，空ゲームオブジェクトの子にGameObjectを配置して，そのGameObjectのみAnchorXYを0.5にする．
Splunk本、Java本(Log4Shell)、Python本のご紹介

# 1.Splunk本
## 1.1.初心者 Windows派向け)
* [Splunk Enterpriseの始め方、Splunk Cloudへの引っ越し - Windows編 (2021/12/4)](https://amzn.to/3jSknBP)
* [本気でWindowsマシンを監視する方法: Splunk + Splunk Windows Add-on編 (2022/1/7)](https://amzn.to/3VRqtQq)

## 1.2.初心者 Unix/Linux派向け)
* [Splunk Enterpriseの始め方、Splunk Cloudへの引っ越し - Linux編 (2021/12/17)](https://amzn.to/3IAEkaR)
* [本気でUnix/Linuxマシンを監視する方法: Splunk + Splunk Unix and Linux Add-on編 (2022/1/30)](https://amzn.to/3GLXmcG)

## 1.3.中級者向け)
* [ログのCIM対応はもう怖くない！ぱぱっとCIM化！: InfoSec Appで可視化もやっちゃう (2022/1/14)](https://amzn.to/3GLmujN)
* [Splunk CloudでSecurity/IT監視基盤を「構築」しよう: WordPress + Apache HTTP + MySQL on Windows編(2022/2/9)](https://amzn.to/3WQdkYY)
* [Splunk CloudでSecurity/IT監視基盤を「構築」しよう: WordPress + Apache HTTP + MySQL on Linux編(2022/2/23)](https://amzn.to/3WZAU5S)

## 1.4.上級者向け)
* [Splunk SPL クックブック - concurrency: 超意外！ログからすぐにわからない「同時接続数」Splunkを使えば、超簡単！(2022/4/10)](https://amzn.to/3IvLLzP)
* [Splunk SPL クックブック - host monitoring: ログでホストの死活監視！？ metadataコマンド一発 Splunkを使えば、超簡単！(2022/5/8)](https://amzn.to/3XdMvxH)

# 2.Java本
## 2.1.上級者向け/Expert)
* (Japanese) [Log4Shell 2時間でlog4jの脆弱性を実際に体験できる本: Javaエンジニアにオススメ(2021/12/26)](https://www.amazon.co.jp/dp/B09P7TLW32/ref=cm_sw_r_tw_dp_4GT8R6N5HAM186ZQC1MX)

* (English) [Log4Shell 2 Hours Hands-On Log4j Vulnerability: For Java engineers(2021/12/30)](https://amzn.to/3vInY8g)

# 3.Python本
## 3.1. 初級者向け)
* [キレイなPython開発環境をクラウド上で構築する本 - Anaconda - AWS/GCP/Azure - 2022年06月号: pipトラブルよ、さようなら(2022/5/29)](https://amzn.to/3Ivp8LO)
 
# 4. 著者のご紹介
## クリスフォレスト (Splunk専門家) ([執筆リスト](https://amzn.to/3GLI6g9))

* Splunk Certified Architect資格保持。Splunkを触り始めて10年のキャリア。森を好み、森の中で一日中過ごしたいと思う森の住人。最近は持ち前のデータアナリティクス思考をフル活用し、新たなイノベーションを見出すべく、仮想通貨に没頭中。

## 高橋静香 (Splunk専門家) ([執筆リスト](https://amzn.to/3GLyQZb))

* Splunkを使ったコンサルティング業務をしています。在宅にいながら、リモートでお客様のSplunkの使い方や応用方法をガイドしています。定時でお仕事を終わらせて、新鮮で良質の食材でお食事を作るのが楽しみです。え？食事ときのアルコール？はい、ワインを少々・・・。クリスフォレストさんとは、Splunk仲間です。

## 森野セリ (サイバーセキュリティ専門家) ([執筆リスト](https://amzn.to/3QnYuq5))

* ファイアウォール、VPN、電子証明書、RADIUS、ウィルス検知等海外製品の輸入、日本国内導入におけるセキュリティ製品のエキスパート。現在某企業のSOC部門にて、セキュリティアドバイザーとして勤務。好みのツールは、Splunk。マニアックなサーチ文を書くことに命を捧げている。年齢・職業・経歴は一切秘密。
Python3 コーディング規約(PEP8-ja)

Python標準ライブラリのコーディング規約を整理します。Pythonのコーディング規約は[PEP8-ja](https://pep8-ja.readthedocs.io/ja/latest/)という文書にまとめられており、命名規則やインデントのルールが記載されています。

標準的なコーディングルールに準ずることでプログラムの可読性を向上させることができます。

### インデント

- インデントは1レベルにつき4つ
- 複数行を継続する場合は4つでなくてもよい
- タブではなくスペースでインデントをつける

### 1行の長さ

- 最大79文字
- docstringやコメント等のテキストは最大72文字
- 2項演算子の前で改行する

## 命名規則

|作成するもの|命名規則|
|-|-|
|パッケージ(ディレクトリ)|全て小文字<br>アンダースコアは非推奨|
|モジュール(ファイル)|全て小文字<br>アンダースコアは可|
|クラス名|CapWords(頭文字が大文字, それ以降はキャメルケース)|
|例外|CapWords<br> 名前の末尾に「Error」を付ける|
|関数名|全て小文字・アンダースコアは可<br>非公開の場合先頭に**_**を1つつける|
|インスタンスメソッドの引数|第一引数は常に**self**|
|クラスメソッドの引数|第一引数は常に**cls**|
|変数名|全て小文字・アンダースコアは可|
|定数|全て大文字<br>単語をアンダースコアで区切る|
【SwiftUI】NavigationView の中の TabView の中の NavigationLink 先で Sheet を開くと NavigationLink が勝手に戻るバグの対処法

GIFの様に、 ``SecondView`` で Sheet を開くと ``FirstView`` に戻ってしまいます。

解消法は、 ``NavigationView`` → ``TabView`` を ``TabView`` → ``NavigationView`` に変えればOKです。

![20220108_01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178570/c583d663-9b66-972f-457c-1d7a0e43218e.gif)

```swift
import SwiftUI

struct FirstView: View {
    
    @State var selection = 0
    
    var body: some View {
        
        // NG。勝手に戻る。
//        NavigationView {
//            TabView(selection: $selection) {
        // OK。
        TabView(selection: $selection) {
            NavigationView {
                NavigationLink(destination: SecondView()) {
                    Text("Go to SecondView").font(.title)
                }
                .tag(0)
            }
            .navigationTitle("FirstView")
        }
    }
}

struct SecondView: View {
    
    @State var isPresented = false
    
    var body: some View {
        Button(action: { isPresented = true }) {
            Text("open sheet").font(.title)
        }
        .sheet(isPresented: $isPresented) {
            Text("sheet").font(.title)
        }
        .navigationTitle("SecondView")
    }
}

struct FirstView_Previews: PreviewProvider {
    static var previews: some View {
        FirstView()
    }
}
```

**バージョン**
Xcode 13.1 
iOS 15.0
nvm-windowsを使ってnodeをバージョン管理



## 最初に

node v12を使っていましたが、メンテナンスも2022.4月で切れるのでバージョンアップしなければと思いつつ、のびのびにしていました。
qiita投稿に慣れるためにもｖ16アップデートしてみます。

### 環境
os: windous10
node12⇒node16

## バージョン管理ツール選択

nodeのバージョン管理ツールはいくつかあるみたいだが、windowsだと選択肢少ないみたい。スター数の多いnvm-windowsにしてみた。

参考

[Node.jsのバージョン管理ツールを改めて選定する【2021年】](https://qiita.com/heppokofrontend/items/5c4cc738c5239f4afe02)

## nvm-windows のインストール

参考
[2020-0711 nvm-windows で Node.js の 環境構築 と バージョン管理 (Windows, nvm) ](https://blog.beachside.dev/entry/2020/07/11/110000)


git-hubのhttps://github.com/coreybutler/nvm-windows/releases にnvm-setup.zipがあるのでクリックしてダウンロード

zipファイルが解凍され、nvm-setup.exeをクリックでインストール開始。インストールフォルダなど聞かれますが、デフォルトでやってみました。

+ nvmインストールフォルダ
  
    C:\Users\〇〇〇〇\AppData\Roaming\nvm

+ node.jsインストールフォルダ
  
    C:\Program Files\nodejs

+ Destination location:
  
    C:\Users\〇〇〇〇\AppData\Roaming\nvm

+ 途中で今まで使っていた「Node.js v12.18.4.」を今後も使うか？⇒今後も使うかもしれないので「はい」とした
  
## nodeインストール

```
nvm install 〇.▼.◇
```
でNodeのバージョン指定できる

## 詰まる⓵
参考ページだと、インストール後にNode使用バージョンの切り替えのため

```
node use  〇.▼.◇
```

とあるが、「内部コマンドまたは外部コマンド、・・・」とでた。
pathが通ってないのか？システム環境変数を確認するが、通っている。

検索していると、「[【nvm】nvm use で exit status 5: になってしまった時の解決方法](https://qiita.com/zb185423/items/fc8d93174e285650248f)」にたどり着く。

### 管理者権限でコマンドプロンプト立ち上げ

```
node use 〇.▼.◇
```

### 動くかの確認
```
node -v

v16.13.1
```

できたー( ^)o(^ )わーい！

## 詰まる⓶
上記で終了かと思った。しかし管理者権限ではいいが、vscodeのterminalでnodeが動かない。(´；ω；`)ｳｩｩ

再起動したら動いた。😌（ほっと）

## 終わりに
環境構築はいつも時間かかる。これだからついつい先延ばしにしてしまう。
次の投稿は画像を貼ろうと思っていたが、これも先延ばし・・・
AWS Systems Manager Session Maneger（SSM）を使ったRDSへの接続

# はじめに
- 本記事では、プライベートサブネットに置いたRDSへのAWS Systems Manager Session Maneger（以降SSM）を使ったローカルからの接続方法について、備忘録も兼ねて書いていく。
- これまでは、プライベートサブネットに置いてあるRDSへ接続するには、EC2を踏み台にしてSSHポートフォワーディングを行う必要があり、そのためにはEC2をパブリックサブネットに置き、SSH用のポートも開ける必要があった。
- しかし、SSMを使えば、EC2をプライベートサブネットに置き、SSH用のポートを開けることもなく、EC2にローカルから接続できるようになり、セキュリティリスクも軽減させられるようになった。

# 実行環境について
- Windowsで実行。

# 作成手順
## RDS作成
- プライベートサブネットにRDSを作成。
- 作成方法については本記事では省略するが、気を付けるポイントを下記に書いておく。
    - RDSに付与するセキュリティーグループの設定。
        - インバウンドルールに、EC2に付与するセキュリティーグループから5432ポートへの接続の許可を入れておくこと。



## EC2作成
- 今回はプライベートサブネット内にEC2を作成。
- EC2の作成方法については本記事では省略するが、気を付けるポイントを下記に書いておく。
    - キーペアは、SSHポートフォワーディング時に必要になるのでダウンロードしておくこと。
    - EC2に付与するIAMロールに下記のポリシーを付与しておくこと。
        -  AmazonSSMManagedInstanceCore

## VPCエンドポイントの作成
- プライベートサブネット内のEC2でSSMを利用するには、AWS PrivateLinkを使う必要あり。
- 下記3つのVPCエンドポイントを作成。
    - com.amazonaws.ap-northeast-1.ssm
    - com.amazonaws.ap-northeast-1.ssmmessages
    - com.amazonaws.ap-northeast-1.ec2messages
- 作成方法については、下記を参照。
    - https://zenn.dev/mn87/articles/31bd31c3c75f04

## SSMの設定
- AWS CLIをインストール。
    - 手順は下記を参照。
        - https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-windows.html
        - https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-quickstart.html
- Session Manager Pluginをインストール
    - 手順は下記を参照。
        - https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html
- `C:\Users\xxxxx\.ssh\config`に下記内容を追記。
    - xxxxxはユーザー名。
    - configファイルがない場合は作成する。

```
host i-* mi-*
    ProxyCommand C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters portNumber=%p"
```


## ローカルより接続
- まずはSSMでプライベートサブネットに置いたEC2に接続できることを確認。

```
ssh -i {ダウンロードした秘密鍵のパス} ec2-user@{EC2インスタンスID}
```

- 接続できたことを確認。
![タイトルなし3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/6d1c2a93-7595-6b19-6a7e-c0507e58f8be.png)

- SSHポートフォワーディングでトンネル開通。
       - 秘密鍵については、置き場所次第では権限エラーが出るので注意。
        - Windowsの場合は、ユーザー直下に置いていたら問題なさそう。
       - ｛｝は除去すること。
    
```
ssh -i {ダウンロードした秘密鍵のパス} ec2-user@{EC2インスタンスID} -L {ローカルのポート}:{RDSのエンドポイント}:{RDSのポート}
```
- 無事トンネルが開通したと思われるので、SQLエディタよりRDSに接続してみる。
![タイトルなし4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/6b329669-bd8e-a3d6-b58c-b3fd3d27ccdb.png)

- 今回はpsqleditより接続。
    - USER/PASSWORD/DB NAME：RDS作成時に設定したもの。
    - HOST：ローカルホストである「127.0.0.1」
    - PORT NO：sshコマンドで設定したローカル側のポート。
![タイトルなし5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/f9773ac1-1b55-5ef9-0c7f-c2db2dbd8861.png)

- 無事に接続ができたことを確認。
![タイトルなし6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264860/9f826cd4-38d3-0fe1-0205-1f6c6db2d05c.png)
Excelの入力シートを基に、Pythonを使って自動でHTML生成してみた

# 目的
pythonスキルアップ用

# 前提
Pythonの環境構築が終わっていること

# 実践
## 入力シートを準備
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/63860480-d3eb-ab5c-15c8-442fe5120e82.png)



## ファイル名、見出しタイトルの準備
```python:test.py
# ブックを取得
book = openpyxl.load_workbook('入力シート.xlsx')
# シートを取得 
sheet1 = book['Sheet1']
# セルを取得
title = sheet1['B2'].value
subTitle = sheet1['B3'].value
```
## 表データを作る
```python:test.py
table = "";
if sheet1['B4'].value == "○":
  loopNumC = sheet1['C5'].value
  i=1
  table = "<div><table border='1'>"
  for num in range(loopNumC):
    arrayB = "B"+str(5+i)
    arrayC = "C"+str(5+i)
    arrayD = "D"+str(5+i)
    tableDataRow = sheet1[arrayB].value
    tableDataA_i=sheet1[arrayC].value
    tableDataB_i=sheet1[arrayD].value
    table+="<tr><td>"+str(tableDataRow)+"</td>"
    table+="<td>"+tableDataA_i+"</td>"
    table+="<td>"+tableDataB_i+"</td></tr>"
    i=i+1
  table+="</table></div>"
```

## ファイル作成～書き込み、ブラウザ表示まで
```python:test.py
index = sheet1['B1'].value

if(os.path.isfile("C:\\Users\\user\\Documents\\python\\html\\"+index+".html")):
  html= pathlib.Path("C:\\Users\\user\\Documents\\python\\html\\"+index+"_copy.html")
else:
  html= pathlib.Path("C:\\Users\\user\\Documents\\python\\html\\"+index+".html")

html.touch()

head = "<DOCTYPE html><html lang='ja'><head>"
head += "<meta name='viewport' content='width=device-width,initial-scale=1'>"
head += "<link rel='stylesheet' href='../css/default.css'>"
head += "<title>"+title+"</title>"
head += "</head>"
cssFile= pathlib.Path("C:\\Users\\user\\Documents\\python\\css\\default.css")

with open(cssFile, mode="w") as f:
        f.write("html,body{background:rgb(29,29,29);color:rgb(200,200,200);}table{width:"+sheet1['E5'].value+";height:"+sheet1['F5'].value+";}")

with open(html, mode="w") as f:
        f.write(head)
        f.write("<body>")
        f.write("<h1>"+title+"</h1>")
        f.write("<h2>"+subTitle+"</h2>")
        if table!="":
        	f.write(table)
        else: 
            f.write("")
        f.write("</body>")
        f.write("</html>")
        
webbrowser.open(html)
```
> Python実行すると、入力シートに書いた内容がHTMLに反映され、ブラウザが自動起動し、画面が確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/83c4decc-c188-99ab-52a6-1923b3de77e4.png)
『UI/UX デザインの原則』を読んで学んだこと + 受託開発におけるUI/UX

#この記事について
この記事では、前半、後半に分けて以下のことを書いていきます。

【前半】
『UI/UX デザインの原則』（平石大祐 幻冬社)で学んだこと
【後半】
「受託開発」におけるUI/UX

特に後半は、私の業務経験に基づき、問題点や解決策について書いきます。

#『UI/UX デザインの原則』を読んで学んだこと
## ・UI/UXの違い

まずは前提のおさらい

<b>UI：できていても差別化にはならない、できていないと離脱につながる</b>
<b>UX：競合との差別化、利益につながる</b>

<font color="Red">大前提の「使い勝手」を整えるのがUI</font>

## ・ユーザー視点で考える
本書では、「ユーザー視点」で考えることの必要性を説いています。
しかしながら、WEB担当者とユーザーでは前提が違う。
<font color="Red">ニーズがすれ違う</font>ことに注意しなければなりません。

特に意識すること
・<b>機能の優位性</b>
・<b>機能が認識されない要因を探る（導線にあっているか、視線にあっているか）</b>

## ・サービスの「利用前」、「利用中」、「利用後」に分けて考える

UXを考える際に、３つのフェーズに分けると考えやすいです。

利用前：<b>不安の解消</b>
↓
利用中：<b>行き詰まったときのサポート、スムーズな導線</b>
↓
利用後：<b>結果の確認など</b>

##受託開発におけるUI/UX

ここまでを踏まえて、早速業務に活かそう！
と思っても、すぐにはできない。

なぜなら、自社サービス開発と受託開発では違いがあるからです。

##・問題点
受託開発において、「〜〜の機能を作って欲しい」と依頼された際の問題点を挙げてみます。

####情報不足
必ずしも以下の情報が提供されるわけではない。
・ペルソナ（ユーザーの情報、特徴）
・利用シーン（いつ、どこで、どのように）

####納期
「UI/UXの優れた機能を作ること」が要件に入っているわけではない。
<font color="Red">「UI/UX」より「納期」が優先される</font>ことが多く、トレードオフの関係にある。

####UI/UXが重視されていない
そもそも、先方の担当者がUI/UXを重視していなければ、UI/UXについて意見するのは難しい。
うざがられる可能性がある。

####ユーザーテスト
<b>先方の方針に依存する。</b>
やらないケースもある。
こちらは実装後のフェーズになるので、あまり気にしなくてよいと思う。


##解決策
###納期と情報不足
開発フェーズをざっくり

<b>依頼を受ける→設計→実装</b>

設計フェーズまでに以下をできる限りやる。
・情報収集
・UI,UXの議論（社内、先方と）

実装フェーズ以降は、<b>UIの変更や議論をする余地はない。</b>
なぜなら納期があるから。

###UI/UXの重要性を認識

情報不足を解決しても、すぐにUI/UXが改善されるわけではないと思います。
ですが、重要視し続けることで、好循環が生まれればいいなと思います。

まずは、開発メンバでUI/UXを意識する
↓
先方といい感じの議論をする
↓
先方もUI/UXを意識するようになる
↓
良いサービスが生まれ、先方とも良い関係が築ける

楽観的ですが、、。

##最後に
UI/UXを考慮しながら開発することは重要。
経験値として溜まっていく。
思いつきで書いたため、半年後に見返してアップデートしていきたい。

「受託開発」におけるUI/UXについての情報が見つからなかったので、
情報いただけたら嬉しいです。
クローラー(？)を自作した話

# 何故作ったのか
~~Scrapyの存在を知らなかったから~~

前からダウンローダーとかそういうの作ってみたかったんです
それで調べてみたらサイトのクロールとか面白そうだし、ネット小説をまとめてローカルで見れるように出来たら結構いいんじゃないかと思ったので
あと動けば良しの精神で作ってるので場合によっては誤作動起こすかもしれません……


# インストール
[リポジトリ](https://github.com/mino-38/prop)をpipで指定してインストールします

```bash
$ pip install git+https://github.com/mino-38/prop
```

__追記__
pypiに上げました(名前衝突があったため名前を少し変更)

```bash
$ pip install prop-request
```
# 使い方

[りどみ](https://github.com/mino-38/prop/blob/main/README.md)の方を見て頂ければ大体の使い方は分かると思います

基本、クロールは以下で出来ます

```bash
$ prop -r [再帰回数(省略可)] -o [出力先ディレクトリ] -I [インターバル] URL
```

# 仕様について
- robots.txtの内容は守るようにされてます
- hrefなどの参照先を、ローカルに存在するものはローカルのファイルを指定するように変換します
- クロール以外も一応できます
- 保存ファイルのフォーマットを指定することができます
- 階層ごとにディレクトリは作られず、指定したフォルダに全てダウンロードされます(~~そもそもネット小説で2階層以上ダウンロードすることがない~~)
- 全部英語です(日本語よりは英語で作ったほうがいい気がしたので)

# 作ってみての感想
改めて見ると余計な機能付け過ぎましたね……
requests.getが引数に取る値をとりあえずオプションに追加したって感じです
引数解析部に関してはargparseを使おうか迷ったんですが一部特殊な解析が要るかなと判断したのでゴリ押ししました(おかげでelifが沢山)

あとrequests、BeautifulSoupの偉大さがよ〜〜〜〜〜く分かりました
docker for windows + ubuntu18.04 . git command not found

立てたばかりのubuntu環境でapt-get installしたいときは、まず```apt-get update```が必要だよという話。 

GitHubの楽しそうなコードを動かそうと思って、WindowsPCでDockerのubuntu18.04環境を立てた。
```docker pull ubuntu:18.04
docker run -it --name <container_name> ubuntu:18.04
```


さっそく目当てのリポジトリを、コンテナ内にダウンロードしようと思いgitコマンドを使たところ次のようなエラーが出た。
**bash: git:command not found**

そうだ、git インストールしてないじゃん！
と思いながら、インストールするおなじみのコマンド
```apt-get install git```
を入力すると、以下のエラーが出る。
***Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package git***

あれ、なんでやろ？と思いながら、いろいろサイトを回って、解決策を探すと以下を実行することで無事にgitをインストールすることができた。
```apt-get update```

立てたばかりのubuntu環境だと、パッケージをインストールするために、パッケージリストを一度更新し、パッケージインデックスファイルをダウンロードする必要があるようだ。
これによって、apt-get install諸々を利用できるようになる。

以下の記事を参照しました
>IT資格マニアのエンジニア技術ブログ×英語：
https://chico-shikaku.com/2020/03/docker-ubuntu-git-command-not-found/ 

>君は心理学者なのか？
https://karoten512.hatenablog.com/entry/2018/01/09/003330