OmniAICreator/Qiita-1.07M huggingface dataset:
セレクトボックスのバリデーション

レビューを受けて勉強になったところをメモ。
こんな感じのセレクトボックスをバリデーションする際の書き方。

```
<%= f.select :hoge, [['A',1],['B',2],['C',3]], { include_blank: "選択して下さい" } %>
```



# ダメなパターン
## とりあえずpresence: trueしとく

```ruby

 validates: hoge, presence: true
```
これやりがちだけど、1か2か3だけを許容（ほかの数字や文字列は却下）したいので、これは適切なバリデーションではない。


# 良いパターン

## ① inclusionを使用するバリデーション
Railsガイドより引用
> このヘルパーは、与えられた集合に属性の値が含まれているかどうかを検証します。集合には任意のenumerableオブジェクトが使えます。
inclusionヘルパーには:inオプションがあり、受け付ける値の集合を指定します。:inオプションには:withinというエイリアスもあり、好みに応じてどちらでも使えます。

ということで、配列になっているセレクトボックス[1,2,3]から送られてきた値をチェックするにはこのヘルパーがぴったり。

```ruby

 validates :status, inclusion: { in: [1,2,3] }
```

こんな感じでセレクトボックスの配列と同じように書けばOK。

## ② numericalityを使用するバリデーション
Railsガイドより引用
> このヘルパーは、属性に数値のみが使われていることを検証します。デフォルトでは、整数または浮動小数点にマッチします。これらの冒頭に符号がある場合もマッチします。整数のみにマッチさせたい場合は、:only_integerをtrueにします。

今回は数値のみが使われるのでこのヘルパーでもよさそう。
ただこれだけだと1,2,3以外の数字が送られてきたときに弾くことができない...
そこでオプションをつける。

> :greater_than_or_equal_to: 指定された値と等しいか、それよりも大きくなければならないことを指定します。
:less_than_or_equal_to: 指定された値と等しいか、それよりも小さくなければならないことを指定します。

このふたつを組み合わせて...

```ruby
validates :hoge, numericality: { greater_than_or_equal_to:1 ,less_than_or_equal_to:3 }
```

これでOK。
ただgreater_thanとかless_thanは年齢の範囲指定とか、金額の範囲指定に使うほうが適切。（18歳以上65歳未満とか1000円以上3000円未満とか）
なので①inclusionで実装がベスト。こっちの実装はベター。
.each_with_index(object)について

## each_with_indexとは
eachメソッドの効果に加えて、配列の要素の番号も扱うことができるメソッド。

### 書き方


```
fruits=[“いちご”, “バナナ”, “みかん”]

fruits.each_with_index do |item, i|

puts “#{i}番目の果物は#{item}です。”

end
```

【出力結果】

0番目の要素はいちごです。

1番目の要素はバナナです。

2番目の要素はみかんです。

といった結果になります！


## each.with_indexの違い

each.with_indexを使えば、手軽に0以外の値から開始させることができる。

```

fruits=[“いちご”, “バナナ”, “みかん”]

fruits.each.with_index(10) do |item, i|

puts “#{i}番目の果物は#{item}です。”

end
```

【出力結果】

10番目の要素はいちごです。

11番目の要素はバナナです。

12番目の要素はみかんです。

といった結果になります！

##each_with_objectとは
与えられた任意のオブジェクトと要素をブロックに渡し繰り返し、最初に与えられたオブジェクトを返します。

-例-

```ruby

arr = [1, 2, 3]
result = arr.each_with_object([]) do |item, memo|
  p item # => 1...
  memo << 1
end
pp result # => [1, 1, 1]

result = arr.each_with_object([1, 2, 3]) do |item, memo|
  memo << 1
end
pp result # => [1, 2, 3, 1, 1, 1]

result = arr.each_with_object([]) do |i, a|
  a << i*2
end
pp result # => [2, 4, 6]
```

## まとめ
自動で番号を振り分けてみたい時に使用してみましょう！！
COVID-19　日本の都道府県別感染状況を可視化する

次の図は、新型コロナウイルス(COVID-19)の都道府県別の感染状況を示しています。各都道府県にある円をバブルと呼びますが、このバブルが大きいほど感染者数が多いことを示します。
（データの出典：厚生労働省 都道府県別の患者報告数 2020/4/19）
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/aef7ce08-aa10-80c4-1d61-2078f7e9f37c.png)
ご存じの通り東京都の感染者数が多いため、東京都のバブルは最も大きくなっています。東京都のバブルに隠れてはいますが、関東地方の神奈川県、千葉県、埼玉県のバブルも大きいです。近畿地方では、大阪府、兵庫県のバブルが大きく、他にも福岡県、北海道のバブルが大きくなっています。

以降では別の可視化方法を用い、都道府県別の感染者数を比較してみます。


●面積で比較する
都道府県別の感染者数を**ツリーマップ**で表してみます。

ツリーマップは、多くのカテゴリがあるパターンを調べるときに有効なグラフです。この例でのカテゴリは”都道府県”であり、47個のカテゴリがあります。各カテゴリの長方形の大きさ（面積）が、そのカテゴリの度数を示します。この例での度数は、”感染者数”　です。

以下のツリーマップでは、地方（関東、近畿など）で色分けし、都道府県の位置情報をある程度反映させたものです。
![imsge2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/73f24ace-a5a7-169c-bdbb-f22266c59513.png)

地方別に見ると関東地方（赤色）が全体の半分程度を占めることがわかります。その中でも東京都は半分以上を占めています。次いで近畿地方（緑色）が大きいことや、九州地方の中で福岡県が大きく占めていることなどがわかります。逆に中国地方や四国地方は、全体に対し小さいです。

●大きいところを強調して
パレートの法則という有名な法則をご存じでしょうか。「全体の上位2割で全体の8割を占める」という法則です。たとえばある会社でいくつかの製品を販売しているとき、全体の上位2割の製品で売上の8割を占める。だから、上位2割の製品に力を注ぐ方が良いといった感じです（最近はロングテール理論というものもあり、上位2割以外のものに注視するという考え方もあります）。

上記の感染者数の状況がパレートの法則に従っているかを確認するために、**パレート図**を作成してみます。

パレート図とは、カテゴリの度数が大きい順に割合の棒グラフを描いていき、折れ線で累積割合を示すグラフです。この例では、都道府県別に感染者数が多い順に棒グラフを描いていきます。
![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/3c05879f-7ff6-8f40-4add-9461ef3be627.png)

上記のパレート図で、赤色で示したのが値の大きい上位10都道府県です。東京都、大阪府と続き、最後が京都府ですが、これらの都道府県が上位約2割です( 10 / 47 = 0.213)。上側の折れ線グラフをみると、この10都道府県で全体の約8割( =0.802) を占めており、パレートの法則が成立していることがわかります。

そのため、上位に着目した次のような**棒グラフ**を描いてみます。

上位10位までは値の大きさを棒グラフで示し、上位11位以降は、棒グラフを積み重ねて1つの棒グラフにします。
![image4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/e6a0b764-ae3a-5eac-7df7-138cc95cbb76.png)

上位11位以降は石川県、茨城県・・・と続きますが、これらの度数をすべて足し合わせても、東京都より小さいことがわかります。


今回の可視化に関連する情報は、以下のページで確認することができます。今回分析の対象とした2020/4/19より前の状況も掲載しており、感染者数のほかに、人口1万人あたりの感染者数、死亡者数などのデータの可視化もインタラクティブに行うことができます。

[JMP Public](https://public.jmp.com/packages/COVID-19-%E6%97%A5%E6%9C%AC%E3%81%AE%E9%83%BD%E9%81%93%E5%BA%9C%E7%9C%8C%E5%88%A5%E6%84%9F%E6%9F%93%E7%8A%B6%E6%B3%81%E3%81%AE%E5%8F%AF%E8%A6%96%E5%8C%96/js-p/fCSYFvlpyks42ZGtY2dWf)


ただ私の切なる願いは、感染者数がいなくなり、このようなデータの集計、可視化をしなくて良くなることです。

■	さあ始めよう！
JMPの全機能を30日間試せるトライアル版で、データからさらなる情報を導き出せることを実感してください。
さあ始めましょう。

ダウンロードは[**コチラ！**](https://www.jmp.com/ja_jp/download-jmp-free-trial.html?utm_campaign=td7013Z000002sEGsQAM&utm_source=JMPblog&utm_medium=)

■	JMPについて
JMP（ジャンプ）は世界中のエンジニア、データアナリストに選ばれているインタラクティブで可視的なデータ分析ツールです。

＜ SNSで様々な情報をお届けしています ＞
[**Facebook**](https://www.facebook.com/JMPjpn)
[**Twitter**](https://twitter.com/JMP_Japan)
急にnginxの再起動やコンフィグテストがエラーになった時の対処法

## 本資料の目的
* nginxの再起動を行う際にエラーが発生した。
* 別環境でも発生したことがあるので、対応内容をここに整理する。

## 現象
* nginxの再起動（configチェック含む）でエラーが発生した。
* 原因と対処について、ここに整理する。

## 解決策
### 事象
* nginxの再起動やコンフィグテストを行うとエラーが発生する。

### 原因
* エラーメッセージより、`/var/tmp/nginx`配下のディレクトリが存在しないことが原因。
	* なんらかの原因で削除されてしまう為、ある時起動などできなくなる

```
■Ansible Playbookのエラーメッセージ
TASK [xxx : nginx設定ファイルの文法チェック] **********************************************************
fatal: [xxx]: FAILED! => {"changed": true, "cmd": ["/usr/local/nginx/sbin/nginx", "-t", "-c", "/etc/nginx/nginx.conf"], "delta": "0:00:00.126446", "end": "2020-04-22 12:09:35.651695", "msg": "non-zero return code", "rc": 1, "start": "2020-04-22 12:09:35.525249", "stderr": "nginx: the configuration file /etc/nginx/nginx.conf syntax is ok\nnginx: [emerg] mkdir() \"/var/tmp/nginx/client/\" failed (2: No such file or directory)\nnginx: configuration file /etc/nginx/nginx.conf test failed", "stderr_lines": ["nginx: the configuration file /etc/nginx/nginx.conf syntax is ok", "nginx: [emerg] mkdir() \"/var/tmp/nginx/client/\" failed (2: No such file or directory)", "nginx: configuration file /etc/nginx/nginx.conf test failed"], "stdout": "", "stdout_lines": []}
	to retry, use: --limit @/home/ansible/xxx/xxx.retry
```

### 対策
* 手動で必要なディレクトリを作成する。

```
/var/tmpへ移動する
# cd /var/tmp

nginxディレクトリが存在しない場合、作成する
# mkdir nginx

nginxディレクトリへ移動する
# cd nginx

client / fcgi / proxyディレクトリが存在しない場合、作成する
# mkdir client fcgi proxy

fcgi / proxyディレクトリのパーミッションを変更する
# chmod 700 fcgi/ proxy/

client / fcgi / proxyディレクトリのオーナーを変更する
# chown nginx:root fcgi/ proxy/ client/

以下のような設定になっていれば完了、コンフィグテストを際実行する
[root@xxx nginx]# ls -ltr
合計 12
drwx------ 2 nginx root 4096  4月 22 12:12 2020 proxy
drwx------ 2 nginx root 4096  4月 22 12:12 2020 fcgi
drwxr-xr-x 2 nginx root 4096  4月 22 12:12 2020 client
[root@xxx nginx]#
```
[RSpec]テストコード 基礎知識

# 背景
良いアプリを作成するには良いテストコード をかけることが不可欠だと思ったので少しですが基礎知識をまとめてみました。

## 基礎知識

・specファイルは、対応するクラス名_spec.rb、と命名する。

・describe = 直後のdo ~ endまでのテストのまとまり。後に続く""の中にはそのまとまりの説明を書く。

・itとexample = 実際に動作するテストコードのまとまりを表します。itの後に続く""の中にはそのexampleの説明を書きます。

・エクスペクテーション = 実際に評価される式のことです。it do ~ endの間に書く。

・expect(X).to eq Y=xの部分に入れた式の値がYの部分の値と等しければ、テストが成功となる。

・マッチャ=テストが成功する条件を示すもの。

[例]→eq(等しければ)、include(含んでいれば)、valid(バリデーションされれば)

・変数=FactoryBot.build(クラス名)でテストデータを利用できる

・変数=FactoryBot.create(クラス名)でテストデータを利用でき、仮のDBに値が保存される

・FactoryBot.build(クラス名, 上書きしたい項目: XX)で上書き出来る
AWS S3入門

# はじめに

- AWS S3(Simple Storage Service)とは、安全性と耐久性を持つスケーラブルなオブジェクトストレージインフラストラクチャ。

# AWS S3の無料枠

- 無料枠は以下の内容

>5 GB の標準ストレージ
>20,000 件の Get リクエスト
>2,000 件の Put リクエスト

# バケットの作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89366/6af9c594-0c96-55bb-d249-36e43fc02144.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89366/191ba133-6599-79c5-d3a1-9d964a9df030.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89366/be9c3d98-ad5b-591b-d63e-f4c7052f90b5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89366/5a543c4b-b91e-82bf-f8cc-1632b507aaab.png)

# バケットのホームページ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89366/4396fd57-1e19-b54d-b5f6-2bfea6525381.png)

## フォルダの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89366/6e0fbd33-ee32-2647-e4e4-acb2e53487ea.png)

## ファイルのアップロード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89366/29b2b157-9ed6-c31d-f09f-df4b1aaf8d88.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89366/7b7dd299-83e8-22e5-be15-dae1eec87d7d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89366/49aa2ad4-16a0-dcf1-23a0-937bae4ec802.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89366/e8e6e90d-d770-b3c2-0708-209421c46df8.png)


# Static website hosting

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89366/6b6ebc32-3216-b839-6bca-6a6aa7de57cf.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89366/25c9cf97-41c0-7559-7b80-35994e437645.png)

# おわりに

- AWS S3でも静的サイトをホスト出来る。
サーバー監視においてIPMIからSNMP Trap送信動作確認手順

Supermicroのサーバーを監視する際に、
IPMIの設定からSNMP Trapを飛ばすことが可能。
SNMPマネージャなどが準備できないとき、
SNMP Trap の設定が正しいか、パケットキャプチャリングで中身を確認する手順。


#SNMP Trap の送信先設定
IPMI Web 管理画面より、SNMPTrapの送信先を設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422457/1ed53138-f8cd-97c4-1e63-4f88ff3e744f.png)

AlertNO1にセットされる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422457/5f087311-50fd-2436-fcf2-d1f49177da3e.png)


#受信側パケットキャプチャリング設定

受信側へログインする。(今回は Linux 環境にて tcpdump　を使う)
下記コマンドでキャプチャリング開始。

```
$ sudo tcpdump -n -s 0 -i ens32 -w /tmp/dump.log host (サーバーIPアドレス)
```

#テスト用 SNMP Trap 送信
サーバー側のIPMI Web 画面から [Send Test Alert] にてテストパケットを飛ばす
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422457/5f127c5f-5878-2286-4d39-9de1a19ea779.png)

#受信した SNMPTrap 内容の確認
tcpdump で生成した、dump.log をwireshark にて確認する。
(SNMPバージョンやCommunity名などが確認できる)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422457/3f70cb23-a52e-6630-1694-229dbebd78b6.png)


以上、SNMPManagerなどが準備できないときに、問題なく送信できているか確認することができました。
Ruby on Rails チュートリアル 11日目

##11日目
今日は、チュートリアルの7章を終わらせました。
[リスト 7.38](https://railstutorial.jp/chapters/sign_up?version=5.1#code-procfile)に書かれていることなのですが、Heroku上でPumaのプロセスを走らせる設定ファイルの作成についてかなり解けるようになるまで時間がかかりました

```
vi Procfile
```
で開いて、

```
web: bundle exec puma -C config/puma.rb
```
を書くまでは良かったのですが

```
:wq
```
を適当に書けばいいということに気づけませんでした。
これでmacのターミナルについても少しだけ使い方がわかりました

明日はチュートリアルの8章をやっていきます
Nuxt async fetch async data で URLパラメータをもらう

# やりたいこと
- URLパラメータをもらう

よし！行ってみよう！

# URLパラメータをもらう
公式のパラメータ説明はこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166346/b5ed660e-8075-a00c-5624-ab1fcfceb51a.png)
よくわからん！

# 呼び出し方
```
const id = "01"
const piyopiyoId = "11"
this.$router.replace("/hogehoge/" + id + "?piyopiyoId=" + piyopiyoId)
```

#受取方
```
async fetch({params, query}) {

    console.log(query.piyopiyoId)
    console.log(params.id)
    
},
```
paramsは、_id.vueで指定したパラメータを取得可能。
queryは、getパラメータで指定したパラメータを取得可能。

#ちなみに、、、、これでも行ける
```
async fetch(context) {

    console.log(context.query.piyopiyoId)
    console.log(context.params.id)
    
},
```
公式の説明は、パラメータの指定方法をcontext経由にするかしないかの違いだったんですね。
contenteditableな要素へのペースト時にスタイルを削除する方法

contenteditableの不便なところが、ペーストされたテキストにコピー元のスタイルが保持されていること。

なので、ペースト時にスタイルを削除する方法。

```js
document.querySelector('div[contenteditable="true"]').addEventListener("paste", function(e) {
    e.preventDefault();
    var text = e.clipboardData.getData("text/plain");
    document.execCommand("insertHTML", false, text);
});
```

いろいろと方法が出てくるが、このスクリプトがたぶん最適解。
https://stackoverflow.com/questions/6899659/remove-formatting-from-a-contenteditable-div
Elastic Beanstalkのメモ

枯れた技術で極力運用の負荷を減らしたいので調べている。随時更新。

beanstalk固有の方法みたいなものの学習コストは嫌気するが同等のものを揃えるのもそれなりに手間暇かかる感じ

ECS使おうか迷う所だがプロダクション環境でコンテナ頑張る必要ない場合は無理しない勢

# ebコマンドのインストール
- [aws公式](https://github.com/aws/aws-elastic-beanstalk-cli-setup)のレポジトリをクローンしてインストールする
  - 書いてある通りにコマンドを打つだけでインストール完了する(トラブルシュートの方法も丁寧に書いてある)
  - インストーラーはpyenvを使い、~/.ebcli-virtual-envにインストールしてくれる。インストール後は.bashrcや.zshrcなりにaliasでパスを通したりする必要はあるかも。(注意書きがインストール後に表示される)
  - `$ source ~/.ebcli-virtual-env/bin/activate`でebコマンドが使えるようになる。(executableにpathを通せばいちいちsourceする必要はない)
  - IAMでポリシー作る場合は[公式のJSON](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/concepts-roles-user.html)がある

# メモ
## コマンドとかメモとか
- `eb init` でアプリの作成
- `eb create` でenvironmentの作成
- `eb platform` はplatform作成に使う。ec2が起動してその中でpackerが動いてイメージを作成してくれる

## workspace_type
少なくともApplicationとPlatformがある。前者はサーバーで動作するアプリケーションのgit プロジェクトと思えばよい。後者はPlatformを作成するgitプロジェクト(要はpacker用のプロジェクト)と考えて差し支えないと思う。

## ドットディレクトリや各種ファイル
- .platform/hooks
  - platform hookを入れておくディレクトリ
  - prebuild, predeploy, postdeployファイル等に記述してplatform拡張できる
- Buildfile, Procfile
  - アプリケーションのルートディレクトリに配置する
  - Buildfileは短期実行されるコマンドを記述
  - Procfileは長期実行されるコマンドを記述
- .ebextensions
  - このディレクトリ以下に.configのsuffixを持ったyamlを設置するとawsリソースをカスタムできる
- platform.yaml
    - カスタムプラットフォーム定義のファイル。アプリのルートディレクトリに設置
    - packerを使ってvmがaws内に構築される
    - workspace_type=Platformの時に必要になる。

## インスタンスデプロイのワークフロー
https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/platforms-linux-extend.html

- secrets-managerに環境変数を寄せている場合は `eb create` で作成されるrole `aws-elasticbeanstalk-ec2-role` に適宜policyを付与した
- .ebextensions/*.configに色々とアップするfileやらコマンドやらを書ける。設定の公式docは[ここ](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/customize-containers-ec2.html)
  - vmに一応sshでアクセスしたい場合はメンバー分の公開鍵を入れておくとか
  - secrets-managerから環境変数を取得してファイルでばら撒きたい場合のコマンド記述とか

## カスタムプラットフォームの作成

[公式のサンプル](https://github.com/aws-samples/eb-custom-platforms-samples)

## dockerプラットフォームに関して
beanstalkでdocker使う場合、単一コンテナと複数コンテナを扱う環境を選択できる。
単一の場合は単にec2上でdocker起動させてコンテナを一つ動かすというもので、サイドカーもできないっぽい。logとかはbeanstalkのお作法に従って出力とかになる。

複数の場合はecsクラスタが起動する。ecsにbeanstalkをかぶせるメリットがあるのか疑問。素直にecs使った方が良いような。

# コマンド実行
environment構築後に修正できる設定とできない設定とがある。vpcやSecurityGroupは修正できないのでcreateする時にオプションつけて実行する。

- `$ eb init app_name --profile mine` でapplicationを作成
    - 手元に `.elasticbeanstalk/config.yml` が生成される
    - .gitignoreで除外設定されている
- `$ eb create app-env-blue` でアプリの稼働環境を作成(自分の都合でGo言語を使う)
    - platformは`-p go`を直接指定しないと後述のconfigアップロードで失敗する
    - platform名のvalidationがebコマンドとbotoの間で齟齬を起こしている様子
    - eb createができた後に打てるeb platform listで確認できるkeyを使う
- `$ eb config save app-env-blue` でapp-env-blue環境のconfigをfetchする
    - `.elasticbeanstalk/saved_configs/hello-go-env-blue.cfg.yml`としてダウンロードされている
    - .gitignoreによりcommit対象から除外されている
    - 適宜修正してputコマンドでアップロードする
- `$ eb terminate app-env-blue` で該当環境を削除できる。ELBやEC2等の関連リソースも一括削除してくれる
UWP や MSIX をコマンドラインやビルド パイプラインからビルドするときに指定するオプションのドキュメント

いつも探してしまうのでメモ。

下のドキュメントにまとまってる。
https://docs.microsoft.com/ja-jp/windows/uwp/packaging/auto-build-package-uwp-apps
【Nginx】ドキュメントルートを変更したい

ここでは仮に、ドキュメントルートを `/home/test/` に変更したいとします。
# 設定ファイルをいじる

###テキストエディタ(vi)でnginx設定ファイルを開き、該当箇所を編集###

```
$ sudo vi /etc/nginx/nginx.conf
```

```nginx.conf
# こんな記述箇所があるはず
server {
　 listen       80 default_server; # 触らない
　 listen       [::]:80 default_server; # 触らない
　 server_name  _; # 触らない
　 # root         /usr/share/nginx/html;　# これデフォルト ※とりあえずコメントアウトしておく
　 root           /home/test;        # こんな感じで任意のディレクトリを指定                                                                  
　 # Load configuration files for the default server block.
　 include /etc/nginx/default.d/*.conf; # 触らない

　 location / {
　　 # ここも関係ない
　 }
   ...
}
```

###変更したら保存して設定ファイルを閉じてnginxを再起動###

```
$ sudo service nginx restart
```

###そして、該当ページにブラウザからアクセスしてみると…###

>403 Forbidden

###え！？###

ってなりますよね、でも大丈夫。**落ち着いてください**。
もう一つ**やらなきゃいけないこと**があるんです。

# 該当ディレクトリにアクセス権限を与える

###ディレクトリのパーミッションを変更することで実行権限を与えます###

```
$ chmod +x /home/test
```

これで無事アクセスできるはずです。

今度はうまくいったでしょう？
herokuのデプロイ方法

# 背景
herokuを使ってデプロイする方法は簡単かつ早いためとても便利です。
これさえ見ればデプロイできるという流れをまとめる記事を備忘録も兼ねて作成しました！


## 手順



※始めてアプリをデプロイするときにすること※

0.herokuCLIをインストールする

```ruby
$ brew tap heroku/brew && brew install heroku
```

1.herokuにログインする

```
$ heroku login
```

2.Gemfileを以下のように編集する
※sqlite3(mysql)は場所を移動させる。pgは新たに追加する。

```ruby

group :development do
  gem 'sqlite3(mysql)'
end

group :production do
  gem 'pg'
end

# 本番環境に適したパッケージに変更する
```

3.productionの中以外をアップデートする

```
$ bundle --without production
```

4.アプリをgitの管理下に置く

```
$ git init
```

5.heroku上にアプリを作成する。(アプリ名は被らないような名前)

```
heroku create アプリ名
```

※再デプロイするときはここから実行※

6.全てのフォルダやファイルを管理対象にすることを明示する、

```
$ git add .
```

7.現在の状態をコメント付きで保存する

```
$ git commit -m “initial commit”
```

8.現在の状態をherokuに送信する。

```
$ git push heroku master
```

9.Heroku上にデータベース作成する。

```
$ heroku run rails db:migrate
```

10.seeds.rbの情報をherokuに渡す。（seeds.rbに記述している場合は実行する。）

```
$ heroku run rails db:seed
```

11.アプリを開く

```
$ heroku open
```
mysql を使う時の備忘録

## 概要
色々なデータベースに触れる機会があったが、結局MySQLに関しても知識が浅かったので
備忘録として役に立ったことを書いていく。随時更新していく。


## 記録

- mysqlが起動しているかのチェック　(Mac)

```
$ mysql.server status
```

- mysqlを起動させる　(Mac)

```
$ mysql.server start
```

- テーブルのコメントを確認する

```
show table status like '<tablename>';
```

- テーブルのカラムのコメントを確認する

```
show full columns from <tablename>;
```

### check character code

```sql
show variables like "chara%";
```

### change character code for DB

```sql


ALTER DATABASE {DB名} CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
```

### check table size (in kilo byte)

```sql

SELECT  
    table_name, engine, table_rows AS tbl_rows,
    avg_row_length AS rlen,  
    floor((data_length+index_length)/1024) AS allkb,  #総容量
    floor((data_length)/1024) AS dkb,  #データ容量
    floor((index_length)/1024) AS ikb   #インデックス容量
FROM 
    information_schema.tables  
WHERE
    table_schema=database()  
ORDER BY
    (data_length+index_length) DESC;  

```

### check table size (in mega byte)

```sql

SELECT  
    table_name, engine, table_rows AS tbl_rows,
    avg_row_length AS rlen,  
    floor((data_length+index_length)/1024/1024) AS allmb,  #総容量
    floor((data_length)/1024/1024) AS dmb,  #データ容量
    floor((index_length)/1024/1024) AS imb   #インデックス容量
FROM 
    information_schema.tables  
WHERE
    table_schema=database()  
ORDER BY
    (data_length+index_length) DESC;  

```





### check database size　(in kilo byte)

```sql
SELECT 
    table_schema, sum(data_length) /1024 AS kb 
FROM 
    information_schema.tables  
GROUP BY 
    table_schema 
ORDER BY       
    sum(data_length+index_length) DESC;

```

### check database size　(in mega byte)

```sql
SELECT 
    table_schema, sum(data_length) /1024/1024 AS mb 
FROM 
    information_schema.tables  
GROUP BY 
    table_schema 
ORDER BY       
    sum(data_length+index_length) DESC;

```
Amazon S3の基礎概念

# S3のデータ構造

- 一般的なデータ構造
    - データをファイル単位で格納し、フォルダという階層構造を持つ。
- S3のデータ構造
    - 単純なKVS(Key-Value型データストア)
    - hoge/foo.txtがあった場合、S3では以下のようにデータを認識する

| キー(フルパス名)  | バリュー(ファイルの内容) |
|:-----------------|:----------------------|
| hoge/            | (空)                  |
| hoge/foo.txt     | contents              |


# S3における空フォルダ

- 既存の空フォルダの中にファイルを配置すると、S3上では2要素管理される。

| キー(フルパス名)  | バリュー(ファイルの内容) |
|:-----------------|:----------------------|
| hoge/            | (空)                  |
| hoge/foo.txt     | contents              |

- 存在しないフォルダに直接ファイルを配置すると、S3上では1要素管理される。
- ※管理コンソールからfoo.txtを消すと、hoge/が要素として認識される

| キー(フルパス名)  | バリュー(ファイルの内容) |
|:-----------------|:----------------------|
| hoge/foo.txt     | contents              |

# S3コマンドの形式

```
aws s3 <Command> [<Arg> ...]
```

- ローカルのパス:[ローカルファイルまたはディレクトリの絶対パスまたは相対パス]
- S3のパス:[s3://\<bucket>/\<prefix>/\<object>]
- prefixはディレクトリやフォルダと思えばよい

## ファイルのアップロード

```
aws s3 cp ./sampledata.txt s3://sample-bucket-**********/dir/
```
- コピー先の末尾がスラッシュで終わる
    - コピー元と同名でファイルをコピー
- コピー先の末尾がスラッシュで終わらない
    - **末尾の文字列に拡張子が無くディレクトリ名のように見えても、ファイル名として認識される**

# 引用
https://www.task-notes.com/entry/20150904/1441335600
https://qiita.com/nakazax/items/b62309884a19d71f9a34#ls---%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E3%83%AA%E3%82%B9%E3%83%88
https://dev.classmethod.jp/articles/amazon-s3-folders/
[Rails]モデルに関するよく使うコマンド集

# 背景
モデルのコマンドはよく使うため備忘録として書き残す。


## モデルのよく使うコマンド


```ruby

$ rails g model モデル名　カラム名:型
# モデルの作成コマンド

$ rails d model モデル名
# モデルの削除コマンド

$ rails g migration add_カラム名_to_テーブル名 カラム名:型
# カラムの追加コマンド

$ rails g migration remove_カラム名_from_テーブル名 カラム名:型
# カラムの削除コマンド

$ rails db:migrate
# マイグレーション実行コマンド

$ rails db:rollback
# 直近のマイグレーションファイルを実行前に戻す

$ rails db:rollback STEP=○
# 任意の数だけ前のマイグレーションファイルを実行前に戻す

```
C#&Unityの演習問題：しまづ君にプログラミングを教えよう！超演習問題編【スタジオしまづアカデミア】

#サロン会員が取り組んだ演習問題

##Q.硬貨の組み合わせが何通りあるのか
＊両替機の概要
・1000円を入れると「10円、50円、100円、500円」の4種類に両替できるを開発したい
・ただし15枚以内
この場合の、両替する硬貨の組み合わせは何通り？

例：500円と100円だけなら{500円x2,500円+100円x5}の2通り


##つづき
- スタジオしまづの[YouTube](https://www.youtube.com/channel/UCDunz_CPkqkQT5ljKXcYkhg?view_as=subscriber)：チャンネル登録お願いします！
- スタジオしまづの[公式サイト](https://fromalgorithm.jimdofree.com)
Monorepo でパッケージ名をコミットメッセージに入れるツールをつくった

# 背景

最近 Monorepo を試しているのですが、いくつか既存のツールではやりにくい部分があったので、自分で作っています。今回紹介するのはその一つで、Git で Monorepo 用のコミットメッセージを書くツールです

## Monorepo のコミットメッセージ辛い問題

Monorepo では全体を同じリポジトリで見られるのは便利なのですが、コミットメッセージを適当に書いてしまうと、どれに対する変更なのかがわかりづらくなります。

これについては、例えば `[mypackage] Add hogehoge` という感じで対応することが多いと思いますが、これを手動で打つのは面倒です

# つくったもの

https://github.com/team-pianoforte/git-pianoforte

コミットの内容から変更対象のパッケージ名を検出し、自動で `[mypackage]` と入力してくれます。

## 使い方

Golang で作られているので、`go get git@github.com:team-pianoforte/git-pianoforte` でインストールしてください。

その後、使用するリポジトリで `git pianoforte install` することで機能が有効になります

デフォルトでは、`packages`以下のディレクトリをパッケージとして認識します

## 仕組み

単純に、コミット対象のファイルの共通祖先を取り出しています。
[Rails]Webアプリケーション開発の流れ

# 背景
アプリケーションを作成する際に何をすればいいか分からないという人に流れをまとめました。

## Railsを使ったWebアプリケーション開発の大まかな手順

1.企画
2.設計
3.開発
4.公開

以上の流れに沿って開発していきます！

## Railsを使ったWebアプリケーション開発の具体的な手順

####1.必要な機能の洗い出し
そのアプリにはどのような機能が必要になるかを洗い出します。

[例]メモアプリ
・一覧表示機能
・新規作成機能
・編集、削除機能
・カテゴリ機能

####2.必要な画面の設計
アプリに必要な画面の設計をします。画面がどれだけ必要か、どのような画面にするかを考えます。

[例]メモアプリ
・メモ一覧ページ
・メモ新規作成ページ
・メモ編集ページ
・カテゴリ別ページ


####3.データベースの設計
アプリのDB設計を行います。どのようなテーブルが必要で、それぞれのテーブルがどのようなカラムが必要かを決めます。

[例]メモアプリ
・memosテーブル(titleカラム、contentカラム、category_idカラム)
・categoriesテーブル(nameカラム)

####4.Railsでアプリケーションの雛形を作成
rails newコマンドを利用して開発するアプリを作成し、ローカル環境で動作するように初期化を行う。

[例]メモアプリ

```
$ rails new memo-app
```

####5.大きな機能から順に実装
実装は、アプリケーションのメイン機能のような大きな機能から実装していく。

[例]メモアプリ
メモ新規作成機能→メモ一覧表示機能→カテゴリ機能のように実装する。

####6.テストコードを記述し動作を担保する
実際にアプリが正常に動くかを確認する。テストコードを書いてプログラムに動作確認をしてもらいます。

####7.リファクタリングによりソースコードを整理する
第三者がソースコードを理解しやすくなる、あとでプログラムを修正がしやすくなるといったメリットがあります。

####8.外部のサーバにサービスをアップして公開する



ここまで完了すればアプリ制作終了です！
[AWS]基礎知識編

# 背景
AWSでよく出てくる用語やコマンドをまとめてみました。


## 基礎知識

### 用語

AMI = OSの情報やディレクトリ、ファイル、ブロックデバイスマッピングなどインスタンス作成に必要な情報を一通りまとめたもの（インスタンスはAMIのコピー）
    
キーペア = 公開鍵（パブリックキー）暗号における公開鍵（パブリックキー）と秘密鍵（プライベートキー）のペア

Elastic IP = サーバーを再起動しても同じIPアドレスを割り当てることができる性質を持つIP

ポート = 1つのサーバと複数のサーバをつなぐもの

セキュリティグループ = Amazon EC2インスタンスに適用可能なAWS標準のファイアウォール機能。EC2インスタンスへのアクセスを"許可"したり、トラフィックを"制御"することができるもの。
           
SSH = 暗号や認証の技術を利用して、安全にリモートコンピュータと通信するためのプロトコルのこと。離れた場所にあるサーバの中で作業を行いたい場合に利用する。
   
yumコマンド = Linuxにおけるソフトウェア管理の仕組み。MacOSにとってのhomebrewと同じ役割を果たします。yumの管理下にあるプログラムのバージョンを管理したり、一括でアップデートしたりできます。
    
パッケージ = LinuxOS下における、ある役割/機能をもったプログラムの集合

Node.js = サーバーサイドで動くJavaScriptのパッケージ。今後のデプロイに向けた作業の中で、CSSや画像を圧縮する際に活用される。

rbenv = Rubyのバージョンを簡単に切り替えてくれるツール。

ruby-build = rubyをインストールするためによく使われているrbenvのプラグイン。(rbenvとセット)

.bash_profile = ログインシェルがbashの状態でログインしたときに読み込まれる設定ファイル

rbenv rehash = インストールしたRubyを使用可能な状態にする(shimsへの反映)

Unicorn = 全世界に公開されるサーバ上で良く利用されるアプリケーションサーバ。

プロセス = PC(サーバ)上で動く全てのプログラムの実行時の単位。

worker = 分裂したプロセス全て

worker_processes = リクエストを受け付けレスポンスを生成するworker(ワーカー)の数。

working_directory = UnicornがRailsのコードを動かす際、ルーティングなど実際に参照するファイルを探すディレクトリを指定。

pid = 起動する際にプロセスidが書かれたファイルを生成します。その場所を指定する。

listen = どのポート番号のリクエストを受け付けることにするかを決めるもの

sudo = コンピュータさんに対するコマンドのひとつ。スーパーユーザ（や他のユーザ）の権限でコマンドを実行するときに使うコマンド。

Swap領域 = メモリが使い切られそうになった時にメモリの容量を一時的に増やすために準備されるファイル。

環境変数 = Railsからは ENV['<環境変数名>'] という記述でその値を利用することができる。コンピュータが持っている、値を入れておく箱（変数）。

secret_key_base = Cookieの暗号化に用いられる文字列です。Railsアプリケーションを動作させる際は必ず用意する。

vimコマンド = 高機能エディタ。コマンドでターミナルで使えるようになる。

アセットファイル = 画像・CSS・JSファイルの総称

PID = それぞれのプロセスに割り当てられた管理用の番号のこと

Capfile = Capistrano関連のライブラリのうちどれを読み込むかを指定できる。

DSL = ある特定の処理における効率をあげるために特化した形の文法を擬似的に用意したプログラム。

releasesディレクトリ = capistranoを通じてデプロイされたアプリをひとまとめにするファイル。

currentディレクトリ = current内に入っているアプリの内容が、現在デプロイされている内容

sharedディレクトリ = バージョンが変わっても共通で参照されるディレクトリが格納されるディレクトリ


###よく使うコマンド

```ruby

$ vim ~/.bash_profile                          # 環境変数書き込み

$ source ~/.bash_profile                       # 環境変数適用
 
$ sudo service mysqld status                   # 状態を確認する

$ sudo service mysqld start                    # 起動コマンド

$ mysql -u root -p　　　                        # PW入力してMySQLへ接続する

$ ps auxwww | grep unicorn                     # 状態を確認する 

$ kill -9 〇〇　　　                             # プロセス強制終了 

$ cat log/unicorn.stderr.log　　　              # ユニコーンのログを見れる

$ sudo service nginx restart                   # nginx再起動

$ sudo less /var/log/nginx/error.log　　　      # nginxのログを見れる

$ bundle exec cap production deploy　　　       # 自動デプロイ

$ less log/capistrano.log 　　　                # capistranoのログを見れる
```
リモートワークで困ったら、Azure DevOps タスクにメンションつけて相談するといい

スクラムのチームは全員が同じ場所にいることが推奨（だったと思います、[Scrum.org の Scrum Guide](https://www.scrumguides.org/scrum-guide.html) には書いてないかも）ですが、そうも言っていられない状況。しかし、リモートワークでスクラムをする場合には、かなり頑張って、メンバーが密にコミュニケーションできるように準備する必要があります。

そのための工夫のひとつとして Azure DevOps のタスクのメンションを使うのが良い感じです。

![Azure DevOps タスク画面の様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474869/2c952964-7b57-eeea-65c1-ab562b1ac6e4.png)


## タスクの Discussion のメンションを活用

Azure DevOps のタスクには、タスクの内容を詳細に書ける「Description」とそれについてメンバーで話し合える「Discussion」のフィールドがあります。使い分けとしては、Description は最新に更新していく。Discussion はそのための確認の会話や、あるいは自分のための作業の備忘録という感じに使えます。

どちらもテキストやリンク、箇条書きなどのある程度の書式の指定、画像の貼り付けなどができるので、自分でタスクの作業をしながら、新たに明確になったことがあったり、逆に不明確で悩んだことがあったりした時に、すぐに書き込むのに使い勝手が良いです。

特に画像が貼れるので（Windowsなら Ctrl+V が可能）、エラー画面や選択に迷ったオプション画面など、文字を手打ちする必要なしにキャプチャをさっと貼っておいて、メモを取りながら作業を進められます。本当に困ったら、そのままそこまでのキャプチャやメモを見てもらえるように、他のメンバーに相談することができるのです。

![メンションでこれまで張り付けた画像を見せて相談できる様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474869/00209a39-d2d3-277d-a0fa-c3f2bb2baa89.png)



Discussion で @ユーザー名 を入力すると、いわゆるメンションができます。はじめに @を入力するだけでユーザー名を検索できるので簡単に開始でき、返信の時は自動的に相手の名前が入っています。

メンションはタスクを保存すると相手に通知され、相手はメールのURLからこのタスクを直接開けるので、すぐに Discussion に書き込むことができます。サイトにログインできるならPCに向かっていなくてもメモや画像の確認と返事ができます。

リモートワークでメンバーがそれぞれ別々の場所・時間で作業していても、きっと良いタイミングで返事を返してもらえるでしょう。同じ場所でリアルタイムで一緒に作業できるコミュニケーションにはかないませんが、かなり良いコミュニケーションが出来ると思います。ちょっと離席して、戻ってみると返事が書き込まれているのをみると、あぁ、ちゃんと一緒に仕事しているな、とちょっと安心します。

## メール・Teams・Slack の会話ではなくタスクを使う意味

リモートワークでは、メールや Teams・Slackなどのチャットやビデオ会議・音声会話など、さまざまな会話の手段が利用できます。

しかし、それらはそれぞれ「人と人」やチャンネル・会議など、タスクとは別の粒度に関連付けられていて、直接的なタスクの内容からは切り離されているため、会話の瞬間は役に立ちますが、後からわからなくなることが多いと思います。

ちょうど、ひと昔前には「メールの返信」を使わないで、「なんでも電話をかける」コミュニケーションはちょっとやりづらいなと感じたはずです。それにとても似ています。例えば、最後に話題に上がった内容には返事がもらえたけど、その直前の重要な質問の会話はすっかり忘れられていた、なんてこともよくあります。電話と違ってチャットなどにはデータがしっかり残っていますが、なんでも検索して確認するのが便利とは必ずしも言えないでしょう。これらはあくまで、会話として流れていく、長期的に残らないの情報と割り切ることも重要です。

対して、Azure DevOps のタスクの会話なら、それぞれタスクの内容と関連付けられているので、それぞれ最後まで会話が完了したかどうか、しっかり把握できます。そして、いつまでもタスクに残り続けるので、タスクの完了後にも、そのタスクとソースコード、ビルドパイプラインとビルド結果、テストとテスト結果、リリース（デプロイ）と、その後のバグまで全て関連付けられて残っていきます（それでいて、タスクを開きなおすまで見えないのもノイズにならなくてよいですね）。いわゆる「トレーサビリティ」がちゃんと保証されている。これはチームを作るマネージャとしてはとてもありがたい。

もちろん、それを「ガチガチに管理されている」とメンバーが感じてしまうと、使うのはちょっとツライかもしれませんが。うまく使いこなすことができれば、ここに当時の会話が残っているおかげで、トラブルが少なくなって効率もよくなり、かえって気持ちが楽になる、ということはありますよね。
[AWS]デプロイ時エラーの解決編

# 背景
デプロイ時のエラーはかなり起きるもの。(もしかしたら自分だけかもしれませんが、、)
そういう時の見るべきポイントを書き出してみました。

## エラー発生時の見るべきポイント

####Railsが起動されない時

・pushのし忘れ、またはEC2サーバ側でのpullのし忘れは無いか

・EC2サーバ側で、/var/www/<リポジトリ名>/log/unicorn.stderr.logをlessまたはcatコマンドで確認し、エラーが出ていないか確認する（下に行くほど最新のログです。時刻表記がUTCであることに注意してください）

・ローカルでの編集のpushやEC2でのgit pullを忘れていないか

・前カリキュラムで実施した、mysqlの起動は正しく行えているか

・EC2サーバ側のSECRET_KEY_BASE等は正しく設定できているか

・EC2インスタンスの再起動を行ってみる



####手動デプロイ後にIPアドレスにアクセスできない時

・502 but gatewayとエラーが出る場合は、nginxのlogの確認が必要になります。
(/var/log/nginx/error.logをlessまたはcatコマンドで確認する。)

・サーバ側で、/var/www/<レポジトリ名>/log/unicorn.stderr.logをlessまたはcatコマンドで確認し、エラーが出ていないか確認する
（下に行くほど最新のログです。時刻表記がUTCであることに注意してください）

・Railsを起動しているか

・EC2インスタンスの再起動を行ってみる(※本番環境にてmysqlとnginxの起動が必要。)



####自動デプロイ時にエラーが起きた時

・そのままもう一度同じコマンドを実行してみる。特に、bundle installのタスクの際に、初めて自動デプロイを実行する場合は、メモリ不足で落ちることがあります

・記述ミスが無いか

・特に、本カリキュラムにおいて、修正したファイルに注目して確認しましょう

・手順を飛ばしていないか

・bundle installなどのコマンド実行を忘れていないか確認しましょう




#### 自動デプロイ後にIPアドレスにアクセスできない時

・ローカル側（localhost3000）においてエラーが出ていないか

・サーバー側で、/var/www/<レポジトリ名>/current/log/unicorn.stderr.logをlessまたはcatコマンドで確認しエラーが出ていないか確認する
（下に行くほど最新のログです。時刻表記がUTCであることに注意してください）

・ローカルでの編集のpushやpullを忘れていないか

・サーバー側のmysqlやnginxの再起動を行ってみる

・EC2インスタンスの再起動を行ってみる(※本番環境にてmysqlとnginxの起動も必要です。)
django データ投入 dumpdata loaddata

参考
https://docs.djangoproject.com/ja/3.0/ref/django-admin/

# アプリケーション直下にfixturesディレクトリつくる

```
mysite
  ├ mysite
  │   ├ settings.py
  └ polls
      ├ admin.py
      └ fixtures ←ここにつくる
```

# デフォルトはjson形式

### データベース→ファイル

```console
python manage.py dumpdata polls > polls/fixtures/data.json
```

#### 特定のmodelだけの場合

```console
python manage.py dumpdata polls.Question > polls/fixtures/Question.json
```

### ファイル→データベース

```console
python manage.py loaddata polls/fixtures/data.json
```

# 私はyamlが見やすい

yaml形式使うなら```PyYAML```が必要なので入れること。

```console
pip install PyYAML
```

### データベース→ファイル

```console
python manage.py dumpdata --format=yaml polls > polls/fixtures/data.yaml
```

### ファイル→データベース

```console
python manage.py loaddata --format=yaml polls/fixtures/data.yaml
```
input,output関数を配列っぽい書き方にする

#概要
前回の記事にご指摘があり、配列っぽい書き方に直しました。
#書き換える前
前回、以下のコードに対して

```C
#include<stdio.h>

struct birthday
{
    /* data */
    char name[20];
    int year;
};

void input(struct birthday *);
void output(struct birthday *);

/*main function*/
int main(){
    struct birthday p[3]; /*重要*/
    input(p);
    output(p);
    return 0;
}

/*input function*/
void input (struct birthday *man)
{
    int i;
    printf("【入力】\n");
    for ( i = 0; i < 3; i++)
    {
        /* code */
        scanf("%s", man->name);
        scanf("%d", &man->year);
        man++;
    }
}

/*output function*/
void output(struct birthday *man)
{
    int i;
    printf("【出力】\n");
    for ( i = 0; i < 3; i++)
    {
        /* code */
        printf("%-8s", man->name);
        printf("%5d \n", man->year);
        man++;
    }
}
```
「`man++`がポインタっぽい」とぼやいたところ

```C
void input(Birthday man[3]){
    for ( int i = 0; i < 3; i++)
    {
        /* code */
        scanf("%s\n ", man[i].name);
        scanf("%d %d %d", &man[i].year, &man[i].month, &man[i].day); 
    }
}

void output(const Birthday man[3]){
    for ( int i = 0; i < 3; i++)
    {
        /* code */
        printf("%-8s ", man[i].name);
        printf("%5d %2d %2d \n", man[i].year, man[i].month, man[i].day); 
    }
}
```
のように配列っぽく書いたらどうですか、とコメントがありました。ありがとうございました。
#書き換えた後
数日たって復習のためにと以下のように書いたわけですが

```C
#include<stdio.h>

typedef struct birthday
{
    /* data */
    char name[20];
    int year;
}Birthday;

void input(Birthday *x);
void output(Birthday *y);

/*main function*/
int main(void)
{
    Birthday man[3];
    input(man);
    output(man);
    return 0;
}

/*input function*/
void input(Birthday *man)
{
    int i;
    printf("【入力】\n");
    for ( i = 0; i < 3; i++)
    {
        /* code */
        scanf("%s", man[i].name);
        scanf("%d", &man[i].year);   
    }
}

/*output function*/
void output(Birthday *man)
{
    int i;
    printf("【出力】\n");
    for ( i = 0; i < 3; i++)
    {
        /* code */
        printf("%-8s", man[i].name);
        printf("%5d \n", man[i].year);
    }
}
```
後から`input`と`output`の引数をポインタを使って書いているのに気づき,配列の扱いにまだ慣れていないんだなと思いました。
#結果の例

```C
【入力】
yuga
1997
yuta
1998
huta
1996
【出力】
yuga     1997
yuta     1998
huta     1996
```

#感想
・`main`の中の`Birthday man[3]`を`Birthday man`と宣言しないこと。
VS2017で出力DLLのサイズが小さくなった



Windows10のVisual studioでDLLを開発しています。
今まで、VS2015で開発していたのですが、VS2017にバージョンアップしました。

すると、VS2015で作成していたものは、正常に動作していたDLLが、VS2017に移植したDLLが動作しなくなりました。
その原因が分からないのですが、
VS2015で作成していたDLLのサイズはDebug版で12MBありました。
ところが、VS2017で作成したDLLのサイズが2MBしかありません。

この為に、動作しなくなったと考えられるのですが、
VS2017でDLLがうまくリンクされていなくて、サイズが極端に小さくなってしまったのだと思います。

サイズが小さくなってしまった原因として考えられることは、
何があるでしょうか？

DependencyWalkerで調べてみたのですが
API-MS-WIN-CORE-APIQUERY-L1-1-0.DLL
などの、API-MS-WIN-COREｘｘｘｘｘのファイルが見つからない
というエラーが出ていました。
どこか、プロジェクトの設定の問題でしょうか？ 

以上。ご教授下さい。
clusterで撮影した写真を一括ダウンロードする

先日clusterというサービスを使ってVRで勉強会に参加してきました。リモート勉強会なのに写真撮影ができるって楽しいですね。イベントの場に来ている という感じがします。

さて、このcluster、「UI部品を非表示にして写真撮影を行う」という機能がついています。ただし、この写真はcluster上のインベントリに保存され、ローカルにダウンロードするには、Web画面からダウンロード操作を行う必要があります。

2020/04/23現在clusterの写真は「チェックした項目をすべてダウンロード」ということはできるんですが、「すべての写真にチェックを入れる」ということはできません。今回わたしは64枚の写真を撮影したので、これらを全部ダウンロードするのは疲れます。

# そこでJavaScriptですよ

そこでJavaScriptです。最近のブラウザでは開発者コンソールでJavaScriptが利用できるので、それを使ってクリック操作を自動化させます。

clusterの場合、一個でもチェックが入っている項目がないとチェックボックス自体が表示されないので・・・。
![2020-04-23_12h21_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14499/3aa514bc-a042-0a48-a2c1-ba35a3da9a00.png)
どの写真でもいいのでひとつ、チェックを入れます。

そして、開発者コンソールを表示して、次のコードを入力します。

```js
Array.from(document.getElementsByClassName("MuiCheckbox-root")).forEach(e => { if(!e.classList.contains("Mui-checked")) e.click(); });
```

![2020-04-23_12h22_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14499/a8be0ad3-3568-9454-bad6-c89e072e74a4.png)

すると、画面上に表示されているすべての項目にチェックが入ります。

2020/04/23現在のclusterでは、画面に表示されていない写真にはチェックボックスがレンダリングされていないようなので、すべての項目にチェックを入れることは残念ながらできないようです。

スクロールしながら何回か上記コードを実行する必要があります。

が、1個1個の写真にチェックを入れるよりはかなり楽になるのでは と思います。
WindowsにPythonのvirtualenvを設定～有効化

## 前提

- Windows 10 またはWindows Server 2019
- Python 3.8.2
- 64Bit版

## Pythonをダウンロードとインストール

以下のURLからexeファイルをダウンロードしよう

https://www.python.org/downloads/release/python-382/

※ バージョンごとにURLが違うので注意が必要。今回は3.8.2のURL

ダウンロードが完了したら、python-3.8.2.exe を実行してPythonをインストール。

![2020-04-28_16h22_53.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247515/5c4330d3-e83d-f52b-7b07-12318f19d7fb.jpeg)


PythonがインストールされるPATHを確認。今回の場合は以下。

```
C:\Users\XXXXXXXX\AppData\Local\Programs\Python\Python38-32
```

## virtualenvのインストール

Pythonがインストールされたら"Pip Installs Packages" 通称 pip も利用できるようになっている。

以下のコマンドでインストール

```DOS:virtualenvのインストール
pip install virtualenv
```

## virtualenvで仮想環境を作成

virtualenvのインストールが完了したらPython用の仮想環境を用意する

```DOS:仮想環境を作成
virtualenv C:\Users\xxxxx\venv
```

コマンドの意味は以下である。

```DOS
virtualenv [作成先のファイルパス\仮想環境名]
```

## virtualenvを利用する（アクティベート）

最後に作成した仮想環境を利用する（アクティベート）する方法は以下である。

```DOS
C:\Users\xxxxx\venv\Scripts\activate.bat
```

Scripts配下にあるactivate.batバッチを実行。
すると(venv)が表示される。

```
(venv) C:\Users\xxxxxxx\venv\Scripts>
```
JetBrains系のIDEで右クリックが効かない

WebStormなどJetBrains系IDEの`2020.1`から、なぜか右クリックが効かなくなりました。

# 解決策
1. とりあえずプラグインを全部Disableしてみる
2. IDEを再起動
3. 右クリックが動くようになることを確認
4. どのプラグインが原因か特定して、それだけDisableにして使う

私の場合は`FTP/SFTP Connectivity`をDisableにしたら右クリックが復活しました。

# 参考
- https://intellij-support.jetbrains.com/hc/en-us/community/posts/360008048700-Pycharm-2020-1-right-click-on-mac-os-not-working

# 環境

- WebStorm: 2020.1
- sw_vers
  - ProductName:	Mac OS X  
  - ProductVersion:	10.15.4  
  - BuildVersion:	19E287
pandasのgroupbyしてshiftするときの速さ比較

# はじめに
pandasでテーブルデータをいじっていると、カテゴリーごとに行方向のシフトを行いたい場合があります（例えば、時系列データで1期ずらしをユーザーごとに行いたいなど）。pandasでグループごとにデータを変換する場合、愚直には`groupby().transform`で実行できます。しかし、グループ化する処理は結構時間がかかります。そこで、いくつかの方法でどれくらい時間がかかるか検証してみます。

# 環境
- OS 名	Microsoft Windows 10 Home
- プロセッサ	Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz、2712 Mhz、2 個のコア、4 個のロジカル プロセッサ
- インストール済みの物理メモリ (RAM)	8.00 GB
- conda 4.8.3
- Python 3.7.7
- numpy==1.18.1
- pandas==1.0.1


# 手順
# データ準備

とりあえず1000万行用意してみました。変数は7つで、5つは適当な数値、2つはカテゴリー変数(X, Y)で、それぞれ10カテゴリー、4カテゴリーとしました。

```python
import numpy as np
import pandas as pd


x = np.arange(10_000_000)
y = np.tile(np.arange(10), int(len(x)/10))
z = np.tile(np.arange(4), int(len(x)/4))

df = pd.DataFrame({"a": x, "b": x, "c": x, "d": x, "e": x, "Y":y, "Z": z})
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/78cd4e72-e83b-b815-b59e-10c174c562af.png)

## 実験
今回は二つのカテゴリ変数でグループ化してみました。

### 方法1
愚直な方法で、これが比較の基準になります。

```python
%%timeit -n 1 -r 10

s = df.groupby(["Y", "Z"])["a"].transform(lambda x: x.shift(1))
# 3.25 s ± 107 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
```

### 方法2
グループ化する変数をあらかじめ結合しておく方法です。処理は速くなりますが、結合に時間がかかってしまうので、頻繁にグループ化処理をする場合に向いています。

```python
dg = df.copy()
dg["YZ"] = dg["Y"].astype("str") + dg["Z"].astype("str")
# 13.7 s ± 964 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
```

```python
%%timeit -n 1 -r 10

s = dg.groupby(["YZ"])["a"].transform(lambda x: x.shift(1))
# 2.62 s ± 25.1 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
```

### 方法3
pandasの`shift`メソッドでなく、numpyのシフト関数を作って実行する方法です。そんなに速さは変わらないようです。

参考：[python - Shift elements in a numpy array - Stack Overflow](https://stackoverflow.com/questions/30399534/shift-elements-in-a-numpy-array)

```python
def shift2(arr, num):
    result = np.empty(arr.shape[0])
    if num > 0:
        result[:num] = np.nan
        result[num:] = arr[:-num]
    elif num < 0:
        result[-num:] = np.nan
        result[:num] = arr[-num:]
    else:
        result = arr
    return result
```

```python
%%timeit -n 1 -r 10

s = df.groupby(["Y", "Z"])["a"].transform(lambda x: shift2(x, 1))
# 3.2 s ± 15.1 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
```

### 方法4
グループ化したあと、イテレーションして各グループを処理する方法です。この方法でも速度がそんなに変わらないのと、より柔軟な処理をかけることができるので、結構好きな方法だったりします。

```python
%%timeit -n 1 -r 10

l = [group["a"].shift(1) for _, group in df.groupby(["Y", "Z"])]    
dh = pd.concat(l, axis=0).sort_index()
# 3.12 s ± 14.4 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
```

### 方法5
実は`transform`不要です。これが一番早いです。

```python
%%timeit -n 1 -r 10

s = df.groupby(["Y", "Z"])["a"].shift(1)
# 983 ms ± 10.9 ms per loop (mean ± std. dev. of 10 runs, 1 loop each)
```

## 結果

| 方法   |   説明 |       time(per loop) |
|:--------|:---------|:------------------|
| 方法１   | 標準手法         |              3.25 s ± 0.107 s |
| 方法２   | 予め結合         |              2.62 s ± 0.0251 s|
| 方法３   | numpy shift         |              3.2 s ± 0.0151 s|
| 方法４   | イテレーション         |              3.12 s ± 0.0144 s |
| 方法５   | transformなし         |              0.983 s ± 0.0109 s |

# おわりに
`transform`を使ってはいけない（戒め）
Scoopをセキュリティソフトに邪魔されずに入れたいな

# 発端

[Scoop](https://scoop.sh/)を公式の通りに、

```
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
```

でインストールしようとしたらセキュリティソフトに阻まれたので、なんとかインストールする

# 準備

## https://get.scoop.sh の内容をファイルに保存する

https://get.scoop.sh に直アクセスして表示された内容をテキストファイルで保存する
get-scoop.sh などで適当なディレクトリに保存
（ここでは作業ディレクトリとしてc:\tmp\scoop に保存）
念のため改行とかはLFのみにしたり

## GitHubからZIPでダウンロード

https://github.com/lukesampson/scoop にアクセスして「Clone or download」から「Download ZIP」でダウンロード

ダウンロードできたらzipそのままを作業ディレクトリに保存
(c:\tmp\scoop\scoop-master.zip)
その後解凍したディレクトリも作業ディレクトリに保存
(c:\tmp\scoop\scoop-master)

## get-scoop.sh の書き換え

書き換えが必要な場所は3カ所

31行目
```$core_url = 'https://raw.githubusercontent.com/lukesampson/scoop/master/lib/core.ps1'```

URLを作業ディレクトリ相当に書き換える
```$core_url = 'c:\tmp\scoop\scoop-master\lib\core.ps1'```

44行目
```$zipurl = 'https://github.com/lukesampson/scoop/archive/master.zip'```
zipファイルのパスを書き換える
```$zipurl = 'c:\tmp\scoop\scoop-master.zip'```

60行目
44行目と同じ

## コマンド実行

DownloadString()で呼び出すファイルを、さっきテキストで保存したファイルにする

```
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('c:\tmp\scoop\get-scoop.sh')
```

```
PS C:\tmp\tools> Invoke-Expression (New-Object System.Net.WebClient).DownloadString('c:\tmp\get-scoop.sh')
Initializing...
Downloading scoop...
Extracting...
Creating shim...
Downloading main bucket...
Extracting...
Adding ~\scoop\shims to your path.
'lastupdate' has been set to '2020-04-23T11:01:26.2306095+09:00'
Scoop was installed successfully!
Type 'scoop help' for instructions.
PS C:\tmp\tools>
```
ZOOMを安全に使う為の主催者側の設定

#ZOOMを安全に使う為に
特に重要な情報を扱う企業・機関でのZOOM利用はないと思いますが、一般的な企業でZOOMを主催する必要がある場合、安全に使用する為の設定方法を記載します。

##概要
ZOOMアカウントの取得は省略し、主催時の設定のみ紹介致します。
今回は下記設定を実施します。
　・PesonalMeetingID(PMI)をOFF
　・遠隔操作をOFF
　~~・待合室機能有効化~~
　・ファイル送信禁止
なお、会議開始後は主催者が「ミーティングをロック」を行うことを推奨します。

##実際の設定

####ZOOMにログインし、「マイアカウント」をクリックします。

![2020-04-23_11h48_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359386/0e1779d1-5528-7599-2036-e01cc57e13ff.png)

####画面左側の「設定」をクリック

![2020-04-23_11h44_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359386/08aab68e-3b91-c3d4-4015-0420ac1dc996.png)

####PesonalMeetingID(PMI)をOFFにします。
![2020-06-08_13h10_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359386/6b8a557c-880b-9ebe-ce9b-20d89bf0de1e.png)

※PesonalMeetingID(PMI)は常に同じミーティングIDを使用するので、PMIを知っている方(過去にミーティングを行った)が別のミーティングに参加できてしまいます。(ミーティングをロックしていない場合や待機室を利用しない場合)
余計なトラブルを防ぐ為にも、毎回別のミーティングIDを使用するように設定します。

####遠隔操作もOFFにします。
![2020-06-08_13h08_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359386/76d11617-8da8-161d-2f7c-969106e60ddd.png)

####ファイル送信はできないように設定します。
![2020-04-23_11h46_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359386/7ed260c3-21e6-ea5d-92e8-d71c7ce034a5.png)

以上で会議開催前の準備は完了です。

###推奨事項
Web会議開始後は他の人が勝手に入れないように「ミーティングのロック」を行うことをお勧めします。

![2020-04-23_10h49_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359386/e00cc38e-ca90-2ead-e0ca-f61940527121.png)

以上、最後までお読み頂きありがとうございました。
S2JDBCでのテーブル結合

Oracle SQL Developerしか触ったことない私がS2JDBCでのテーブル結合にかなり苦戦したので、過去の私への備忘録です。

◆S2JDBCでの結合のポイント
　（１）結合先・結合元のテーブルのエンティティクラスにアノテーションをつける必要がある。
　　　　アノテーションは、「多対一(＠ManyToOne)」と「一対多(＠OneToMany)」がセット
　（２）それをもとにサービスクラスで結合の記述をする。
　（３）複数のテーブルの結合も同様に可能。

◆（１）エンティティにアノテーションをつける
２つのテーブルについて、**外部キーを持つ方（所有者）**と**持たない方（被所有者）**の区別をしっかりつける。
ここでは、外部キーを持つ方 ⇒ 従業員テーブル
　　　　　　　　持たない方 ⇒ 部署テーブル　　　　とします。
たとえばテーブルの中身はこんな感じ…

【従業員】Employee

|id |name  |dep_id |
|---|------|-------|
|1  |john  |3      |
|2  |kate  |1      |
|3  |perry |2      |
|4  |smith |1      |　
★dep_idが外部キー

【部署】Department

|id |dep |
|---|----|
|1  |営業|
|2  |経理|
|3  |人事|


まずEmployeeのエンティティクラスにアノテーションをつけていきます。

```java:Employee.java
public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;
    ....
    /** dep_idプロパティ */
    @Column(length = 20, nullable = false, unique = false)
    public String dep_id;

    /** Departmentプロパティ */  //(1)外部キーで呼び出すテーブルのエンティティ定義を追加する。
    @ManyToOne //（2）Employeeから見たDepartmentは「多対一」の関係なので、ManyToOneアノテーションをつける。
    @JoinColumn(name="dep_id", referencedColumnName="id") 
        //(3)結合するカラムを指定。nameにEmployee、referencedColumnNameにDepartmentのカラムをプロパティ名で記載。
    public Department department; // (4)Departmentのプロパティ名をここで指定。
}
```

次に、Departmentの方の記述です。

```java:Department.java
public class Department implements Serializable {
    private static final long serialVersionUID = 1L;
    ....
    /** depプロパティ */
    @Column(length = 20, nullable = false, unique = false)
    public String dep;

    /** employeeListプロパティ */ //(1) DepartmentではEmployee型リストのプロパティを定義することに注意。
    @OneToMany(mappedBy="department") 
        //（2）Departmentから見たEmployeeは「一対多」の関係なので、OneToManyアノテーションをつける。
        // mappedByには、Employeeエンティティで指定したプロパティ名を記載。
    public List<Employee> employeeList; // (3) 結合したテーブルのエンティティのプロパティ名を指定。
}
```

これでエンティティの編集は終了！

◆（２）サービスクラスでの結合の記述
例えば結合したテーブルから、部署IDでレコードを検索・取り出すときは、こんな感じ。

```java:Service.java
	public List<Employee> findById(String dep_id) {
		List<Employee> employeeList= jdbcManager
									.from(Employee.class) // 主キーを持つテーブルのエンティティクラス
									.innerJoin("department", // ↑で指定したプロパティ名
										new SimpleWhere() // 検索条件の指定
											.eq("department.id", dep_id)) //("テーブルプロパティ名.カラムプロパティ名", 引数)
									.getResultList();
		return employeeList;
```

※innnerJoin以外にも結合方法はあるので、使いたい場合は公式サイトで確認しましょう

◆（３）複数テーブルの結合
複数テーブルでもやることは同じ感じです。
　１）外部キーを持つテーブルのエンティティクラスに、結合したいテーブル分のエンティティ定義を追加
　２）外部キーを持たないテーブルに、それぞれリストのプロパティを定義
　３）サービスクラスの　.innerJoin("プロパティ名")等を結合したいテーブルの分記述

おわり
Pythonでunittest

# Unittestとは
unittest（単体テスト）は、作成した関数やプログラムが期待通り動作するか試行することを目的としています。
今回は覚書もかねて大まかな共有します。

# 環境
macOS 10.14.6
# Unittestの基本的使い方
以下は`tashizan`関数をtestするときのコードです。
`tashizan`は引数２つに対し、その和を返す関数です。

```python:Test.py
import unittest

def tashizan(val1,val2):
    ans = val1 + val2
    return ans

class Test(unittest.TestCase):
    
    def test_tashizan(self):
        actual = tashizan(1, 2)
        expected = 3
        self.assertEqual(actual, expected)
        
if __name__ = "__main__":
    unittest.main()
```

`Test.py`内のコードについて上から順に説明します。



```python:Test.py
import unittest

def tashizan(val1,val2):
    ans = val1 + val2
    return ans
```

unittestをインポートし、関数`tashizan`を定義します。

```python:Test.py
class Test(unittest.TestCase):
    
    def test_tashizan(self):
        actual = tashizan(1, 2)
        expected = 3
        self.assertEqual(actual, expected)
```

①`Test`クラスを定義し、`unittest`内の`TestCase`クラスを継承します。
②変数`actual`に答えを格納します。
③変数`expected`に期待される答えを格納します。この場合1+2=3となるため、`expected`には3を格納しておきます。
④`TestCase`内の`assertEqual`メソッドは２つの引数が等しいかどうかを返します。
typescript 3.7以上で styled-componentsのpropsの型を取り出す

typescript 3.7 以上を使用している場合 styled-components で書かれたコンポーネントを `ComponentProps` を使用して型を取り出そうとしてもうまく取り出せません
これは型定義でコンポーネント呼び出しがオーバーロードされており，[2つ目の定義](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/02019242320f8a66d625ad4a0ad1ef8dc6e51ad3/types/styled-components/ts3.7/index.d.ts#L159) がComponentProps に渡る為です．（なぜこれがComponentPropsに渡るとうまく型がとりだせないかは長くなるので割愛します

これを解決するために props の型を取り出す型を用意します

```typescript
import * as React from 'react';
import { StyledComponent, StyledComponentProps } from 'styled-components';

export type ExtractStyledComponentProps<SC> = SC extends StyledComponent<
  infer C,
  infer T,
  infer O,
  infer A
>
  ? StyledComponentProps<C, T, O, A> & {
      as?: keyof JSX.IntrinsicElements | React.ComponentType<any>;
      forwardedAs?: keyof JSX.IntrinsicElements | React.ComponentType<any>;
    }
  : never;
```

```typescript:使い方
const Component: React.FC<{ hoge: string, fuga?: number }> = (props) => <div />;
const StyledComponent = styled(Component)`
  background-color: red;
`;

// ------------------------------
// 先ほど作った型を使って propsの型を取り出してみる
type Props = ExtractStyledComponentProps<typeof StyledComponent>;

// Props が意図した型かテスト（vscode等で各変数の型を見てみて下さい）
const test = (props: Props) => {
  const hoge = props.hoge; // => string
  const fuga = props.fuga; // => number | undefined
  const theme = props.theme; // => {}
  const as = props.as;   // => JSX.IntrinsicElements | React.ComponentType<any>
  const forwardedAs = props.forwardedAs; // => JSX.IntrinsicElements | React.ComponentType<any>
};
```

ExtractStyledComponentProps によって型を取り出すことができるようになりました :tada: 

さらに発展させて React コンポーネントなのか styled-components で書かれたコンポーネントなのかを意識せずに型を取り出せるようにしたいと思います


```typescript
import * as React from 'react';
import { StyledComponent, StyledComponentProps } from 'styled-components';

// 先ほど作った型
export type ExtractStyledComponentProps<SC> = SC extends StyledComponent<....

export type ComponentPropsWithStyledComponents<C> = C extends StyledComponent<any, any, any, any>
  ? ExtractStyledComponentProps<C>
  // StyledComponent の型で無い場合は ComponentProps を使って取り出す
  : React.ComponentProps<C>;
```

```typescript:使い方2
const Component: React.FC<{ hoge: string, fuga?: number }> = (props) => <div />;
const StyledComponent = styled(Component)`
  background-color: red;
`;

// ------------------------------
// 先ほど作った型を使って propsの型を取り出す
type Props1 = ComponentPropsWithStyledComponents<typeof StyledComponent>;

// 意図した型かテスト（vscode等で各変数の型を見てみて下さい）
const test1 = (props: Props1) => {
  const hoge = props.hoge; // => string
  const fuga = props.fuga; // => number | undefined
  const theme = props.theme; // => {}
  const as = props.as;   // => JSX.IntrinsicElements | React.ComponentType<any>
  const forwardedAs = props.forwardedAs; // => JSX.IntrinsicElements | React.ComponentType<any>
};

// React.FC 型も試してみる
type Props2 = ComponentPropsWithStyledComponents<typeof Component>;

const test2 = (props: Props2) => {
  const hoge = props.hoge; // => string
  const fuga = props.fuga; // => number | undefined
  const children = props.children; // => React.ReactNode
};
```

これで無事両方の型を取り出すことができるようになりました