OmniAICreator/Qiita-1.07M huggingface dataset:
Mapbox GL JSで地図をPNGとPDF形式で出力する

## 概要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858331/ab78b58c-f507-95da-945b-c27330f5253c.png)

私が個人で行っている東アフリカのケニアとルワンダの水道局向けの水道ベクトルタイルの[オープンソース活動](https://docs.water-gis.com/ja/)の中で、やはり今表示している地図を画像やPDFとして出力できた方が便利という要望がありました。

MapboxGLから地図画像を出力する方法はサーバー上で画像を作って返すというようなことが一般的な気がしますが、アフリカでのオープンソース活動のコンセプトはサーバーを持つ予算もないような小規模な組織でも運用可能にすることですので、フロントエンドだけで完結させたかった。探していると[mpetroff/print-maps](https://github.com/mpetroff/print-maps)というソースコードを見つけ、それをプラグイン化し、[mapbox-gl-export](https://github.com/watergis/mapbox-gl-export)を開発しましたのでご紹介します。公式のMapbox GL JSの[プラグインサイト](https://docs.mapbox.com/mapbox-gl-js/plugins/)にも掲載されています。

## 使い方

Github packageもしくはnpmjsに登録されていますので、簡単にお使いになれます。オープンソースライセンス（`MITライセンス`）にしていますので、ご自由にお使いいただけます。

まず、npmパッケージとしてインストールします。

```
npm i @watergis/mapbox-gl-export --save
```

まずパッケージをimportします。

```js
import MapboxExportControl from "@watergis/mapbox-gl-export";
import '@watergis/mapbox-gl-export/css/styles.css';
```

次にmapインスタンスを生成します。

```js
const map = new mapboxgl.Map({
        container: 'map',
        style:'https://narwassco.github.io/mapbox-stylefiles/unvt/style.json',
        center: [35.87063, -1.08551],
        zoom: 12,
        hash:true,
    });
    map.addControl(new mapboxgl.NavigationControl(), 'top-right');
```
ここでは私が関わっているケニアのナロック水道局の水道ベクトルタイルのstyle.jsonを使います。背景には国連ベクトルタイルツールキットで生成されたOSMベースの地図を表示しています。

Mapオブジェクトにプラグインを追加します。特にオプションは設けていませんので、そのまま追加するだけです。

```js
map.addControl(new MapboxExportControl(), 'top-right');
```

本当は出力するファイルサイズとか、DPIとかいろいろオプション化した方がいいのかもと思いましたが、とりあえず固定でいいかと思っています。オプション化して欲しい設定などありましたら、Issue上げてくださればと思います。

あとはwebpackなどでビルドしてあげれば完了です。

## 完成

下にデモ画像を用意しました。

![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858331/6c9c2c8c-a5d3-4791-2814-281b44036dca.gif)

上のデモの中で出力した画像はこんな感じ。地図の状態（方位や傾きなど）もそのまま出力します。
![map-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858331/e84584e6-674a-c328-5b67-790aea888025.png)

実際に地図を動かしてみてみたい方は[こちら](https://watergis.github.io/mapbox-gl-export)のURLからアクセスしてご覧になれます。

### このプラグインで出力した画像についての注意点

現時点でプラグインにより、画像にアトリビューションを付与することができていません。つきましては、出力画像を利用する際には、必ず別途以下のようなトリビューションを付与していただけるとありがたいです。基本的にはアプリの地図の右下あたりに出ているかと思います。

```
©NARWASSCO,Ltd., ©Mapbox | OpenStreetMap contributors, Powered by the United Nations Vector Tile Toolkit
```

## Githubリポジトリについて

以下が、Githubのリポジトリは[こちら](https://github.com/watergis/mapbox-gl-export)になります。
Exampleも用意しておりますので、より完全なソースコードをご覧になりたい場合はご利用ください。

## このプラグインへのコントリビューション

プラグインの利用に際して、要望やバグ修正などありましたら、Issueやプルリクエストはいつでも歓迎いたします。また`star`や`Fork`をいただけると励みになります。

### 改善したい点
- FeatureStateの状態を画像出力に反映したい

今一つIssueが上がっているのですが、FeatureStateの機能を使って一時的に色を変えたりした状態では地図を出力しても元のスタイルの色になってしまうというのがあります。内部的には出力用のキャンバスを用意してスタイルファイルからレンダリングして画像にしているのですが、そこにFeatureStateの状態を反映できればいいかと思っていますが、やり方がわかっておりません。

- Attributionを画像に追加したい

今のプラグインではアトリビューションの画像への追加が実現できていません。本当であればstyle.jsonに記載されているアトリビューションの情報を画像に付与して出したいです。しかし、ちょっとそのやり方を見つけられず実現できずにいます。

- 出力するサイズや画像の種類を増やしたい

例えばA4だけでなく、A3とか、B5とかよく一般的に使われるサイズを増やしたい。あとはJPEGとかも追加したい。

もしそのあたり、お力、ご助言を頂けたら大変助かります。

このプラグインが皆様の地図アプリのお役に立てましたらと思います。
javascript  ~map使い方~

#mapの使い方

配列内の数字を文字列から数値にまとめて変えたいとき

```javascript

  let yoso = [ '0', '0', '1', '2' ]
      yoso = yoso.map(Number);
      console.log(yoso) // [ 0, 0, 1, 2 ]
```


map() メソッドは、与えられた関数を配列のすべての要素に対して呼び出し、その結果からなる新しい配列を生成します。
参考：https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map

```javascript

const array1 = [1, 4, 9, 16];

// pass a function to map
const map1 = array1.map(x => x * 2);

console.log(map1);
// expected output: Array [2, 8, 18, 32]

```


便利だなmap関数
1分で学ぶJSON入門

JSONってなんですか？という質問に口頭で答えられるようになればいいなーと思い改めてJSONについて超初歩的な解説の記事を作成しました。

## JSONとは?
[wiki](https://ja.wikipedia.org/wiki/JavaScript_Object_Notation)によると下記の通り。

>JavaScript Object Notation（JSON、ジェイソン）は**データ記述言語**の1つである。
軽量なテキストベースの**データ交換用フォーマット**でありプログラミング言語を問わず利用できる。

この２行がJSONの説明になるのですが難しいワードが出てきたので噛み砕いて説明します。

## データ記述言語とは？
ざっくり説明するとデータの記録に使うフォーマット。
ここでいうフォーマットは書き方のルールである。
JSONの場合は下記のようなフォーマットとなっている

```javascript

[
  {"name" : "太郎", "age" : 26},
  {"name" : "花子", "age" : 23}
]
```


## データ交換用フォーマットとは？
各プログラミング言語間のデータの受け渡しのフォーマット(書き方のルール)
RubyやPHPといったさまざまなプログラム言語からデータのやり取りを行うイメージ。

## なぜJSONが生まれたのか？
15年ぐらい前までは**XML**というデータ記述言語でjavasciptとデータのやりとりを行なってました。
XMLはHTMLと同様に文章中の文字列をdivなどのタグで挟むように書く必要があります。
先ほどのコードをXMLで記述すると下記の通りです

```XML
<?xml version="1.0" encoding="utf-8"?>
<data>
  <item>
    <name>太郎</name>
    <age>26</age>
  </item>
  <item>
    <name>花子</name>
    <age>23</age>
  </item>
</data>
```
データ量はタグ分だけ多くなり処理のパフォーマンスも下がるという問題点がありました。
そこで登場したのがデータをタグではなくテキスト(オブジェクト)で記載したJSON形式。
タグを記載する必要がない分データ量は XML よりも少なくて済みます。
つまり処理のパフォーマンスも下がる可能性が下がるということです。


## データのやりとりイメージ
![スクリーンショット 2020-12-02 10.33.27（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/c75f0b18-7a9f-edce-8603-3408dd68aa00.png)

続きまして、アルサーガパートナーズ Advent Calendar 2020 5日目の記事は @miumi  さんのAPIについてです:tada:
ベン図の限界とUpSet


## ベン図とは

複数の要素を持つセット間の要素の重複を可視化するものだ。
Pythonとmatplotlib_venn で例を示す。

```python
from matplotlib_venn import venn3
set1 = set(['1', '2', '3', '5', '7', '8', '11', '12', '13'])
set2 = set(['1', '2', '4', '5', '10'])
set3 = set(['1', '5', '6', '7', '8', '9', '10', '12', '13'])
venn3([set1, set2, set3], ('Set1', 'Set2', 'Set3'))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7591/bc3961ed-d372-0e6c-fbb9-471d3efb9909.png)



## ベン図の問題

- 「セット間で重なっている面積」は「セット間要素の重複数」を必ずしも反映しない(またその実装がかなり難しい[というかできない?])
- セット数が多くなると破綻する

## ベン図に替わるUpSet

とにかくUpSetの実例を示す。
RとUpSetRを用いる。

```r
library(UpSetR)
listInput <- list(one = c(1, 2, 3, 5, 7, 8, 11, 12, 13), two = c(1, 2, 4, 5, 
    10), three = c(1, 5, 6, 7, 8, 9, 10, 12, 13))
upset(fromList(listInput), order.by = "freq")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7591/625a0a3c-9d95-b177-0e0d-13ba353ed845.png)

UpSetの図が示すものの説明は不要だろう(先程のベン図と見比べてもらえれば何が何と対応しているかわかるだろう)。
逆に言うと言葉が要らないのが可視化ってもんか。

## UpSetの歴史と今

UpSetの可視化手法(アイデア)が論文(DOI: 10.1109/TVCG.2014.2346248)として公開されたのは2014年のようだ。このようなシンプルな可視化手法がこんな最近まで出なかったことに驚きを感じる人がいるかもしれない。「図を組み合わせて何かを表現する」ってのが革新的で、以前にはこの発想が無かったのかもしれない。バイオインフォではこの図は重宝するケースが多く、多くの論文で活用されているようだ。ちなみに前述DOIの論文の引用数は656[2020/12/04 Google調べ]でかなりのもんである。


## 結論

可視化でやれることはアイデア次第でまだまだある。

以上
MBRを理解するために

#MBR(マスターブートレコード)を理解するために
次のサイトを参考にしました。

- http://nobusan.jp/computer/boot/boot.html
- https://qiita.com/kure/items/4a828b16cc927bdc0501

##メモ
- 基本的に32bit版OSを起動するためにはMBRが要る。
- MBR=レガシーBIOSでの起動。
- MBRにはPC起動時のプログラムが含まれる。

##MBRの確認方法
####Ubuntuでの確認方法
次のコマンドを使います。
`hexdump -C -s 0 -n 512 /dev/sda`
指定のデバイスの先頭(-s 0)から512バイト(-n 512)をダンプします。
【Semantic Segmentation】AUNet : Unetの進化系?!

<h1>AUNet: Attention-guided dense-upsampling
networks for breast mass segmentation in whole
mammograms</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/9ab682b1-93e2-a5e9-69dc-b98c4696a57e.png)

乳がんをsemantic segmentationする論文があったので読んでみた。

Unetとほとんど同じ形をしてるのだが、Upsample Blockを改善したらしいので見ていきたいと思う。

<h1>新規性</h1>
<h2>upsampling block</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/52c0f196-ab10-bb95-ace0-980355259c04.png)
Unetで使われているDeconvolution(up-conv 2x2)ってそんなに効率的じゃないから、biliner-upsample(inteporlation)で十分でしょ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/b797b2b8-ff19-7858-f446-6a2e700fecaf.png)
これが超ベーシックのbilinear upsampling block


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/68be263e-deaf-3ca1-acc7-49bcb0410768.png)

high-level(Global)とlow-level(Local)の特徴量を両方とも取り出す為にupsampling blockをこんな感じにしたらしい。

ちょっと投げやりだけど、concatだけよりsumもあった方が良いでしょって感じ。
dense upsampling convolutionと言うらしい。
*あんまり細かい事は書いてなかった

次にGlobal Average Poolingした結果をチャネル毎にかけてますが、
channel-wise attentionと言う。
重みをつけてどのchannelに注目するかを決める手法。

<h1>結果</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/652a6c45-96ea-c834-8623-b1e56475c6a7.png)
Unetより遥かに良い

<h1>結論</h1>
・Unetを模倣していた。
・Deconvolutionよりbiliner upsampleの方が効率的
・dense upsampling convolutionをしてbiliner upsampleの足りない所を補完
・channel-wise attentionをupsampling blockに入れてみた

こういうシンプルなネットワークを改善した論文は勉強になるから好き。

<h1>参考文献</h1>
AUNet: Attention-guided dense-upsampling networks for breast mass segmentation in whole mammograms
https://arxiv.org/pdf/1810.10151.pdf
Stable Baselines3 を使って強化学習をカスタムSIに使ってみよう

> 本記事は [PyTorch Advent Calendar 2020 12月5日寄稿](https://qiita.com/advent-calendar/2020/pytorch) 参加記事です。

Qiitaを含む日本語で書かれている強化学習を解説するコンテンツも、アルゴリズムの中身を解説するものが中心です。

とくに初期の日本語の強化学習をタイトルに持つ書籍でのサンプルコードは、CartPole（棒倒し）や多椀バンディット（スロットゲーム）、迷路などの環境を使ったものばかりで、すぐに流用できそうな機能を紹介するものがあまりありませんでした。

そこで、アルゴリズムや強化学習の仕組みなどの解説を最小限にして、カスタムSIへの適用を最優先にしたスライドを作ってみました。

以下、SlideShareに公開したスライドです。

[![thumbnail](https://image.slidesharecdn.com/openaigym-201203220851/95/slide-1-1024.jpg)](https://www.slideshare.net/HoriTasuku/si-openai-gym-239729205)

ここで紹介している Stable Baselines は TensorFlow1.x 前提ですが、Stable Baselines3 は PyTorch (1.4+) でも動作します。


Stable Baselines では、PPOなどGPU版とCPU版で別れたエージェントモデルクラスを提供していることもありますが、Stable Baselines3 ではそのあたりを考慮しなくても動作するようになっていて便利です。

Stable Baselines/Stable Baselines3 ともにほぼ同じインターフェイスですので、TensorFlow に変えたい場合もコード修正が少なくなる利点もあります。

ただしStable BaselinesではLSTMを使った方策も用意されていますが、Stable Baselines3では MlpPolicy(多層パーセプトロン) か CnnPolicy(CNN) の２種類しかありません。

LSTMなどを使いたい場合は、独自の方策ネットワークを作ることになりますが、以下のリンクにある通り、独自のクラスを作ることも可能です。

- [Stable Baselines の使いやすいインターフェイスを使ったままで、独自の方策ネットワークを定義する](https://fight-tsk.blogspot.com/2020/12/stable-baselines.html)

強化学習のサンプルコードがゲーム画面やシミュレータ画面を扱ったものが多く、UnityやUnrealEngineで実装したシミュレータがいると誤解している人もいるかもしれませんが、そのような3D/2Dシミュレータがなくても実装することは可能です。

最初に紹介したSlideShare内で紹介していましたが、じゃんけんAIを強化学習で実装するサンプルコードを以下のGitHubに置きましたので、こちらのコードを参考にしてみてください。

- [GitHub: rock-paper-scissors](https://github.com/coolerking/rock-paper-scissors)

p.s.

PyTorchっぽい記事でなくて、スミマセン..
systemdとsystemctlの違い

## はじめに
Linuxの学習をしているとsystemdとsystemctlと言う言葉が出てくる。
似たような言葉でややこしいので、軽くまとめてみようと思います。

## systemd
Linuxの起動処理やシステム管理を行う仕組み
> systemdは、システム管理デーモン、ライブラリおよびユーティリティの一式であり、管理および設定における中心的プラットフォームとしてLinuxコンピュータオペレーティングシステム用に設計されている。。

## systemctl
systemctlは、systemdをコントロールするコマンド。
> systemctlはsystemdのシステムおよびサービスマネージャの状態を監視し制御できる。

## 参考
[systemd - サーバ構築、運用時によく使うコマンド、TIPS](https://qiita.com/bluesDD/items/eaf14408d635ffd55a18)
[よく使うsystemctlコマンドまとめ](https://qiita.com/shimajiri/items/ae8fe481bea3e9660a0c)
[systemd超入門](https://dev.classmethod.jp/articles/systemd-getting-started/)
[Wikipedia:systemd](https://ja.wikipedia.org/wiki/Systemd)
MySQLでquit;コマンドで終了した際に、root@以下省略が表示されてしまい元のディレクトリに戻れない

#環境
mac OS Big Sur
docker上でMySQLを起動
（何か間違えていましたらすみません）
##状況
MySQLをターミナル上で終了しようとした際にroot@が表示されてしまう

```
MySQL [book_log]> quit;
Bye
root@ebe3e64de4d6:/var/www/html#
```
何か押してしまってroot@が表示されてしまったのだろうか

exitコマンドで抜け出せました！

```
root@ebe3e64de4d6:/var/www/html# exit;
exit
ss@saaaMPro part2 %
```
rootが表示され、かなり焦りました笑

参考にさせていただきました。ありがとうございます！
[ターミナルにて、mysqlからexitできない]
(https://teratail.com/questions/206451)
転生したらホワイト企業の社員だった話

この記事は [GLOBIS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/globis) の4日目の記事です。

今年もいよいよ1ヶ月弱となりました。
皆さんは楽しいエンジニアライフを過ごせていますでしょうか？
このアドベントカレンダーで、お伝えしたいことはただ1つ。


*キャリアにおいて、生殺与奪の権を他人に握らせるな！！*

# 生殺与奪の権を奪われるとどうなるのか
言われたことを盲信的にやっているだけであったり、キャリアについて意識せずに日々を過ごすと、市場価値のあるスキルが身に付きません。その結果、自分がやりたいことができなかったり、場合によっては企業の言いなりになり、企業そのものがコケた時に転職できずに死にます。まぁ、鬼滅の刃的に言い換えると、妹を失い、鬼に殺されます。

# 主体的にキャリアを選択しよう
楽しいエンジニアライフを送るためには、仕事を通じて高いパフォーマンスを発揮し、周囲から認められること、自らの目標や志を達成すること、そして生まれた余裕から家族と過ごす時間を増やしたり、趣味や副業など好きなことに取り組んでいられる状態が必要ではないでしょうか。

そのために何よりもまず、スキルを高め、大きな成果を生み出せるようになることが必要です。

# 盲目的に企業に縋るのはNG
企業はエンジニア個々人のスキルを最大化するために活動をしているわけではないので、身を置く環境を間違えると悲惨なことになります。例えば、すでに化石となっている古いプログラミング言語やフレームワークを用いた開発などです。このような状況下ではスキルは高まりません。高まるのはその企業内に限定されたスキルであり、その事業がコケたり、ヤバイ状況に陥った場合に逃げ場がなくなります。

私が新卒入社したシステム企業ではWebエンジニアとは異なるスキルセットが求められていたため、スキルを効率的に習得することができませんでした。その結果、弊社に転職した際にも数ヶ月、エンジニアスクールに通う無職時代を経験しました。いま、Webのエンジニアとして働くことができているのは、現在の職場の皆さんのお陰です。ここで実務経験を積んだり、多くのアドバイスや学習機会を頂くことで、スキルを身につけることができました。

スキルを高め、成果を出し、楽しいエンジニアライフを送るにはどうすればいいのでしょうか。私が考えていることを少しでも皆さんにお役に立てるように書いてみようと思います。

# 市場価値を意識しよう
新卒入社したり、中途でエンジニアの世界に入ってきて日が浅い場合、まず目の前の仕事をやり遂げよう！と考え、そしてやり遂げて充実感を得ることが多いと思います。しかし、他社でも成果を生み出せるスキルは身についているか？、転職市場で評価される能力を高られているか？と定期的に自問自答してください。

スキル向上の方向性がずれていると、将来的にやりたいことができても組織やチームを移れなかったり、会社や事業そのものが転覆した時に転職できず、自分自身も沈んでしまいます。特に、あれだけ働いたり、努力していたにも関わらず、振り返ってみれば汎用性の高いスキルは何一つ身についていなかった、という状況は非常に精神的にも辛いものになります。

どのようなスキルの市場価値が高いのか、自分にはどのスキルがあり、今後どのようなスキルを身につけていかなければならないのかを把握しておくようにしましょう。「webエンジニア ロードマップ」、「エンジニア 中級 上級」などとGoogle検索すると、だいたいどんな技術を身につければいいか出てきます。

できれば、友人や知人、同僚などからアドバイスを受けられれば良いです。それらの人脈が全くない場合は、勉強会等に参加して人脈を増やしたりしてみるのも一つの手です。

# スキルアップできる環境に身を置こう

スキルアップの方向性を確認できたら、いよいよ身を置くべきチームの話になります。

企業やチームによって、劇的に環境が異なります。新しい技術に意欲的で、人間関係も良好、残業もほとんどない環境もあれば、古い技術しか使わず怒号が飛び交い、月残業が100時間に達するような環境もあります。スキルアップしやすいのは明らかに前者です。

後者のような環境であったり、身に着けるべきスキルの方向性と仕事を通して得られるスキルに乖離があった場合にはチーム異動や転職を積極的に検討するべきです。規模の大きな企業の場合は積極的にチーム間交流が行われ、新しいビジネスや技術に触れられるので良いですね。

# 転生したらホワイト企業の社員だった話

グロービスに入社後、世界が変わりました。

まず、残業がありません。これにより圧倒的に使える時間が増え、コーディングするもよし、家事をするもよしで、人生全体に余裕がでました。以前の職場が100時間前後の残業が発生して退職や休職者が続出していた状況とは雲泥の差です。

また、モダンな環境に囲まれており、向上心が高い人が多いです。日常業務で使っている技術だけでなく、新しい関数型言語を習得するなど幅広く勉強会が開かれたり、各自学んでいる印象があります。逆に学ぶ速度が早く、置いてかれないようにせねばと刺激を受けること多々です。MBOや1on1を通し、上長とスキル習得の方向性を決めたり、サポートを受けられるのも心強いです。

そして、優秀で人格者が多いです。プロダクトオーナーは著名なIT企業出身者やMBA取得者だったり、エンジニアも爆速で成長している若手やコードが芸術的に美しいベテランまで、層が厚いイメージがあります。

100時間の残業、PascalやCOBOLといった古い技術スタック、超優秀だけど10人以上退職させている軍曹やクラッシャーがいる、という闇の環境から転生した身としては、もっとスキルを高めて成果を出したいなーと楽しいエンジニアライフを送っています。

以上です。市場価値を意識する、習得すべきスキルを明確にするなど、当たり前のことですが忘れがちなことなので、新卒入社した頃の自分をイメージして書いてみました。

# キャリアについて参考になる記事一覧

まずは楽しめ！と及川さんが語られている記事
https://type.jp/et/feature/12373/
様々な企業のエンジニアの方々の生き様を感じられる記事
https://techlife.cookpad.com/entry/2015/07/03/135711
私と同じくSIerからWeb系に転職して楽しくて仕方がないエンジニアの皆様
https://shiganai.org/

# おまけ
「社畜の刃」無限残業編　が流行っていますね。残業はダメ絶対。
https://www.youtube.com/watch?v=k2Ifh7VNADw
【API Gateway】API Gatewayとは

## API Gatewayとは
APIの作成・管理をするためのフルマネージド型サービス

- 最大数十万個のAPI同時呼び出し・受付が可能
- Lambdaと組み合わせることで完全にサーバーレスなAPIを実現可能
- WebSocketを利用したリアルタイム且つ双方向の通信のAPI処理が可能

## APIの作成
- API Gatewayで作成するAPIは、1つ以上の**リソース**を持ち、各リソースが1つ以上の**メソッド**を持つ
- RESTfulなAPIのメソッド・エンドポイントの例 `GET https://api.example.com/dev/pet/1`
<br> → `GET`：メソッド、`api.example.com`：API、`dev`：ステージ、`pet/1`：リソース

### メソッドの設定
各メソッドではアップストリームを選択し、APIクライアントとAPI Gateway間のやりとり、API Gatewayとアップストリーム間のやりとりを適切に行えるよう、リクエスト・レスポンスの変換設定を行う

|メソッド|設定内容|
|:--|:--|
|メソッドリクエスト|API Gatewayの受付設定を行う（リクエストに認証が必要か、どのようなクエリパラメータを受け付けるか等）|
|統合リクエスト|API Gatewayとアップストリーム間の統合設定を行う（アップストリームの指定、リクエストボディの変換等）|
|統合レスポンス|アップストリームとAPI Gateway間の統合設定を行う（ステータスコードのマッピング、レスポンス内容の変換等）|
|メソッドレスポンス|API Gatewayからクライアントへのレスポンス設定を行う（ステータスコードごとのレスポンスヘッダーや、レスポンスボディの設定等）|

**クライアントとアップストリーム間のやりとりの流れ**
**リクエスト**：クライアント → [メソッドリクエスト] → API Gateway → [統合リクエスト] → アップストリーム
**レスポンス**：アップストリーム → [統合レスポンス] → API Gateway → [メソッドレスポンス] → クライアント

## APIの公開
作成したAPIを利用可能な状態にするためには、APIの公開作業であるデプロイを行う

- デプロイ先として複数の**ステージ**を持ち、各ステージに異なるバージョンのAPIの公開が可能
- デプロイしたAPIのベースURL（デフォルト）：
<br>`https://{api-id}.execute-api.{region}.amazonaws.com/{stage}`
- 利用者の所有するドメインをカスタムドメイン名として設定することも可能

## APIドキュメント
公開したAPIを利用者が活用しやすいよう、利用方法等の説明を記載・公開するもの

- API Gatewayには、APIに関するドキュメントを作成する機能が用意されている
- 作成したAPIのリソース・メソッド・リクエスト・レスポンスなどに各要素に説明を付けるだけで、APIドキュメントの標準形式に則ったAPIドキュメント定義ファイル（**Swagger（OpenAPI）**）をエクスポートすることが出来る
- Swagger形式のAPIドキュメント定義ファイルをAPI Gatewayにインポートし、APIの作成をすることも可能
OS再インストール後、タッチパッドが使えなくなった

【困ったこと】
　dynabookでWindows10をクリーンインストール（USBでインストールするタイプ）したら、タッチパッドでクリック・ドラッグ以外の動作ができなくなった。
　ネットで調べたら、マウスの詳細設定のとこに「ClickPad」とか「ELAN」とかのタブがあるから、そこで設定をしてくれって書いてあったから探したけど、見つからなくて困ってた。

【環境】
PC : dynabook
型番 : PT75UBP-BWA
OS : Windows10

【対策】
　Windows10等のセッティング完了後、Windowsの設定（歯車のやつ）の更新とセキュリティのところに、「必要に応じてドライバの更新をしてね」という感じの場所ができており、そこにELANの項目があり、それにチェック入れて更新した。

【結果】
　再起動後、タッチパッドの他の動作もできるようになった。

【注意事項】
　自作PCとかじゃない（私のように企業から買って、いろいろ企業系のアプリが入っている）場合、普通にクリーンインストールすると、企業系のアプリは無くなってしまい、後でDLすることが難しくなる（当たり前）。なので、再インストール先にもアプリが入れられるようなものがあるらしいので、再インストールする前には確認したほうがいいかもしれない。
JS 知識をつなげる (JSアウトプット)

##あいさつ
初めての人は初めまして！知っている人はこんにちは！
中学生バックエンドPGのAtieです！
今回は今まで学んできたJSで一つの作品を作っていきます！
ここまで来たらとりあえず基礎は自分なりにできたと思います！
では！

##作品の設計
今回はボタンを押すとユーザーのリストが増えていくものを作っていきます！

ユーザーは前回の記事の[これ](http://jsonplaceholder.typicode.com/users)を使っていきます！

必要な機能
- webApiを叩いてくる
- リストを追加
- リストを表示
大まかな処理がこのようになると思います

##準備
まずは作っていくための準備をします

```index.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf8">
    </head>
    <body>
        <script src="index.js"></script>
    </body>
</html>
```

まずはhtmlです
構造は簡単でスクリプトファイルを読み込んでいるだけです

##DOM操作
まずはDOM操作を実装していきます
今回の作品はボタンとリストが必要なのでhtmlに記述していきます

```index.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf8">
    </head>
    <body>
        <ol id="lists">
        </ol>
        <button id="btn">もっと</button>
        <script src="index.js"></script>
    </body>
</html>
```
ボタンのidはbtnリストのidはlistsにしました

ではidをjsで使えるようにしていきます

```main.js
const btn = document.getElementById("btn");
const lists = document.getElementById("lists");
```

これでjsからbtnとlistsが使えるようになりました

##webApiを叩く
DOM操作の準備が整ったのでwebApiを叩いていきます！
webApiを叩くにはasyncで非同期関数にしてawaitを使います
ボタンが押されたらwebApiを叩きたいのでこのようにします

```index.js
btn.addEventListener("click", async function () {
    const res = await fetch("http://jsonplaceholder.typicode.com/users");
    const users = await res.json();
});
```
これでwebApiが叩けるようになりました

##listに追加
ではlistに追加していきます
コードが見やすいように関数で分けて記述しました

```index.js
// DOM
const btn = document.getElementById("btn");
const lists = document.getElementById("lists");

// 関数
function addList(user) {
    const list = document.createElement("li");
    list.innerText = user.name;
    lists.appendChild(list);
}

async function getUsers() {
    const res = await fetch("http://jsonplaceholder.typicode.com/users");
    const users = await res.json();

    return users;
}

async function listUsers () {
    const users = await getUsers();

    users.forEach(addList);
};

//イベント
window.addEventListener("load", listUsers);
btn.addEventListener("click", listUsers);
```

コードがすっきりなりました
最後のwindowsのところではリロードされたら表示されるようになっています

##さいごに
いやぁ長かったjsの基礎のアウトプットが終わりました！！
今度は一つの分野を掘り下げた記事を書きたいと思っています！
Twitterしています→[AtieのTwitter](https://twitter.com/Atie_BackendPG)
では！また次回の記事で！

##参考、学習資料
[【JavaScript入門 #9】これまで講座で学習した知識をフル活用しよう【ヤフー出身エンジニアの入門プログラミング講座】](https://www.youtube.com/watch?v=Oi38X7mNixE)
XMLHttpRequestについて調べてみた。

XMLHttpRequestを初めて使うにあたり少し調べてみたので、忘れないようにメモしておく。

基本「 https://reffect.co.jp/html/xmlhttprequest-basic 」こちらのページを参考にしています。

>・XMLHttpRequestは、JavaScriptを使ってブラウザとWEBサーバ間でデータの送受信を行う際に利用するオブジェクトです
・XMLHttpRequestはWEBサーバから一度すべてのデータを読み込んだ後でもデータの送受信を行うことができるため、ページをリロードすることなくページ内容を書き換えることが可能。

使う手順。

```
<script>

// (1)XMLHttpRequestオブジェクトを作成
var xmlHttpRequest = new XMLHttpRequest();

// (2)onreadystatechangeイベントで処理の状況変化を監視
xmlHttpRequest.onreadystatechange = function(){
    if(this.readyState == 4 && this.status == 200){
        console.log(this.responseText);
    }
}

// (3)HTTPのGETメソッドとアクセスする場所を指定
//第三引数をtrueにすることで非同期処理になる
xmlHttpRequest.open('GET','/user',true);

// (4)HTTPリクエストを送信
xmlHttpRequest.send();
</script>
```

【補足】
Laravelではcrsfトークンを入れないと419エラーが出る。
```
<meta name="csrf-token" content="{{ csrf_token() }}">
<script>
　　　　var formdata = new FormData();
      formdata.append('name', 'knhj');

     var xhttpreq = new XMLHttpRequest();
     xhttpreq.onreadystatechange = function () {
        if(xhttpreq.readyState == 4 && xhttpreq.status == 200) { alert(xhttpreq.responseText);}
        if(xhttpreq.readyState == 4 && xhttpreq.status != 0) {alert("アップロード完了");}
     };
     var token = document.getElementsByName('csrf-token').item(0).content; 
     xhttpreq.open("POST", "ポスト先", true);
     xhttpreq.setRequestHeader('X-CSRF-Token', token); 
     xhttpreq.send(formdata);
</script>
```

参考は https://qiita.com/knhj/items/833f1b32c68570a2272e
PHPでの入力フォーム作成

#PHPでの入力フォーム作成について

以下のような入力フォームをPHPで作成し、
別ファイルへ出力するようにした。


![スクリーンショット 2020-12-03 20.20.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/794525/49907ce2-4028-3adc-c667-c57eb815977c.png)


ソースコード(ファイル名index.php)

```
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<form action="submit.php" method="get" >
<p> 名前: <input type="text" name="your_name" value=""></p>
<p> 年齢: <input type="text" name="your_age" value=""></p>
<input type="submit" >
</form>
</body>
</html>
```

名前と年齢を入力して、送信ボタンを押すと以下の通り、出力される(出力ファイル名:submit.php)

![スクリーンショット 2020-12-03 20.23.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/794525/f1a31a9b-1e4f-dae7-0f64-6c370e19b2ad.png)



![スクリーンショット 2020-12-03 20.25.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/794525/941cd613-3b4d-e4b0-ee43-6259b368d7fe.png)

```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<p><?php echo $_POST["your_name"] ?>です</p>

<p>年齢は<?php echo $_POST["your_age"] ?>です</p>
</body>
</html>
```



今回はGETでサンプルコードを記載したが、GETをPOSTに変更すれば同様に出力される。



##GETとPOSTの違い

####GETについて

GETでデータを取得した場合、URLの後ろに送りたいデータを付与して、送信する。
以下の通り、入力した名前と年齢がURLに反映されている。

GETを使う場合、URLにデータが残ってしまうというデメリットあり

![スクリーンショット 2020-12-03 20.28.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/794525/74cf39e7-6ee9-a63f-67df-f2e56704e7da.png)



####POSTについて

POSTを使用する場合、HTTPリクエスト内のメッセージボディにデータを含めて送信する。


```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<form action="submit.php" method="post" >
<p> 名前: <input type="text" name="your_name" value=""></p>
<p> 年齢: <input type="text" name="your_age" value=""></p>
<input type="submit" >

</form>
</body>
</html>
```


postでデータを取得した場合、URLには送信したデータが記載されない。
URLに記載されるべきではない情報(PW等のログイン情報)がPOSTで送信される。

![スクリーンショット 2020-12-04 5.34.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/794525/d672993a-5868-6b55-c047-9ed23a3daa69.png)
Dataflow Template "BigQuery to TFRecord" の中身

# Dataflow Template "BigQuery to TFRecord"のソースコードを読んでみる
Dataflow Template は、Google Cloud の分散処理サービスである[Cloud Dataflow](https://cloud.google.com/dataflow)をコードを書かずに動かすことができるシロモノです。いくつかの一般的な処理の[テンプレート](https://cloud.google.com/dataflow/docs/guides/templates/provided-templates)が提供されており、今回はそのうちの「[BigQuery to TFRecord](https://cloud.google.com/dataflow/docs/guides/templates/provided-batch#bigquerytogcstfrecords)」です。機械学習の前処理のひとつです。

ソースコードは[こちら](https://github.com/GoogleCloudPlatform/DataflowTemplates/blob/master/src/main/java/com/google/cloud/teleport/templates/BigQueryToTFRecord.java)

# main処理
大きな流れとしては、
1. 入力されたSQLを使ってBigQueryからデータを読み、その際にTensorFlowのtf.Futureに変換して、tf.ExampleにシリアライズしたPCollectionを生成("RecordToExample")
2. 指定されたtrain/test/validの割合に応じて、Partition変換でデータを分割する
3. 指定されたGoogle Cloud Storageのディレクトリにtrain/test/valというディレクトリを切って、TFRecord形式のファイルを出力("WriteTFTrainingRecord"/"WriteTFTestingRecord"/"WriteTFValidationRecord")

# ちょっとしたポイント
## BigQuery StorageAPIでREAD
BigQueryからの読み込みは、`.withMethod(BigQueryIO.TypedRead.Method.DIRECT_READ)` で指定。

```java
PCollection<byte[]> bigQueryToExamples =
        pipeline
            .apply(
                "RecordToExample",
                BigQueryIO.read(BigQueryToTFRecord::record2Example)
                    .fromQuery(options.getReadQuery())
                    .withCoder(ByteArrayCoder.of())
                    .withTemplateCompatibility()
                    .withoutValidation()
                    .usingStandardSql()
                    .withMethod(BigQueryIO.TypedRead.Method.DIRECT_READ)
                // Enable BigQuery Storage API
            ).apply("ReshuffleResults", Reshuffle.viaRandomKey());
```


## Futureに変換する際の型変換
- "STRING"/"TIME"/"DATE" -> Bytes(Array考慮)
- "BYTES" -> Bytes
- "INTEGER"/"INT64"/"TIMESTAMP" -> Int64
- "FLOAT"/"FLOAT64" -> Float
- "BOOLEAN"/"BOOL" -> Int64(1 or 0)
- その他 -> Error(Unsuported)

## データ分割の指定がない場合
train/test/validの割合指定がない場合、全部trainになる。1が、100%。


```java
void setOutputSuffix(ValueProvider<String> outputSuffix);

@Description("The training percentage split for TFRecord Files")
@Default.Float(1)
ValueProvider<Float> getTrainingPercentage();
```
add (2) -水平加算系-

# はじめに
 - この記事は[ひとりNEONアドベントカレンダー2020](https://qiita.com/advent-calendar/2020/neon-only) 4日目の記事です
 - 昨日の[add](https://qiita.com/tomoaki_teshima/items/79faa3581c18abce0a3c)に引き続き、今日は水平加算系の命令を紹介する


# 水平加算命令
 - 水平加算は、ベクトル内の全要素の和を取る命令
 - 入力は複数だけど、出力は単一の要素 (なので、厳密には SI **M** Dではない、と誰かが言っていた)
 - 水平加算系というだけあって、いくつかあるので、`padd`、`paddl`、`addv`、`addlv`の4つの命令を紹介する
    - ちなみに、名前からして一見水平加算しそうな`hadd`命令は`halving add`で、和を取ったあと右に1bitシフトする命令。つまり水平加算ではない。
 - 本当に`add`命令多すぎである。

![昨日示した`add`系の命令の内、水平加算系の命令だけ抜き出したサブセットの図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12162/992ad9c3-4ae9-ecbe-d784-5339dfb59bd3.png)


# `padd`命令
![https___qiita-image-store.s3.amazonaws.com_0_12162_fa0b9e39-a1cd-81ff-69c6-dda60f8b2a79.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12162/11074e3f-9e6f-87bb-bd3d-1466058da29d.png)

 - この図は[4年前に使った](https://qiita.com/tomoaki_teshima/items/00ab8036195b445d1dde)やつの再掲だけど、基本的に結果の`n`番目の要素には、入力レジスタの(`n*2`番目の要素+`n*2+1`番目の要素)が格納される。

 - intrinsic関数のシグネチャとしては引数は、2つのベクトルを取り、同じ型を返す。(ex: `uint8x16_t vpaddq_u8(uint8x16_t a, uint8x16_t b)`)
 - 先の図は`vpadd_u8`(64bit幅の命令)を表した図だが、`vpaddq_u8`(128bit幅の命令)でも、1つ目のレジスタと2つ目のレジスタをあわせて256bit幅の仮想的なレジスタに対して処理が行われる。入力レジスタの`n*2`番目の要素と`n*2+1`番目の要素の和が、出力レジスタの`n`番目の要素として格納される
    - `vpadd`命令であれば入力は64bit幅のレジスタ2つで128bit幅。総和を計算するには4回の命令(演算)が必要になる。
    - `vpaddq`命令であれば同5回の命令(演算)が必要になる
 - SSEでは、一発で水平加算を求める命令があったが、NEONにはこの`padd`命令しかなかった。 **いままでは**。


# `addv`命令
![vaddv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12162/4dad54da-1e9a-cb17-3256-8d53571df408.png)

 - NEONは、Arm v8の命令セットに含まれた、と何度も書いたけれど、実はその際、`double`演算を始めとする、Arm v7時代には存在しなかった命令たちが追加されている
 - 前述の図は`vaddvq_u8`で128bit幅のレジスタの、8bit整数型の各要素の和を1回で計算している[^1]
 - `addv`命令もその一つで、こちらは、SSEの水平加算命令よろしく、一発で各要素ごとの和を求めてくれる
 - 戻り値は、各要素の型が使われる(`vaddv_u8`ならば`uint8_t`型、`vaddv_s32`なら`int32_t`型) 

# `paddl`命令
 - `paddl`命令では加算する際に各要素をbit拡張する。これにより演算結果がオーバーフローすることを防げる。
 - `paddl`命令は単一のレジスタしか受け付けない。
 - 隣り合う要素ごと加算し、結果を倍の要素に格納して返す。(ex: `uint8x16_t`を受けて`uint16x8_t`型を返す)
![vpaddl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12162/682f9986-9a4a-10f2-f4f5-ef16feef0371.png)

# `addlv`命令
 - この流れで行くとなんとなく分かると思うけれど、`addv`命令の結果を、オーバーフローを防ぐために要素の型より一段広い型で返す
    - ex: `vaddlv_u8`命令だと、各要素は`uint8_t`だが、処理結果は`uint16_t`型で返ってくる
    - こちらも、入力として64bit幅、128bit幅、どちらも受け取る

# その他
 - `vpadd_f16`ならびに`vpaddq_f16`命令が存在するが、こいつらはArm v8.2拡張命令セットなので、実行時にCPUがサポートしているかチェックが必要


# おわりに
 - 本当に`add`命令多すぎである
 - 明日も私の担当の予定です


[^1]: 今気づいたんだけれど、4年前の記事は無駄に`padd`命令を何回も計算してたから、`addv`命令でハミング距離を再計算したら結果が覆る可能性が微レ存？
【Discord.py】Unicode絵文字とカスタム絵文字の違いを紹介

#はじめに
###投稿者の自己紹介
どうもまぬおです！discord.pyでBotを開発しています。よろしくお願いします

###お知らせ
[Discord Bot Advent Calendar 2020](https://qiita.com/advent-calendar/2020/discordbot)
この記事はDiscord Bot Advent Calendarの4日目の記事です。ほかの方の投稿もぜひご覧になってください

[1日目【Discord.py】Discord.py 1.5で追加されたIntentsを攻略する](https://qiita.com/manuo/items/7f62dc2f1e0a801a0708)
[2日目【Discord.py】チャンネルを持ったカテゴリを作成する](https://qiita.com/manuo/items/0723b9d47bddd755ea76)
[3日目【Discord.py】ボイスチャンネルの招待メッセージを送信する](https://qiita.com/manuo/items/7811987a932a1d25c780)


他の日にも投稿しています。たくさんのViewありがとうございます！
良ければ、LGTMもよろしくお願いします！

###今回のテーマ
今回は、Unicode絵文字とカスタム絵文字の違いについて紹介したいと思います
Unicode絵文字とカスタム絵文字では扱いに少し違いがありますので、その辺を紹介できればと思います

また、この記事はある程度Botを開発したことがある**中級者向け**の記事になっています。Botの開発を始める方法などは書きませんので注意してください
初心者の方には、別の方が書いていただいた初心者向けの記事があります
ボクもこの記事からDiscord Bot開発を勉強し始めましたのでおすすめです！

[PythonでDiscordBotを書く方法](https://qiita.com/1ntegrale9/items/9d570ef8175cf178468f)
##絵文字とは
###簡単便利なスタンプ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527954/6e9c37c2-51a8-d527-82d6-5556e0dccdee.png)
絵文字はご存じの通り、いろんな顔やサムズアップなどたくさん種類があります
返事をしたいけど文字を打つのがめんどくさい時に便利ですね
また、Discordでは自分で絵文字を追加することもできます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527954/ebe8d1b5-323d-00e0-63e4-ca33754a64e9.png)
サーバーに合う絵文字を使えるので便利です
##二つの違い
人間が絵文字を打つときにはさほど変わりはありませんが、Botが絵文字を使用するときには違いが出てきます
これらはそれぞれの絵文字を取得する際のコードです

~~~python3
# Unicode絵文字
UnicodeEmoji = "\N{SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES}"

# カスタム絵文字
CustomEmoji = "<:manuo:784105295328313394>"
~~~
###Unicode絵文字の場合
`"\N{Unicode Character Name}"`で絵文字を取得します
{}の中に入れる文字列は[Unicode Character Nameを確認するサイト](https://emojipedia.org/)で確認できます
使いたい絵文字の文字列を検索して記述してください
###カスタム絵文字の場合
`"<:alias:ID>"`で絵文字を取得します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527954/e4974dd3-4321-28e2-a5cf-deec29f3adee.png)
aliasは絵文字を入力する画面で確認できますが、IDは絵文字を打つ画面でもサーバー設定の絵文字を管理する画面でも確認することができません
以下の記事でも紹介されていますが、IDは`\:alias:`と入力して送信する方法で確認できます
[Discordの絵文字IDを確認する方法](https://qiita.com/Arusu_Dev/items/683aef9da468725e778a)
参考にさせていただきました。ありがとうございます
##実際に使ってみる
絵文字の取得方法がわかったところで、実際にBotに送信させてみます
今回のコードはこちら

~~~python3
import discord

TOKEN = "TOKEN"

client = discord.Client()

# Unicode絵文字
UnicodeEmoji = "\N{SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES}"

# カスタム絵文字
CustomEmoji = "<:manuo:784105295328313394>"

@client.event
async def on_message(message):
    # 送信者がBotの場合は反応しない
    if message.author.bot:
        return

    # 絵文字を返信
    Channel = message.channel
    await Channel.send(UnicodeEmoji)
    await Channel.send(CustomEmoji)

client.run(TOKEN)
~~~
Bot以外からメッセージが送られたら絵文字を返すBotですね
![result.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527954/47ea85c7-4f33-4d31-0e2b-0e800b418345.gif)
Unicode絵文字、カスタム絵文字のどちらも使えているのがわかると思います

##おわりに
###取得に一癖あり
普段から頻繁に利用する絵文字ですが、Botで扱う際には一癖あります
取得した後は同じものとして扱えるので、そこからはややこしくないのですが
Botが絵文字を使えると一気にお茶目さが増すので、ぜひ使ってみてください
サーバーに追加した絵文字を有効活用すると、同じ機能でも視覚的にわかりやすくなるのでおすすめです
###おわりのあいさつ
ここまで読んでいただき、ありがとうございました
この記事がみなさんの開発に役立つと幸いです
それでは良いDiscord Bot開発ライフを！
###各種バージョン
Python3 : 3.6.9
Discord.py : 1.5.1
"private"って一体何者？

ある程度学習が進んでくると『private』という記述に遭遇しませんか。
今回でその正体を明かしていきます。

[今回のテーマ]
・いったいどういう役割をするのか
・どんなときに使えば良いのか

そもそもSwiftではアクセス修飾子というものを利用できます。これにより、書いたコードの役割を適応させたい範囲を明確に定義することができます。

ちなみに、、
Swiftには３つの修飾子があります。

・private
・public
・internal


[本題]
❶privateはどんな役割をするのか？

＝ファイルの外のコードから、クラスやそのメンバー、エクステンション、トップレベルの関数などに対してアクセスできなくする。

❷どんなときに使えばいいの？

＝クラスからはアクセスできるけど、外からはアクセスできないようにしたいとき。

have a great day...
フォルダを一瞬でzip化してくれるコードを作りました！

#きっかけ
今日作業中にフォルダをzip化して友人に送る必要があったので、
pythonで作って、今後も再利用できる形であげれないかなと思い、作成してみました！

##zipファイルを作るためにすること
zip化したいフォルダがカレントディレクトリの状態で下記コードをターミナルで実行
enterを1回押すと完成して、カレントディレクトリの一個上のディレクトリにzipファイルが保存されます

```shell:zip

git clone git@github.com:taigasenren/settingsPy.git
cd settingsPy
python settings.py
cd ..
rm -rf settingsPy
```

##コード
os.chdir('../')で一つディレクトリをあげSettingsPyからカレントディレクトリに戻ります
その後カレントディレクトリの一つ上のディレクトリにカレントディレクトリの名前でzipファイルが保存されます

```python:zip.py

import os
import shutil

os.chdir('../')
cd = os.getcwd()
print(shutil.make_archive(cd, 'zip', root_dir = cd))
```

##最後に
まあ普通にフォルダの圧縮をディスプレイで操作すればいいと思うのですが、自分はわりとcliで完結させたいので便利かなと思って作ってみた次第です

もしご利用になられた場合はStarとlgtm押して貰えると嬉しいです！

##追記
現在私は個人事業主として下記のサイトの事業を取り進めております。(サイトはまだ作成して間もないのでまだガタガタです、、)
ホテルの自動チェックインのラインでの実装や、rpaの制作をメインに進めています。
ビジネスでのLineBotのご活用や作業の自動化等にご興味があれば是非ご連絡ください。何卒よろしくお願いいたします。

####サイト:
https://senren.work/

####メディアに取り上げていただいた記事:
https://ascii.jp/elem/000/004/033/4033137/

####メール:
info@senren.work
iOS Simulatorのキャプチャ動画を撮る環境を整える

従来のiPhoneは画面が四角で、QuickTime PlayerやMac標準のショートカットで範囲指定することでキャプチャ動画を取ることができました。しかし、最近のiPhoneは角丸で更に上のほうがボコッと凹んでいるので従来の方法ではきれいに撮ることができません。
調べてみると、iOS Simulatorを使うだけで撮れることが判明したのでその方法をまとめます。

# バージョン
Xcode 12.1

# やり方
iOS Simulatorの画面録画はターミナルで以下のコマンドを打つことで出来ます。

```terminal:terminal
xcrun simctl io booted recordVideo ファイルの名前.拡張子
// 例： xcrun simctl io booted recordVideo sample.mov
```
このコマンドを実行すると、起動しているiOS Simulatorの録画始まります。`Ctrl + c`で録画を終了することができ、録画した動画はコマンドを実行したディレクトリの直下に保存されます。

# なんか覚えにくくない？
これらのコマンド、なんかムダに長くて覚えにくくないですか？(実際、僕は録画する度に調べていました。)
なのでエイリアスというのを設定します。
## エイリアスとは
ざっくり言うと、ターミナルで打つコマンドに設定できる別名のことです。

## エイリアスを設定する
今回はzshでエイリアスを設定する方法をまとめます。
こういったシェル周りの設定をいじるときはviコマンドを使うことが多いですが、慣れてない人には難しいorタイポの温床になると思うので、今回はVSCodeを使った方法を紹介します。
### ターミナルからVSCodeを起動できるようにする
[こちらの記事](https://qiita.com/naru0504/items/c2ed8869ffbf7682cf5c)に簡単にまとまっているのでこれに沿って`code`コマンドを使えるようにしてください。

### エイリアスを設定する。
codeコマンドを使ってVSCodeを開けるようになったら次は実際にエイリアスを登録しましょう。

```terminal
code ~/.zshrc
```
でVSCodeでファイルを開けたら以下のコードを追加して保存します。(recordDemoの部分は任意の文字列で大丈夫です。)

```zsh:.zshrc
alias recordDemo='xcrun simctl io booted recordVideo'
```
保存できたらターミナルで以下のコマンドを打ちます。

```terminal:terminal
source ~/.zshrc
```

これで、エイリアスの登録できました！これで以下のように登録したエイリアスを使うことが出来るようになりました！

```terminal:terminal
recordDemo test.mov
```
コマンドを打つと録画が始まったと思います！お疲れ様でした！！！

# 最後に
エイリアスはめちゃめちゃ有効な時短テクニックです。今回に限らずgitのコマンドなど自分がよく使うコマンドを色々登録してみましょう。
(ちなみに僕はherokuをよくheorkuと打ち間違えるので、heroku='heorku'とエイリアスを登録しました。)

# 参考文献
- [ターミナルからVisual Studio Codeを起動する方法【公式の方法】 - Qiita](https://qiita.com/naru0504/items/c2ed8869ffbf7682cf5c)
- [zshにエイリアスとかいう奴入れたら人生の時間がn秒増えて神 - Qiita](https://qiita.com/Ancient_Scapes/items/abfb0673aa5df3274fc6)
- [Take a screenshot and record a video in iOS Simulator | Sarun](https://sarunw.com/posts/take-screenshot-and-record-video-in-ios-simulator/)
- [Capture iOS Simulator video for App Preview - Stack Overflow](https://stackoverflow.com/questions/25797990/capture-ios-simulator-video-for-app-preview)
【バリデーション】エラーメッセージの日本語変換

#目的
入力をさせる際のバリデーションに引っ掛かった時のエラーメッセージを日本語化し、
見やすく、理解しやすくすること。
またformオブジェクトを使用している場合、うまく反映されなかったのでその場合の記述方法を忘れないため。

#手順
gem 'rails-i18n'を追加

config/application.rbにconfig.i18n.default_locale = :jaの記述追加により言語設定を日本語に指定

この時点で再起動、bundle install後、デフォルトで設定されているcan't be blankなどは
既に日本語に変換されている。
しかしそれ以外の設定されたカラム名やエラーメッセージには対応していないので以下を行う。

まずdeviseに対してのパターン
localeの直下にdevise.ja.ymlというファイルを作成し以下のサイトからコピペ
devise.ja.yml(https://github.com/tigrish/devise-i18n/blob/master/rails/locales/ja.yml)

ここまで導入してもまだ変換されないカラム名などがあるので
同様の場所にja.ymlを作成

```ruby
ja:
# gemでカバーできない変換を記述
 activerecord:
   attributes:
     user:
       nickname:           ニックネーム
       first_name:         お名前(姓)
       last_name:          お名前(名)
       birthday:           生年月日
     item:
       name:               商品名
       image:              画像
 activemodel:
   attributes:
      order_address:
    #  formオブジェクト使用しているのでactivemodelで指定
       city:               市区町村
       house_number:       番地
       post_code:          郵便番号
       phone_number:       電話番号
       prefecture_id:      都道府県
```
このような形式で記述、インデントの位置関係で何を表すか決められているので正確にインデントは行う。
初めformオブジェクトを使用したモデルに関しても同様に記述しなぜ適用されないかがわからなかったが
activerecord:の部分をactivemodel:と変えて指定することで改善できた。
この変更によりテストコードの見直しも必要になるのでそちらも併せて行う。
マンガでわかる絶え間なき陳腐化ミニアンチパターン

![D8C43CF2-10C9-4B39-9308-6516E203D587.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/321c7fe8-fbee-dfd0-eb92-881356edad52.png)
http://wiki.c2.com/?ContinuousObsolescence

ベンダーというやつは、ソフトウェアの大胆なバージョンアップを繰り返すことで、つねに話題に上がってくる状況を作ろうとするものです。もちろん、文化的発展の速さを反映している場合もありますが、マーケティングやシェアの確保を狙って意図的に仕掛けてくる場合もあり、厄介です。

新バージョンへの置き換えもたいへんですが、そのせいで、これまでの常識が急速に古くなったり、新技術を使わないといけないという焦りが優先してしまう状況は、ユーザーのニーズとは無関係なので望ましくないですね。

アンチパターン出版当時はあまりその傾向はありませんでしたが、現在では、Java と OOP スキルや、Web ブラウザと W3C 標準の HTML のように、いくらベンダーがバージョンを上げてきても、ユーザーはそれを意識することなく、ある一定の水準の技術標準さえ満たせば、将来的に動作を保証してくれるロードマップに価値を見出すようになってきたと感じます。

安定したインターフェースに依存して、実務に集中したコードを中心とし、攻めた最新技術を使った部分をいつでも交換できるかたちにしておきたいですね。
Windows Terminalに施したカスタイマイズ

まだちょこっとしかいじってないんですが備忘録も兼ねて書き記しておきます

##設定ファイルの開き方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269735/370d63a5-6b47-a79e-94a2-89bc93ba766d.png)
タブバーのプルダウンメニューから設定を押下するとsetting.jsonがデフォルトのエディタで開ける

##見た目関係

```setting.json
        "defaults":
        {
            // Put settings here that you want to apply to all profiles.
            "fontFace" : "Consolas", //フォント名
            "fontSize" : 14, //フォントサイズ
            "colorScheme" : "One Half Dark" //カラースキーム
        },
```

とまあこんな感じです　至ってシンプル
使用できるカラースキームは
https://docs.microsoft.com/ja-jp/windows/terminal/customize-settings/color-schemes
から確認できます。

##SSHをメニューに追加する
今回は試しに同じLAN内にあるRaspberryPiに接続するように設定してみた

```setting.json
"list":
        [
（追加する）
            {
            	"guid": "{*guid}", //GUIDを入力
            	"hidden": false,
            	"name": "Local RaspberryPi", //表示名
            	"commandline": "ssh pi@raspberrypi.local", //SSHのコマンド
            	"icon": "C:\\Users\\unko\\desune\\gazoudayo.anyimgtype" //アイコンのパス
            }
        ]
```
GUIDは適当に生成して入れてください。
アイコンは自前で用意しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269735/0a94942a-cb04-e7c0-f97a-ff9739e02497.png)
ちゃんとできてればこんな感じ

##その他
随時追加するので乞うご期待
【PostgreSQL】SELECT内で他のテーブルを更新する

# はじめに
これは、[PostgreSQL Advent Calendar 2020](https://qiita.com/advent-calendar/2020/postgresql)の4日目の記事となります。

2018年からサーバーリプレース作業でデータベースを Oracle 11g から PostgreSQL 9.6 に移行作業をし、コロナ禍で出張が延期になるなど影響がありましたが、1年(月1〜3拠点)かけて全国25箇所の導入作業が2020年9月に完了しました。
[OracleからPostgreSQL移行について](https://qiita.com/yaju/items/7cf5ab6987ecd1d83b13)

下記の問題がまだ解決できていません。どこかの設定値を変えたらいいとかアドバイスがあればよろしくお願いします。
[【PostgreSQL】テーブルのインデックスが壊れた話](https://qiita.com/yaju/items/3f2ed8e41851158885d3)

今回はSELECT内で他のテーブルを更新するという、一般的なデータベース使用者には意味不明かもな記事となります。

# 自律型トランザクション
ハンディ端末を使用したアプリーケーションがあり、読み込んだバーコードとの照合処理を行う仕組みがあります。マスタテーブルにSQLを埋め込んで動的に照合方法を変更でき、画面に表示させるメッセージもメッセージマスタに登録しておき、マスタテーブルに表示するメッセージコードを指定しています。

Oracle 11gの時にメッセージを動的に変更したいという要望があり試行錯誤した結果、SQLのユーザー関数を作成して自律型トランザクション（PRAGMA AUTONOMOUS_TRANSACTION)を使用して、メッセージマスタの指定コードのメッセージを書き換えることで実現させました。

移行作業をしている際に、PostgreSQLには自律型トランザクションをサポートしていないので、この方法は使えない旨を伝えたところ、その運用は今は使用していないので大丈夫との回答を得たので何もしませんでした。
今月になって別のユーザーからメッセージを動的に変更したいという要望を受け、再度調査し直したところ下記の記事を見つけました。

>PostgreSQL は、自律型トランザクションを正式にはサポートしていません。自律型トランザクションを使用する必要がないよう、リファクタリングを行うことをお勧めします。自律型トランザクションの使用が避けられない場合、 PostgreSQL では dblink を使用することになります。(中略) dblink は新しい接続を開き、この接続を利用してクエリを実行します。dblink 経由で実行されるすべての SQL オペレーションは、メイントランザクションとは無関係に、即座にコミットされます。
[Oracle 自律型トランザクションを PostgreSQL に移行する](https://aws.amazon.com/jp/blogs/news/migrating-oracle-autonomous-transactions-to-postgresql/)

## dblink
dblinkは、データベースセッション内から他のPostgreSQLデータベースへの接続をサポートするモジュールとなります。
https://www.postgresql.jp/document/9.6/html/contrib-dblink-function.html

PostgreSQLの標準機能なので下記のコマンドでインストールすることができる。

```
CREATE EXTENSION dblink;
```

リモートDBが持つテーブルにローカルライクにアクセスできるが、下記などの制約がある。

* リモート表をSELECTする場合、データを全件ローカルに持ってくるためデータ転送が多くなる。
* リモートDBのテーブルや行をロックしない。整合性を担保するためには二相コミットの実装が必要。
* 独特なSQL書式

## postgres_fdw
dblinkの後継機能となります。
https://www.postgresql.jp/document/9.6/html/postgres-fdw.html

クエリはオーソドックスな書式で通用するが、結合、ソート、LIMIT、集約などがリモートではなくローカルで行われる。
※WHERE句によるシンプルな絞り込みはリモートで行ってくれる。

PostgreSQLの標準機能なので下記のコマンドでインストールすることができる。

```
CREATE EXTENSION postgres_fdw；
``` 

# 実装
今回はユーザー関数を作成し、dblinkを使用してメッセージマスタを対象IDのメッセージを更新します。

```sql:update_message
CREATE OR REPLACE FUNCTION "db_test"."update_message" (in varchar, in varchar) RETURNS varchar AS
$BODY$
DECLARE
    slink CHARACTER VARYING(1000);
    sSql CHARACTER VARYING(1000); 
BEGIN
    slink := 'host=127.0.0.1 user=fuga password=hoge dbname=db_test';
    sSql := format('update mst_message set message = %L where id=%L', $2, $1);

    EXECUTE format('select * from dblink(%L, %L) tt(updated text)', slink, sSql);
    RETURN $2;
END;
$BODY$
LANGUAGE 'plpgsql'
```

# 確認
## 変更前
```sql
select * from mst_message
where id = 'MES0001'
```

|id|message|
|:--|:--|
|MES0001|ラベル|

## 実行
SELECT内で他のテーブルを更新する。

```sql
select update_message('MES0001','ADR-123')
```

## 変更後
```sql
select * from mst_message
where id = 'MES0001'
```

|id|message|
|:--|:--|
|MES0001|ADR-123|

# 最後に
今回、dblinkやpostgres_fdwの機能を知ることができて良かったです。
他のPostgreSQLデータベースへの接続ができるので、アイディア次第では面白いことができそうです。

PostgreSQLは自律型トランザクションをサポートしていないからと安易に諦めてはいけないですね。
[メモ]Raspberry Pi4B+を用いた外部ストレージの自動マウント

# 参考サイト
https://kowaza.blue/post-181/

# 環境
```
$ uname -a
Linux raspberrypi 5.4.72-v7l+ #1356 SMP Thu Oct 22 13:57:51 BST 2020 armv7l GNU/Linux

$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 10(buster)
Release:        10
Codename:       buster
```

#設定の変更
```
$ umount /dev/sda1
$ sudo mkdir /mnt/ext_usb
$ sudo chmod 777 /mnt/ext_usb
$ #（現在使用できるブロックデバイスの情報を一覧表示する）
$ sudo blkid
~略~
/dev/sda1 LABEL_FATBOOT="Hoge" LABEL="Hoge" UUID="FFFF-1DF5" TYPE="vfat" PARTUUID="04dd5721-01"
~略~
$ sudo vi /etc/fstab
$ # 以下を/etc/fstabの末尾に追加
PARTUUID=04dd5721-01 /mnt/ext_usb vfat defaults,nofail 0 0
$ reboot

```

#自動マウントの確認
```
-----reboot後------
$mount -v | grep /mnt/ext_usb
/dev/sda1 on /mnt/ext_usb type vfat(rw,relatime,fmask=0022, dmask=0022,codepage=437, iocharset=ascii,shortname=mixed,errors=remount-ro)
$ #自動的にマウントされている事が確認できる。
```
Flash Advent Calendar 3日目 - JavaScriptバイナリ入門 -

開発環境は整ったので、いざSWFファイルのバイナリデータを分解していこうと思います。
とはいえ、バイナリに関して全く知識がないので、必要そうな知識を頭に入れておきます。

# 目次
* TypedArray
* Bit演算

# TypedArray
バイナリデータを扱う上でTypedArrayの知識は必須です。
型と扱える範囲を覚えておきます。

参考サイト
[TypedArray - MDN - Mozilla](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/TypedArray)

|型|範囲|
|:-----------------|:------------------|
|Int8Array|-128 ～ 127|
|Uint8Array|0 ～ 255|
|Int16Array|-32768 ～ 32767|
|Uint16Array|0 ～ 65535|
|Int32Array|-2147483648 ～ 2147483647|
|Uint32Array|0 ～ 4294967295|
|Float32Array|1.2×10-38 ～ 3.4×1038|
|Float64Array|5.0×10^-324 ～ 1.8×10^308|

また、TypedArrayは可変できないので注意が必要です。
必要な分だけメモリーを確保します。

```javascript
const typedArray = new Uint8Array(100);

// 100以上の数値を代入する
for (let idx = 0; idx < 110; idx++) {
    typedArray[idx] = idx;
}

// 結果
console.log(typedArray.length); // 100
console.log(typedArray) // 0から99までの値が代入されます。
```

# Bit演算

ここまでは、なんとか理解できたのですが
ここからが難題です・・・
事前にBit演算の式と結果をふんわりみておきます。

## ビットシフト演算子

|式|演算子|例|
|:-----------------|:------------------|:------------------|
|<<|左シフト演算子|typedArray[offset] << 8|
|>>|右シフト演算子|typedArray[offset] >> 7|
|>>>|符号なし右シフト演算子|typedArray[offset] >> 5|

## バイナリービット演算子

|式|演算子|例|
|:-----------------|:------------------|:------------------|
|&|論理積 (AND) |typedArray[offset] & 0x1|
|｜|論理和 (OR)|typedArray[offset]｜0|
|^|排他的論理和 (XOR)|typedArray[offset] ^ 2|


では、Adobeが提供しているSWFのバイナリの仕様書からSWFの実装を読み解いていきます。
[SWF File Format](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf)

ええ。全然、理解できません。。。
そこで、バイナリを操作できるライブラリを探しました。

最初に辿り着いたのが@yoya さんの作った[IO_Bit](https://github.com/yoya/IO_Bit)でした。
ありがたく、実装内容を参考にSWFの仕様書を読み解いていきます。


UI8 [Unsigned 8-bit integer value]

```javascript
getUI8 () 
{
    // offsetをインクリメントして次のポインターに移動
    return typedArray[offset++];
}
```

UI16 [Unsigned 16-bit integer value]

```javascript
getUI16 () 
{
    return typedArray[offset++] | (typedArray[offset++] << 8);
}
```

UI24 [Unsigned 24-bit integer value]

```javascript
getUI24 () 
{
    return typedArray[offset++] | (typedArray[offset++] 
        | (typedArray[offset++] << 8) << 8);
}
```

UI32 [Unsigned 32-bit integer value]

```javascript
getUI32 () 
{
    return typedArray[offset++] | (typedArray[offset++]
            | (typedArray[offset++] | (typedArray[offset++] << 8) << 8) << 8);
}
```

[IO_Bit](https://github.com/yoya/IO_Bit)を参考にしながら
一つ一つ仕様書の実装を入れ込んでいきます。

後は仕様があっていれば、そのパターンをテスト実装していきます。
[JavaScriptでのテスト駆動開発](https://qiita.com/ienaga/items/1828b4703fc669308081)

とても地味な作業ですが、ここをしっかり作れば2度3度と改修する必要はないので気長にがんばります。。。

仕様書は複数あるので、ひたすら解読と実装とテストを繰り返します。
[ActionScript3.0の仕様書](https://www.adobe.com/content/dam/acom/en/devnet/pdf/avm2overview.pdf)
[Action Message Format AMF3](https://www.adobe.com/content/dam/acom/en/devnet/pdf/amf-file-format-spec.pdf)
[Video File Format](https://www.adobe.com/content/dam/acom/en/devnet/flv/video_file_format_spec_v10_1.pdf)

少し気が遠くなりそうですが、ここさえできれば
っという気持ちでがんばります。

とはいえ、あまり実用性もないと思いますので
今日はこの辺で終わろうと思いますw

明日はclass設計(プロトタイプチェーン)を書こうと思います。
[Gradle]gradleのコマンド引数でビルド設定を切り替える

プロジェクトプロパティを使う。

## 要点
- build.gradleからはproject.properties["<key>"]でプロジェクトプロパティを参照する
- gradleのコマンド実行時に-P<key>=<value>でプロジェクトプロパティを設定する

## 例

Boolean値のビルド設定を切り替える例を示す。

```gradle:build.gradle
def foobar = project.properties.getOrDefault('foobar', '').toBoolean()

android {
    buildTypes {
        debug {
            debuggable foobar
        }
    }
}
```

```shell:コマンド
# foobarをtrueにする
./gradlew app:assembleDebug -Pfoobar=true
```

デフォルトはdebuggableはfalseだが、コマンドで指定したときのみtrueになる。
HerokuでS3を使うアプリで500エラーが出た時の設定


# heroku側のconfigにS3のキーをセット

Laravelで作ったアプリをHerokuにデプロイしたら500Errorが出た話ですが、

AWS S3を使用している場合には、AWSのLaravelプロジェクト内の「.env」だけではなく、
Herokuのconfig側も設定が必要
  
```
heroku config:set 
AWS_ACCESS_KEY_ID=AAAAAAAAAAAAAA AWS_SECRET_ACCESS_KEY=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AWS_DEFAULT_REGION=ap-southeast-1 AWS_BUCKET=AAAAAAAA -a アプリ名
```
的な感じで設定が可能
3日目：観覧車で学ぶBlenderでのモデリングとUnityへのインポート

この記事はアドベントカレンダー「[【VCI】テーマパークを作ろう](https://adventar.org/calendars/5855) 」の3日目の記事です。


#今回の内容
今回はテーマパークの観覧車を作成しながら以下のことを学びます

* Blender(モデリングソフト)でのモデリング 
* BlenderからUnityへのファイルの持っていき方

今回は結構自己流の方法が入ってしまうかもしれません。(より良い方法があればコメント・Twitterで教えて頂けると助かります。)

# モデリングソフトを導入する
前回お伝えしたように、Unityでは使えるオブジェクトが少ないため、基本的にモデルは外部で作成するか購入して持ってくることが多いです。
今回はBlenderというソフトを使用してモデリングを行います。
　Blender：https://www.blender.org/
　(steam版)：https://store.steampowered.com/app/365670/Blender/
(私はsteam版を使っています)

モデリングソフトは他にもいろいろな種類があります(例：[Metasequoia](https://www.metaseq.net/jp/))
それぞれ長所・短所がありますので気に入ったものをお使い下さい

# Blenderでモデルを作成する
では早速モデリングをしていきましょう。今回は観覧車のゴンドラを作って行こうと思います。
初期設定や画面の味方、モデリングの仕方等はほかサイトで説明されているため、今回はかなり説明を省略します。

まずははじめに画面中央にあるCubeを削除し、上の方にある追加>メッシュから円柱を追加します。
この円柱をベースに、なんやかんやした結果が下の画像です。
(回転・拡縮・切込み・オブジェクトの追加などを使用しました。気になる方は調べてみて下さい。)
![20201204-000819.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64877/68b6df30-88f2-047f-eb5f-d0a82384b2ed.png)

# マテリアルを作成する
モデリングが完了したため、次にこのモデルに色をつけていこうと思います。

画面右のアイコンが縦に並んでいる部分の中にマテリアルプロパティという項目があり、ここでマテリアルの設定が可能です。
1つのオブジェクトで複数のマテリアルを使うこともできます。その際は、マテリアルを当てたいメッシュを選んで「割り当て」ボタンをオスことで割り当てることができます。

今回は以下のようにゴンドラのベースカラーとガラスの部分の2つに分けました。
![20201204-002018.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64877/5e0b5179-4695-408a-4b5f-ee0523b1101b.png)

今回は使用しませんがベースカラーの左側の点をクリックするとテクスチャを使用でき、画像を適用することも可能です。

# モデルをUnityに持っていく
BlenderからUnityにモデルを持っていくためには、一度fbxというファイルにして出力し、それをunityで読み込む必要があります。
(もしかしたら他にも方法があるかも？)


### Blenderからfbxでエクスポートする
まずはじめに出力したいオブジェクトを選択します。作成したオブジェクトを全部出力したい場合は未選択でも大丈夫です。
次にMenuからファイル>エクスポート>Fbxを選択します。すると保存のウィンドウが出ますが、その際に右の方に以下のような設定項目が出てきます。
![20201204-011003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64877/f06463f9-39d5-b9a8-fe56-88584cd8e8e1.png)
私は出力時は以下のように設定しています。

* 必要なファイルのみ選択した場合は「選択したオブジェクト」にチェックを入れる。
* 未選択の場合は最初から作成されていたカメラとライトが含まれてしまうため、カメラ・ランプを対象外にする。
* -Zが前方を+Zが前方に変更(出したい向きと逆になることが多いためやってます。やらないときもあります)
* トランスフォームを適用にチェックを入れる。

最後のトランスフォームですが、こちらにチェックを入れないとUnityに持っていったときにsizeが100の状態になってしまいます。(100%の意味合い？)
VCIでは使用できるサイズが決まっておりsizeが100では取り扱いが不便なのでチェックを入れています。

### Unityでfbxを読み込む
出力が完了したら作成したfbxをプロジェクトに追加します。D&Dでそのまま追加できます
今回はModelというフォルダを作成し、その中に置きました。

追加したモデルを選択するとInspecterに以下のような内容が表示されます。
![20201204-003136_inspecter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64877/506e7407-4e88-ab6f-3e1e-89953cd4dc9a.png)
fbxは入れたままの状態ではBlenderで作成したマテリアルがいじれないので、この中央ぐらいにある「Extract Materials」を選択し、任意のフォルダにマテリアルを展開します。

作成したマテリアルに修正を加えることで見た目を変更する事ができます。
以下の例ではガラス部分を半透明にし、基本色の部分をそれぞれ以前作成した赤・緑・青のマテリアルに変更しました
![20201204-004515.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64877/8bec0633-d23f-918d-e7bf-6935a5b60465.png)

以上で今回の作業は完了です。

#終わりに 
いかがでしたでしょうか？
今回は簡単なモデルの作成でしたが、Blenderは様々な機能があるためもっと凝ったモデリングをすることも可能です。
(その分なれるまでのハードルは高いですが。。。)
次回は作成したモデルにコライダーを追加していきます。