OmniAICreator/Qiita-1.07M huggingface dataset:
Excelで複数条件でのフィルター方法（2×3）


フィルターの詳細設定の使い方がよく分かっていませんでしたが、分かったので備忘録として残しておきます

やりたいことはカテゴリが家電と書籍の中で、パソコン・スマホ・タブレットを含む商品名を絞り込みたいです

SQL的にこんな感じ
(カテゴリ = 家電 OR カテゴリ = 書籍)
AND (商品名 LIKE '%パソコン%' OR 商品名 LIKE '%スマホ%' OR 商品名 LIKE '%タブレット%')

商品の表を範囲選択してフィルターの詳細設定

![スクリーンショット 2020-10-21 17.36.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275540/74d55d2e-5eb6-b687-14d0-a097176dbb52.png)

オプション設定
![スクリーンショット 2020-10-21 17.42.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275540/f2ab48f8-b32e-53bc-f2b1-46395e29a5a9.png)

絞り込み結果
![スクリーンショット 2020-10-21 17.37.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275540/07517c27-2a18-3faa-876d-437676297820.png)
[作り方] discord.js グローバルVC(グローバルボイスチャット)

**グローバルVCを作ってみた。**

[**NeoXBot**](https://discord.gg/zXH4x5F)というdiscordのbotを作ったときに、
[**グローバルボイスチャット**](https://neox-guild.glitch.me/true/)のリクエストがあったので、
先月ごろ作りました。

**準備**
・`"discord.js"` をnpmからインストール

```
npm install discord.js
```
・音声用に `"discordjs/opus"` を同じくnpmからインストール

```
npm install @discordjs/opus
```

```js
/**
DiscordID:696600519283572766
©X / KOU00000
orichalcum.gom@gmail.com
*/
//グローバルボイスチャットの名前
const gvcName = "グローバルボイスチャット";
const token = "あなたのbotのtoken"

const discord = require("discord.js");
const client = new discord.Client();
client.login(token);

//音データ作成用
const {Readable}=require('stream');

//音の流れない音データを作る。
class Silence extends Readable{
  _read(){this.push(Buffer.from([0xF8,0xFF,0xFE]))}
};
/**
 * discord の client が ready 状態になってないと、
 * client.channels..... を行えない。
*/
client.on("ready",()=>{
console.info("ready...")
client.channels.cache.filter
//グローバルボイスチャットが変数gvcNameと同じチャンネルを抽出
(ch=>ch.type === "voice" && ch.name === gvcName)
.forEach(ch=>
{
ch.join()//vcに参加
.then(conn => {//connに参加したvcのデータが含まれる。

      //音の流れない音データを配信 
      //(最初にbotがVCで音データを流さないと音の取得ができないため。)
      conn.play(new Silence,{ type: 'opus' });
      let receiver = conn.receiver;
      //だれかがVCで発言したら。
      conn.on('speaking', (user, speaking) => {
        //botだったら放送しない。
        if(user.bot)return; 
        //音を取得
        const UserVoice = receiver.createStream(user);
        const broadcast = client.voice.createBroadcast();
        //流す音
        broadcast.play(UserVoice,{ type: 'opus' });
    //一斉にbotが接続中のVCに取得した音声を配信。
    for (const connection of client.voice.connections.values()) {
         connection.play(broadcast);
    };
        });
    });
});
});
```
※　※　※
ここにのせたコードは、
[**NeoXBot**](https://discord.gg/zXH4x5F)に搭載してるものとは別に、
公開用にシンプルにしたバージョンのコードなのですが、
ちゃんとしたテストなどを行っていないので、
もしかしたらちゃんと動かないかもしれないです。
答えられる限り答えるので、何かあればコメントでお願いします。
【結合テストコード】date_selectから要素を選択する方法

簡単な結合テストコードを書いていてドツボにハマったので備忘録的に残しておきます。間違っていたらご指摘頂けると幸いです。



    <%= raw sprintf(
        form.date_select(
          :birthday,
          class:'select-birth',
          id:"birth-date",
          use_month_numbers: true,
          prompt:'--',
          start_year: 1930,
          end_year: (Time.now.year - 5),
          date_separator: '%s'),
        "<p> 年 </p>", "<p> 月 </p>") + "<p> 日 </p>" %>

このような年、月、日を選択するフォームで思うように要素を選択できかったので悩んでいたのですが、以下の記事が参考になりました。

[使えるRSpec入門・その4「どんなブラウザ操作も自由自在！逆引きCapybara大辞典」](https://qiita.com/jnchito/items/607f956263c38a5fec24)

結論としてはブラウザで検証を行い指定したい要素をチェックすると、きちんと１つずつname属性が割り当てられていたので、そのまま記述し


    select '1930',from: 'dear_person[birthday(1i)]'
      select '12',from: 'dear_person[birthday(2i)]'
      select '12',from: 'dear_person[birthday(3i)]'

こちらで無事パスしました。
完全に私のミスです。
基本情報を飛ばしていきなり応用情報を受けたときに思ったこと

# 1. はじめに
初投稿。はじめまして。
高専の電気系卒で今は某大学の大学院生をしている七海です。
本記事では、IPAの試験初挑戦で応用情報技術者試験を受けた感想と試験対策について書いていきます。
ITパスも基本情報も知らない人間なので、「ふ～ん」程度に流し読みしてもらうのがいいかなと思います。

(↓2021/01/18 追記)
受かりました！午前81.25点、午後72点でした。[応用情報技術者試験ドットコム](https://www.ap-siken.com/)は大正義でした。

#2. 受験前にあった予備知識
僕が申込前に持っていた予備知識は以下の通りです。
・C言語の基礎的な知識
・論理演算、ビット演算などの工学基礎計算
・PC(ハードウェア)の構成要素
・組み込みマイコンを使った開発の経験
高1のときから工学に触れていた分、ハードウェアの基礎知識については同年代の人より幅広かったかもしれません。ただ、ネットワークやソフトウェアの分野は素人同然でした…。

#3. 応用情報を受けた感想
結論から言うと、過去問さえブン回していれば試験自体はクリアできると感じました(特に午前試験)
参考書で粗方概念を理解して後はひたすら過去問周回。これが一番効率が良いように思います。


僕は予備知識が少しあった分初動は楽でしたが、結局のところ過去問の演習量がモノを言うなと感じたのが感想です。というのも、試験で頻出する問題というのは学校で習わない事項であったり参考書に載っていない内容であることがほとんどだからです。いくら事前知識があってもIPAの試験を受ける限りワカラン殺しは往々にして発生するわけで、それをクリアするためには公式の過去問を参照するのが一番手っ取り早いということです。
 
ただ、社会人で長らく情報技術に触れていなかった方や文系の方にとっては午後問題が脅威になります。応用情報の午後問題は実際の現場のシチュエーションを模擬した問題が出されるため、一問一答だけを視野に入れていると応用が利かず苦しい思いをします。これについては最後に軽く方針を示したいと思います。

#4. 試験当日(10/18)までの勉強履歴
限られた時間の中で試験に受かるために大事なことは、試験に出ないところに時間をかけすぎないことだと思います。これに気付いたのが9月末だったので当時の本人は快活オールで遅れをカバーしたらしいです。
・7月末　申し込み(マジで忘れがち)
Twitterのフォロワーは基本情報の申込を忘れて阿鼻叫喚していました。就活直前の人は特に注意してください。

・8月中旬　こちらの本を購入↓
[キタミ式イラストIT塾  応用情報技術者 ](https://gihyo.jp/book/2019/978-4-297-11023-9) ~~(キタミ本と呼ばれているらしい)~~
800ページを超える書籍であるため威圧感やしんどさがありますが、イラストベースの解説なので理解がしやすく、午後問攻略時も内容のイメージがつきやすいのでお勧めです。参考書には一長一短ありますが、午後問を視野に入れると文字オンリーの書籍を買うよりイラスト付きのものを買った方が効率良いと思っています。

・9月1o日ごろ　読み終わる、そして気付く
「前半に覚えたやつ何も覚えてない」
陥りがち。僕はあろうことか復習をせずに先先ページをめくっていたので、読破するころには前半に覚えた内容をすっかり忘れていたのです。応用情報はどの分野にも英字3~4文字の技術用語が飛び交っているので、どれがどの分野のどんな単語か完全にごちゃごちゃになっていました。それは後に過去問周回で解決できたのですが、覚えたことを頭から逃がさない為にも毎回復習からスタートするのを強くお勧めします。

・9月末　テキストほぼ理解、そして再び気付く
「言うて午前問題あんまり解かれへんな」
先述したことがここで起こりまして、参考書籍だけでは試験範囲をカバーできないことをこのタイミングで理解しました。この後は[応用情報技術者試験ドットコム](https://www.ap-siken.com/)をタブレットで参照して午前問1000本ノックをしていました。分野ごとに過去問を辿り、解答の方針を即座に思い出せなかった問題はスクショして復習フォルダ行き。その日の最後にフォルダを眺め、翌朝も眺め、翌朝勉強前はフォルダ閲覧から始めるようにしました。結果的にこれが効果的だったみたいで、試験当日は過去問と同じ問題を計15問くらい即答できました。

・10月10日~　午後問対策
ある個人ブログを見たときに「午後問は1週間で十分」ということが書かれていたので、それに倣ってこのタイミングにしました。1週間で「セキュリティ、ネットワーク、プログラミング、システムアーキテクチャ、組込みシステム」の5問を対策しました。でもこれはタイミング少し遅かったかもしれないです。理想は地雷除けのためにサブでもう一分野武器を作っておくべきなのですが、僕はその時間を取れませんでした。実際、当日はネットワークの問題がかなり難しかったので相当苦しい思いをしました。スケジュールの逆算は大事です。

#5. 試験結果(解答速報参照)
午前: 83.8%
午後: 67%
セキュリティ…16/20
プログラミング…16/20
システムアーキテクチャ…8/20
ネットワーク…10/20
組込みシステム…17/20
計算ミスが痛かったですが、記述の正答率に助けられました。

#6. さいごに
僕は午後問を技術系の大問で埋めましたが、どうやら点を安定させやすいのは文系大問らしいです。解答のキーワードが問題文中に記載されていることが多いらしく、「大問1つ30分の時間内に全てのキーワードを見つけることができれば8割は固い」と隣のデスクの友人が言っていました。なので、午後問の情報技術系問題に恐れを抱いた場合は文系問題(ストラテジー、マネジメントなど)を稼ぎ頭にしてしまうのも手です。
東大理情・CS専攻の卒論・修論・博論テンプレートを Overleaf でコンパイルする

東京大学大学院情報理工学系研究科コンピュータ科学専攻 および 東京大学理学部情報科学科の学位論文（卒業論文/修士論文/博士論文）を組版するためのドキュメントクラス [iscs-thesis](https://www.i.u-tokyo.ac.jp/edu/course/cs/thesis/iscs-thesis.pdf) v1.3 を、Overleaf に対応させました。

**[東京大学理学部情報科学科 卒業論文 テンプレート](https://ja.overleaf.com/latex/templates/dong-jing-da-xue-li-xue-bu-qing-bao-ke-xue-ke-zu-ye-lun-wen-tenpureto/dypcftrrrcct)**
**[東京大学大学院情報理工学系研究科コンピュータ科学専攻 修士論文 テンプレート](https://ja.overleaf.com/latex/templates/dong-jing-da-xue-da-xue-yuan-qing-bao-li-gong-xue-xi-yan-jiu-ke-konpiyutake-xue-zhuan-gong-xiu-shi-lun-wen-tenpureto/vmmkxshyywpg)**
**[東京大学大学院情報理工学系研究科コンピュータ科学専攻 博士論文 テンプレート](https://ja.overleaf.com/latex/templates/dong-jing-da-xue-da-xue-yuan-qing-bao-li-gong-xue-xi-yan-jiu-ke-konpiyutake-xue-zhuan-gong-bo-shi-lun-wen-tenpureto/pgxvtknpjbwq)**

Overleaf を使うことで、ローカルの PC 上で TeX 環境を構築せずとも学位論文の執筆が可能になり、バックアップの保存もできます。

作成にあたっては、qnighy さんの [iscs-thesis](https://github.com/qnighy/iscs-thesis) リポジトリが参考になりました（文字コード変換の手間を省くことができました！）。ありがとうございます。

## 表紙を中間報告用にしたい場合

`thesis.tex` の `documentclass` を `final` から `interim` に変更します。

```diff
- \documentclass[master,final,11pt]{iscs-thesis}
+ \documentclass[master,interim,11pt]{iscs-thesis}
```

他にも色々オプションがあるようなのですが、よく知らないので、詳しくは [iscs-thesis のドキュメント](https://www.i.u-tokyo.ac.jp/edu/course/cs/thesis/iscs-thesis.pdf) をご覧ください。

## 参考

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ただし、クラウドサービスについては「タイムアウト制限」に注意すべき。<br>卒論・修論が50ページを超えるとコンパイルに1分以上かかるのも普通だろうけど、例えばOverleafの*無料枠*の場合は30秒のタイムアウト制限がある。<a href="https://twitter.com/hashtag/TeX?src=hash&amp;ref_src=twsrc%5Etfw">#TeX</a></p>&mdash; 某ZR（ざんねん🙃） (@zr_tex8r) <a href="https://twitter.com/zr_tex8r/status/1092338008269836288?ref_src=twsrc%5Etfw">February 4, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

章ごとに分割コンパイルをすると良さそうです。cf. [分割した LaTeX ファイルを subfiles を使ってコンパイルする](https://qiita.com/sankichi92/items/1e113fcf6cc045eb64f7)

## 合わせて読みたい

[Overleaf に論文の語数をカウントさせる](https://qiita.com/HelloRusk/items/f7eab51a36f6d4379629)

## 関連

[計数工学科卒論LaTeXテンプレートをOverleafでコンパイルする](https://qiita.com/yokotech/items/4e98f75caf7b52282b19)
Quest対応の5000ポリNecoMaidアバターをVRChatへアップロードする方法（Quest2で動作確認した）

#はじめに
Quest対応の[5000ポリNecoMaidアバター](https://sonovr.booth.pm/items/1843582)をVRChatにアップロードする備忘録になります。

# システム環境
- Windows 10
- Oculus Quest2
- Unity 2018.4.20f1
- VRCSDK2

#導入
1．Unityプロジェクトを作成します。

2．VRCSDK2-2020.09.25.00.08_Public.unitypackageをインポートします。

3．ダウンロードした5000porynecomaidをフォルダごとProjectビューのAssetsフォルダにD&Dします。

4．5000porynecomaid1.1.unitypackageをダブルクリックして、インポートします。

5．5000porynecomaid設定済プレハブをHierarchyビューへD&Dします。

6．VRChat SDKのControl Panelを開き、VRChatのアカウントでログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/f3f26011-a0ad-62b9-99e4-c80befb864d1.png)

7．Builderを開き、Switch Build Target to Androidをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/fcc2ced1-9d6b-5a6e-2b61-6af10204d82b.png)

※ Unity HubからAndroid Build Supportを追加しておく必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/be99dbee-9a73-a97e-d317-dd199ec5a5c0.png)

8．アップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/0c6dc278-0a7c-4ec6-6f80-279b15a959de.png)

9．Windowsでもアップロードしておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/2212af45-d037-a0ff-a567-bb8abd66a514.png)

10．Quest2でVRChatを起動し、アバターが確認できればOKです。
![122103608_376293196837656_4623000491698136780_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/10b33849-e1f8-68ce-887c-17cdf6d0049f.jpeg)

かわいい！
[Tips]didEndEditingRowAtを扱う際の注意点

UITableViewDelegateの[tableView(_:didEndEditingRowAt:)](https://developer.apple.com/documentation/uikit/uitableviewdelegate/1614963-tableview)は、セルのスワイプやEditModeを扱う際に触る機会のあるDelegateのAPIですが、注意点が1つあります。

それは**スワイプアクションによってセルが削除されても呼ばれる可能性がある**という事です。

スワイプによる削除は以下の2種類あると認識しています。

- `tableView(_:commit:forRowAt:)`を実装しつつ、`tableView(_:trailingSwipeActionsConfigurationForRowAt:)`を`nil`で返している時の**標準スワイプ削除**
- `tableView(_:trailingSwipeActionsConfigurationForRowAt:)`で削除アクションを含むConfigurationを返している時の**独自スワイプ削除**

もしかしたら標準スワイプ削除を利用している場合は、内部の挙動によって`tableView(_:didEndEditingRowAt:)`が呼ばれないことがあるのかもしれませんが、後者の実装をしている場合は呼ばれることがあります。

そのため、以下のようなコードを書いているとクラッシュします。

```swift

func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?) {

    let indexPath = indexPath!
    let cell = tableView.cellForRow(at: indexPath)! // クラッシュ!
    
    // cellに対するアクション
}
```

独自スワイプ削除でセルを削除した場合、`indexPath`自体は`nil`ではありませんが、`tableView.cellForRow(at: indexPath)`の結果が`nil`になりクラッシュします。

また、API設計理由を考えても何かしらの理由で`indexPath`自体が`nil`で渡されるケースが存在するはずのため、`indexPath`のケアも必要です。

このような意図しないクラッシュを避けるために、以下のようにOptional-Bindingを正しく利用して記述しましょう。

```swift

func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?) {

    // もしくはguard-else節など
    if let indexPath = indexPath, let cell = tableView.cellForRow(at: indexPath) {
        // cellに対するアクション
    }
    
}
```
AWS S3向けのウイルススキャン機能をテストしてみた

#はじめに
AWS S3にファイルをアップロードする際にウイルススキャンをしたいと考えている方、多いのではないでしょうか？特に外部の不特定多数のユーザから送ってくる情報の中に、マルウェアが潜んでいる可能性もあります。
前段でAmazon EC2にウイルス対策ソフトを入れて、一度EC2上でファイルをスキャンしてからS3にアップロードする運用もあるようですが、AWS EC2を常時起動しておかなければらないので余分なコストがかかってしまうかもしれません。
特にオブジェクトで管理されているS3に保存した個々のファイルがスキャンされたかどうかも知りたいのではないでしょうか。
このたび、S3向けのウイルススキャン機能を提供する製品Cloud One - File Storage Securityをテストしてみましたので感想を書かせていただきたいと思います。

#テスト手順
##Cloud Oneアカウントの準備
アカウントは以下のURLから「Create an Account」でアカウントを申請します。
https://cloudone.trendmicro.com/
![アカウント申請.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698816/f0a373ee-c796-2d8a-b740-e09da58dfee4.png)

##S3バケットの作成
テストでは[filescantest]という名前のバケットを作成します。
![S3bucket.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698816/9b956d44-61ea-ef88-004f-da3a5a61875f.png)

##Cloud One - File Storage Securityの設定その１
Cloud Oneにログインし、File Storage Securityのコンソールに入り、「Deploy All-in-one Stack」- 「Launch Stack」を選択します。
![LaunchStack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698816/0647a2a3-8448-a1bd-a90a-ee5cfa245088.png)

##Cloud formationのテンプレート作成
テンプレートを作成するとはいっても、Stack名（任意）とバケット名（作成済みのバケット名）を入力するだけです。
![Stackconfig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698816/911bb4e8-6cf1-cf62-96ac-56298eae4626.png)

##テンプレートからスタックを展開
展開とはいっても作成済みのテンプレートから展開されるだけなので、待つのみです。
展開されれば、Scanner StackとStorage Stackの２つのStackが作れますので、それぞれのROLEARNをコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698816/b2c231cc-07d8-33ea-e9bf-1a23f5c66d5c.png)

コピーするパラメータは各スタックの出力の中にあるStackManagementRoleARNの横にある値をコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698816/91c51b77-2080-09f6-3bbb-73598f5b2e07.png)

##Cloud One - File Storage Securityの設定その２
コピーしたARNをそれぞれコピーし、Submitします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698816/9a3c3415-7ced-784e-861b-662bfc0fa16c.png)

以上で、File Storage Securityの導入が完了となります。
次にファイルをアップロードしてみましょう。

##ファイルのアップロード
任意のファイルを作成し、アップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698816/1edf9e2f-0a3c-34ca-583d-fc8fa13aa402.png)

##スキャン結果の確認
ファイルのプロパティを開き、スクリーンショットの通り、ファイルがクリーンかどうかや、スキャンした時間などの詳細を確認することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698816/0becaf31-f950-3756-e17c-04f0e7ccc3ef.png)


#感想
以上、どうでしょうか？導入まではたぶん１０分もかからないですね。
テストしてみて思ったことですが、
1.導入がとにかく楽です。
2.個々のオブジェクトのスキャン結果とその日時が分かります。
3.AWSの知識がなくても簡単に導入できます。
4.サーバーレスで、管理サーバや、スキャンサーバの構築が不要です。

こちらのプロダクトはPost-scan処理を柔軟に指定できるようですので、ワークフローをお客様のニーズに応じて設定できます。
例えばCleanのファイルをさらにクリーンファイルを格納するバケットに移したり、ウイルスが含まれるファイルであれば、隔離専用のバケットに移すことを実現できます。
次回はPost-scanについて触ってみたいと思います。
pybind11 配列データ型のメモ

pybind11 で配列型を扱うときは主に以下があります.

`py::list` : Python List 型
`py::array` : generic な array 型(numpy. Python array モジュールでは無いっぽい)
`py::array_t` : `py::array` の型指定版(e.g. `py::array_t<double>`)
`py::buffer` : Python Buffer(ByteArray)

py:array, py::array_t では, Python 側からの入力は tuple, array も OK です(内部的に numpy ndarray に変換)

たとえば頂点データのように多量の(型付き)配列データを Python world に expose する場合は, 性能を考えて numpy 使うのがよいでしょう.

ちなみに, pybind11 `numpy.h` 自体には, NumPy データ型の自前定義が含まれているため, C++ モジュールコンパイル時には numpy ヘッダや, numpy ライブラリとのリンクは不要になっています.
(python 側では numpy のインポートが必要)

numpy を使わずに pure Python にしたいのであれば `py::list` or `py::buffer` でしょうか.
【StereoDepth】StereoDRNet: DilationでPSMNet超え



<h1>StereoDRNet: Dilated Residual Stereo Net</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/86f6288c-54a2-ac4a-fe8a-9d2bb91a443d.png)

[PSMNet](https://qiita.com/minh33/items/db6ebea1f8b52b956ed3)の進化版で精度も高くFLOPS数も小さい。

Dilationを用いる事でGlobal情報を学習しながら小さいモデルでも精度が出るようになった。

<h1>Feature Extraction</h1>
他のネットワークと同じでdownsampleしながら畳み込む。最終的に1/4のwidthとheightになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/fe0a4a11-0526-ea20-3a88-bf857f1d85a8.png)

もっとglobalな情報にもアクセスしたいので、Dialationを用いて複数解像度のデータを結合している。


<h1>Cost Volume</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/7ceabe10-36d7-6a11-546b-443faccd3d81.png)

[PSMNet](https://qiita.com/minh33/items/db6ebea1f8b52b956ed3)とほとんど同じで、Dilationを使うことでよりGlobalとLocalの情報にAccessしようとしている。

<h1>Disparity Refinement</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/cdb16632-4b68-916e-253c-fb8d3e9a908b.png)

いつも計算するGeometric ErrorとPhotometric ErrorとLeft Imageを入力してOcclusion MapとResidual Disp Rを推定する。

Residual Disp RはLeft Imageと2つのErrorによって計算された差分で、Left Disparityを足す事でRefineされたDisparityを求めることが出来る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/e3f42c91-a2ec-9986-0150-458d655e5fb3.png)
Ground TruthのOcculusion Mapと比較してCross-Entropy-Lossを計算する。

どうやってGround TruthのOcclusion Mapを作るのか気になる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/eb717870-fd95-ca7c-71c4-26a9d2f195db.png)

RefineしたDisparity MapとGround TruthのDisparity Mapの差分を計算する。

<h1>結論</h1>
Dilationを用いたSpatial Poolingをすることで、Globalな情報を捉えラてるようになり、texture lessな場所なども以前より精度よく推定出来るようになっている。

Disparity Refinementで使われていたOcclusionの推定はどうやってGround Truthを得れるのか不明で、もしSimulator以外で出来るのであれば役立ちそう。

<h1>参考文献</h1>
StereoDRNet: Dilated Residual Stereo Net
https://arxiv.org/pdf/1904.02251.pdf
【HTML/CSS基礎】インライン要素とブロック要素/widthとheight　


まずインライン要素とブロック要素と聞いて何を思い浮かべます？

僕>>width/heightが決めれたり、
横いっぱい伸びたり、隣に並んでくれたりする要素？値？でしょ！

びっくりするくらいざっくりとでしか覚えてません。。
その都度、ネットで調べて適宜対応しています。


しかし！！！

もう頭の中に入れて、調べたくない、、、
調べる時間がもったいない、、、
そんな気がするので、備忘録として残します。


アウトプットまでがインプット！！！


## 目次
###①インライン要素とブロック要素
- ①-1 それぞれの値の特徴
- ①-2 細かいところ

###②widthとheight
- ②-1 width/height: auto; 
- ②-2 auto と 100%の違い

###③width指定ではみ出る
- ③-1h widthではみ出るの回避


###④番外編　画面縮小時に、flexboxで指定した要素が縮小しないのを解決

####①-1 それぞれの値の特徴

1) block 
- p, div, ul, h1~h6タグの初期値
- 要素が横いっぱいにまで広がり、縦に並んでく(前後に改行)
- 高さ・幅・余白指定　可能！
- text-align/vertical-align　不可能！ 

2) inline
- a, span, imgの初期値
- 要素が横に並んでいく
- 幅・高さは文字の大きさで決まる
- 上下のmarginは指定できない
- text-align(親要素)/vertical-align　可能！
**リンクタグの幅を指定したいときは、
inline-block要素 か block要素を指定してあげる 

3) inline-block
- displayで指定！！
- 横に並びつつ、少し距離をとる
- 高さ・幅・余白指定　可能！
- text-align(親要素)/vertical-align　可能！

4) none
→無視！！

#####①-2 細かいところ

- inline要素の中にblock要素は入ることはない



##### ②-1 width/height: auto;

- block要素の場合　
→何もしないと、横いっぱいに広がる
- inline/inline-block要素の場合
→要素の幅＝要素の中身（テキスト）
 100%で指定することで、横いっぱいに広がる。


##### ②-2 auto と 100%の違い
- autoの場合
→ widthの中にpadding/border　
　が含まれる

- 100%の場合
→ widthの中にpadding/border
　が含まれない
　余白をつけた分だけ、親要素からはみ出でしまう

##### ③-1h widthではみ出るの回避
- 入れ子にする 
→外側の要素を100%にしてあげて包む
- calc()関数を使う
→maring: 0; border: 2px; padding: 2px;の場合
左右のはみ出し合計は8px
なので、その分を引いてあげる
width: calc(100% - 8px）；
- box-sizingを利用
→box-sizing: border-box;を指定することで、
padding/borderまでwidthの指定範囲が広がる。


#### ④番外編　画面縮小時に、flexboxで指定した要素が縮小しないのを解決
- widht/heightを指定してあげる。

長文・乱文失礼します🙇‍♂️
プログラミング言語と言語処理系について超ミニマムに解説してみる

#前置き
今回の解説は友人に聞かれて説明した時に自分でもしっかり説明しきれなかったので、自分の中で整理することも含めて書いています。
(間違いがあればご指摘お願いします！)

#プログラミング言語とは
「**どんなプログラムを実行したいかという命令を伝える言葉**」です。

#言語処理系とは
「**プログラミング言語で書かれたコードの内容をコンピュータが理解して実行するためのソフトウェア**」です。
(※以下、言語処理系を処理系と略します)

#JavaScriptで例える
JavaScriptでは、まず皆さんがやるようにコードを書きます。

```main.js
function example() {
    //ここに処理を書く
}

example(); /*処理を実行*/
```
↑のコードを書くだけで関数が実行されるはず...と思いますよね？
ただ、テキストエディタでいくらコードを書いてもそれだけでは何も起きません。
なぜか？　そう、処理系でプログラムを処理していないからです。

##JavaScriptの処理系はどこにある？
結論から言うと「**ブラウザ**」にあります。
ブラウザとはchromeとかFirefoxとかIEのことです。

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="main.js"></script>  <!-- この1行!!! -->
</body>
</html>
```
↑の`<script></script>`で`JS`ファイルを`html`内に読み込み、それをブラウザ上で処理することで初めてプログラムが実行されます。
それが可能なのは、**ブラウザ**の中に**処理系**が組み込まれているからです。

#結論
プログラムは、

**1. プログラミング言語でコードを書く**
**2. コードを言語処理系で処理して実行する**

↑の流れで行われている！

#おまけ(ここからは読みたい人だけ)
ブラウザ上でのJavaScriptの処理系は「**JSエンジン**」と呼びます。
そのJSエンジンの仕様はブラウザ毎に多少変わってきます。
例えば、chromeのJSエンジンは**V8**、firefoxは**spider monkey**という処理系が組み込まれていますが、
JSエンジンが違えば当然処理の仕方も異なるため、同じコードでも実行結果が微妙に異なります。
また、このブラウザではこの関数は使えるけどこっちのブラウザでは使えないというのも処理系が異なるため起きることです。
PowerShellでChocolatyをインストールしようとしたらセキュリティソフトにブロックされた

#状況
PowerShellを右クリック&管理者権限で起動して、公式サイト(https://chocolatey.org/install) に記載のコマンドを入力し、パッケージマネージャーChocolateyをインストールしようとしたら、セキュリティソフトにブロックされました。ネットで調べたら、McAfeeを使っている人はブロックされてしまうらしいです。手持ちの別のセキュリティソフトの入ったPCではブロックされませんでした。

```dummy:PowerShell(管理者権限)
> Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
発生場所 行:1 文字:1
+ Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.Service ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
このスクリプトには、悪質なコンテンツが含まれているため、ウイルス対策ソフトウェアによりブロックされています。
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ScriptContainedMaliciousContent
```

#対処法
セキュリティソフト(McAfee)を起動し、リアルタイムスキャンを一時的に無効にします。その後、もう一度PowerShellを起動してからコマンドを入力しインストールすればできるはずです。

#補足
私は、PowerShellの再起動をせずにコマンドを入力してはブロックされてを繰り返しました…。リアルタイムスキャンを無効にしてもそれまで起動していたソフトはスキャンされるようです。
ちなみにMcAfeeなら、設定→セキュリティ履歴でログを確認できるので、McAfeeにブロックされたのか否かすぐに確認できます。
ltspiceでラジオ その5

#概要

ltspiceでAMラジオやってみた。
ゲルマニュームダイオード、やってみた。

#写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/39555db9-1be6-ddf0-0c11-e36b12163956.jpeg)



#１N60 model

```
.model 1N60 D(IS=1.6E-15 N=0.3439 RS=72.1 CJO=1PF)
```

以上。
入力必須ではない項目の入力有無による画面の表示方法

#環境
この記事ではmacOS Catalina10.15.6にインストールしたRuby 2.6.5を使っています。

#概要
下記の条件分岐を行うことがゴールです。
入力必須ではない項目が入力された時→詳細画面で表示（図１）
一方、入力されなかった時→詳細画面で表示されない（図２）

図1　入力された時🔽
![スクリーンショット 2020-10-21 16.23.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693227/0e1c7a6c-d4f9-2261-212d-cdd70135f676.png)

図２　入力されなかった時🔽
![スクリーンショット 2020-10-21 16.25.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693227/fbdbf56b-0f0e-0321-6c67-e7db03aaa450.png)


# 結論 .present?を使用
if文の条件式の際に、```.present?```を使用することで、条件分岐することが出来ます。
そのため、@report.otherの値が存在する際には、備考の内容が表示されます。

```html:show.html.erb
        <% if @report.other.present? %>
          <tr>
            <th class="detail-name">備考</th>
            <td class="detail-value"><%= @report.other %></td>
          </tr>
        <% end %>
```
以上です。
最後までお読みいただきありがとうございます！
同じことで悩んでいる方の手助けになったら幸いです！

#参考
下記のサイトを参考にして、私自身も解決出来ました。
オブジェクトの記法についてより知りたい方は、下記ご確認ください！

https://qiita.com/fursich/items/e4be106b2aa639fd3e6a
xcode12（iOS14SDK）でビルドした際に missing one or more architectures required by this target: arm64 で error になる場合 

Xcode12 iOS14SDK環境で、xcodebuildなどしたときに下記エラーが出たら

```
error: The linked framework 'Pods_XXXXXXX.framework' is missing one or more architectures required by this target: arm64. (in target 'XxxxxxExtension' from project 'XXXXXX')
```

iOSシミュレータ で必要ないarm64用バイナリがビルドされてしまっている可能性が高いです。

Xcode12から ` Valid Architectures(VALID_ARCHS) ` が不要になったようなので、まず `Build Settings` にこの項目があったら消します

次に `Excluded Architectures` に以下のように追加します

これでarm64でのバイナリビルドが除外されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48695/53533248-4f41-830d-857d-d2f6e9f654b5.png)


# cocoapods を使っている場合

`Podfile` に下記を追加して、 `pod install` すれば `Excluded Architectures`が設定されます

```ruby
post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
    config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
  end
end
```



# 参考

stackoverflowで詳しく説明されてる方がおりました

https://stackoverflow.com/questions/63607158/xcode-12-building-for-ios-simulator-but-linking-in-object-file-built-for-ios
PayjpのCustomer作成とdefault_cardの設定

# はじめに
 Payjpの決済方法の記事はたくさんありますが、default_card設定方法はなかったので書かせていただきます。
 トークン化については他の方が書かれているので、javascriptの記述は割愛します。
 
# 開発環境
ruby 2.6.5
Rails 6.0.3.3
# 参考

説明不足なところはこちらで補ってください。


リファレンス: 
https://pay.jp/docs/api/#customer-%E9%A1%A7%E5%AE%A2
https://pay.jp/docs/customer



# Cardモデル
自分の場合はCardモデルで下記のカラムを保存しています。


| id | user_id | card_token | customer_token |
|:---|--------:|:----------:| :-------------:|
|    | integer | tok_~      | cus_~          |


# Customer作成
Customer作成にはcard_token（tok_~)が必要になります。
javascriptで受け取ったtokenをコントローラーに渡して、下記の記述をします。

```ruby:cards_controller.rb
def create
    # card_tokenが正しいか確認
    if params[:card_token] == nil
      redirect_to new_user_card_path
      return
    end
    # ユーザーのcustomer_tokenが存在する場合
    if Card.find_by(user_id: current_user.id)
      card = current_user.card
      customer = Payjp::Customer.retrieve(card[0][:customer_token])
      customer.cards.create(
        card: params[:card_token]
      )
    else
    # ユーザーがcustomer_tokenが存在していない場合 
    customer = Payjp::Customer.create(
      description: "test",
      card: params[:card_token],)
    end
    # cardテーブルに保存
    card = Card.new(
      user_id: current_user.id,
      card_token: params[:card_token],
      customer_token: customer.id)
end
```


# Customer情報取得
 配列`@cards`を定義して、customer_tokenをもとにcard情報を入れます

```ruby:card.controller.rb
cards = Card.where(user_id: current_user.id)
      @cards = []
      cards.each do |card|
        @customer = Payjp::Customer.retrieve(card.customer_token)
        @cards << @customer.cards
      end
```
ユーザーにカードを選択してもらい、引数「i」で選択されたindexを受け取れるようにフォームを作成します。
ビューで`@cards`に対してeach_with_indexで下記の記述でカード情報を表示させられます。


```ruby:select.html.erb

<%= form_with url: set_default_card_path, method: :post, local: true do |f| %>
 <% @cards.each_with_index do |card, i| %>
   <%=f.radio_button :selected, :"#{i}" ,id: "check_card", checked: (card.data[i] [:id] == @customer[:default_card])  %>
   <%= "**** **** **** #{ + card.data[i][:last4]}" %> 
   <%= "#{card.data[i][:exp_year]}年#{+ card.data[i][:exp_month]}月" %>
 <% end %>
 <%= f.submit "次へ進む" %>
<% end %>
```

# default_cardの設定方法
select.html.erbのform_withの中でradio_buttonを使い、params[:selected]に#{i}の値を受け取っています。
`@customer`の[:default_card]に代入して、@customer.saveで完了します。
※@customer.saveをしないと更新されません。

```ruby:cards_controller
def set_default_card
 cards = Card.where(user_id: current_user.id)
      @cards = []
      cards.each do |card|
        @customer = Payjp::Customer.retrieve(card.customer_token)
        @cards << @customer.cards
      end
 @customer = Payjp::Customer.retrieve(card.customer_token)
 index = params[:selected].to_i
    @customer[:default_card] = @cards[0].data[index][:id]
    @customer.save
end
```

### 念のため
+ customerを作成していない場合、card_token(tok_~)があれば、Payjp::Charge.createができます。
+ customerを作成した場合、cardのid(car_~)、もしくはcustomerのid(cus_~)があればPayjp::Charge.createができます。
+ customerのidを渡した場合はcustomerのdefault_cardが使われます。
（指定しない場合は最後に登録したカードがdefault_cardになります。）

# 最後に

もっと簡便な記述もあるかも知れませんが、これで実装することはできます。
あとは、各々アレンジしてください。
[IntelliJ]予測変換が動かなくなる

予測変換が一瞬出て消えたり、そもそもでなかったりと不安定な状態になりました。

![スクリーンショット 2020-10-21 16.36.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178351/4d1341ce-d3d0-922c-7c21-37121ebeed22.png)

普段なら `.` などを打つと次に続く候補がでてくるのですが・・・

### 直し方
IntelliJ側の問題なので、キャッシュが可能性として高そうです。

![スクリーンショット 2020-10-21 16.37.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178351/0939ed94-26a6-6858-e2a9-077efe552c03.png)

`File` -> `Invalidate Caches / Restart` でキャッシュを無効化して再起動。

動作しました。

![スクリーンショット 2020-10-21 16.39.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178351/ef8d96f5-9ffd-ab50-6f4f-13365e544ff2.png)
libcxx std::hash 実装のメモ

C++11 は unordered_map や unordered_set で便利になりましたが, その背景には `std::hash` の導入があります.

しかし `std::hash` の実装自体はややこしいものです.
ここでは libcxx(`libc++`)の実装を見てみます.


## string

`__string` という名前のヘッダファイルの `__do_string_hash` に実装があります.

https://github.com/llvm/llvm-project/blob/f2a06875b604c00cbe96e54363f4f5d28935d610/libcxx/include/__string#L1155

アルゴリズムとしては 32bit (size_t が 32bit の場合) では murmur2, 64bit では cityhash を使っています.
この実装は `<utility>` にあります.

https://github.com/llvm/llvm-project/blob/f2a06875b604c00cbe96e54363f4f5d28935d610/libcxx/include/utility#L977

CityHash の情報はこちら

https://github.com/google/cityhash
http://web.stanford.edu/class/ee380/Abstracts/121017-slides.pdf

イマドキに hash を一から実装するのであれば SipHash https://131002.net/siphash/ が良さそうな気もしますがどうかしらん?
vue.jsを初めて学ぶ① [hello world]

vue.jsを学ぶ記事では一貫して、
jsfiddle上で、Vue.jsのCDNを読み込んで使用していく。

[jsfiddle](https://jsfiddle.net/) → ブラウザで、html,css,vueが実装できる。

[Vue.js](https://jp.vuejs.org/v2/guide/) → CDNが使用できる。


# hello world
- ガイドへ移動
![スクリーンショット 2020-10-21 16.03.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/67ff8a47-d1d2-bd8f-466d-b82c74505bf1.png)
- scriptタグをindex.htmlに貼り付ける

以下どちらでも可能
![スクリーンショット 2020-10-21 16.03.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/15935173-4a5d-927a-0bb6-c92246300a50.png)


```text:index.html
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

<div id = "app">
  <p>
    {{message}}
  </p>
</div>
```
- scriptタグを使用して、vue.jsのCDNを使用できるようにする
- {{message}}にて、Vueのmessage内容が反映される。

```text:index.js
new Vue({
　el: '#app',
　data: {
　　message: 'Hello World'
　}
})
```
- elにて、id'app'を持つ要素にdata(message)をもたせる。


以上で Hello Worldが表示される。

![スクリーンショット 2020-10-21 16.12.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/85d54a09-c298-5831-8bcf-9373b2dba2b5.png)

# Hello Worldを反転させる
- htmlファイルに、buttonタグとvue専用のDOMイベント **v-on:click="メソッド名"** を追加。

```text:index.html
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

<div id = "app">
  <p>
    {{message}}
  </p>
  <button v-on:click="reverseMessage">
    メッセージ反転
  </button>
</div>
```
- jsファイルに、methodsを追加。ｈｔｍｌで指定したDOMのメソッド名とfunction関数を記述する。この関数がDOMが動作した時の処理になる。

(reverseMessageでは、文字が反転する関数が記述される。)

```text:index.js
new Vue({
	el: '#app',
  data: {
  	message: 'Hello World'
  },
  methods: {
  	reverseMessage: function() {
  		this.message = this.message.split('').reverse().join('')
  	}
  }
})
```

![スクリーンショット 2020-10-21 16.39.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/2ea61c3d-4387-2feb-0266-f892a5a039e6.png)






まとめ
1. htmlファイルにscriptタグを導入し、Vue.jsをインストール
2. new Vue（）で括ることでVue.jsが使用できる
3. el: htmlファイル内の要素を指定
4. data: データをもたせる事ができる。さらに、messageで文字列などの要素を持たせる。
5. jsファイルで指定した要素（idやclass）を、htmlファイルに用意し{{}}で囲み指定する。message要素が表示。
6. Vue専用DOMのv-on:clickを追加
7. reverseMessageで、文字反転の関数を呼び出す。
確認画面を経由すると画像データがnilになる時の解決方法

投稿画面→確認画面→投稿完了の流れで作成したい時ってありませんか？
確認画面加えるだけなんですが、データの保存や扱いが少し違っていたことで詰まりました。。
その時の経験を備忘録として書いていきます！

### この記事が参考になるであろう方
・確認画面では画像が表示されるのに、投稿詳細画面では画像がアップロードできていない。
・`binding.pry`等でデバッグして投稿確認のアクション(confirmアクション)の挙動を確認すると、imageだけnilになっている。
・SQL操作をして確認してみても、やはり画像データだけが保存されてない。

### なぜnilになるのか？
どうやら、確認画面を経由した場合には、確認画面から戻される情報に画像データは無いみたいです。

確認画面を表示する前に画像データを別で保存しておき、それを取り出して使う必要があるようです。


### 解決方法の結論

・ 確認画面内に`hidden`の記述を加える。
・ `:image_cache`のパラメータを使用する。
（コントローラ内で`:image_cache`を渡すのを忘れないように。。）

hidden= **隠しデータをサーバーに送信する際に使用。value属性で指定した値がサーバーへ送信する。**

image_cache= **画像のデータそのものを取り扱うパラメータ。（確認画面の実装を挟む際等に使用するパラメータです。）**


# 参考コード

```new.html.erb
<div class="thumbnail">
  <%= f.file_field :image %>
  <%= f.hidden_field :image_cache %>   ← 追記
</div>
<%= f.submit "確認画面へ" %>
```

```confirm.html.erb
<%= form_with model: @tournament, url: tournaments_path, html: { method: :post }, local: true do |f| %>
  <%= f.hidden_field :start_time %>
  <%= f.hidden_field :image %>
  <%= f.hidden_field :image_cache %>   ← 追記
  <%= f.submit "作成する"%>
<% end %>
```

```tournaments_controller.rb
def tournament_params
    params.require(:tournament).permit(:start_time, :image, :image_cache)
end
```
これで画像データが受け取れて表示できる！..はずです。



# 最後に
確認画面を経由した場合の記述は所々変わってきてくるので、意外に詰まってしまいますね。もっとたくさんの経験して成長したいと思います！！

同じ境遇になった方のお役に立てば嬉しいです。
解決や参考になったらLGTM:thumbsup:して頂けると喜びます。笑
jestでimport文を使うには



## 環境
・jest  ^26.5.3
・babel-jest　^26.6.0
・@babel/core ^7.7.5
・@babel/preset-env　^7.7.6

```json:babelrc
{
  "presets": [
    "@babel/preset-react",
    ["@babel/preset-env", {
      "targets": {
        "node": "current",
        "ie":11,
        "safari":9
      },
      "useBuiltIns": "usage",
      "corejs": 3,
      "modules": false
    }],
  ],
```

babelrcの初期設定がこんな感じになっています。

## なぜimport/exportが使えないのか

上記設定のままだと、`jest`でimport/export(es6)文を実行することはできません。
jestでは require系のcommonjsしか使えないためです。
なので、 babelの処理で es6 -> commonjsへの変換を行う必要があります。

## es6 -> commonjsに変換するには？
鍵を握るのは、 `@babel/preset-env`のoptionの `modules`の項目です。
現在`false`で設定しています。
falseだと、moduleの読み込み系の文を変換しない、つまりimport/export文はそのままなので
jestでエラーが出ているというわけです。

これを、 `NODE_ENV`での切り替えを行い、 **jestでテストしている時だけes6->commonjsに変換する**
という風に設定します。

## jest用のNODE_ENV
実はjestはデフォルトでtest用のNODE_ENV `test`が設定されています。

```js:jestの中身
if (process.env.NODE_ENV == null) {
process.env.NODE_ENV = 'test'
}
```

なので、こちらで `jest NODE_ENV=test` と設定する必要はなく、
`jest` コマンドだけでbabelrcの処理を分岐させることが可能です。

```diff:babelrc
{
  "presets": [
    "@babel/preset-react",
    ["@babel/preset-env", {
      "targets": {
        "node": "current",
        "ie":11,
        "safari":9
      },
      "useBuiltIns": "usage",
      "corejs": 3,
      "modules": false
    }],
  ],
  "env": {
+   /* ここから下がjest用の処理 */
+    "test": {
+      "presets": [
+        "@babel/preset-react",
+        ["@babel/preset-env", {
+          "targets": {
+            "node": "current",
+            "ie":11,
+            "safari":9
+          },
+          "useBuiltIns": "usage",
+          "corejs": 3,
+          "modules": "cjs"
+        }]
+      ]
+    }
  }
}
```

`NODE_ENV`が`test`の場合は、 `"modules": "cjs"` に設定しています。
（cjsはcommonjsの略です)

## jestがbabelでコンパイルされるようにする
上記作業だけではまだes6->commonjs変換を行うことはできません。
jest実行時にbabelでコンパイルするよう指示する必要があります。
jest実行時のconfigファイルはデフォルトでは`jest.config.js`ですので、
`jest.config.js`を作成します。

```js:jest.con
module.exports = {
  verbose: true,
  transform: {
    '^.+\\.js$': 'babel-jest',
  },
  moduleFileExtensions: ['js'],
};

```

`babel-jest`パッケージをインストールします。
このパッケージがbabelでのコンパイルを行ってくれます。
https://www.npmjs.com/package/babel-jest

```
$ npm i -D babel-jest
```


## 以上でOK!　動作チェック

```js:exporter.js
export async function addCalcFun(baseValue, addValue) {
  return baseValue + addValue;
}
``` 

```js:importer.spec.js
import { callErrorFun } from './exporter'

describe('エラー', () => {
  it('通常のエラー', () => {
    expect(callErrorFun(2+2)).toBe(5)
  })
})

```

```
$ npx jest importer.spec.js
```

問題なく設定できていれば、上記の処理がうまく走ります🎉


## 参考資料
https://qiita.com/riversun/items/6c30a0d0897194677a37
https://tech.bitbank.cc/lets-test-by-jest/
https://qiita.com/hogesuke_1/items/8da7b63ff1d420b4253f#importexport%E6%A7%8B%E6%96%87%E3%82%92%E4%BD%BF%E3%81%88%E3%81%AA%E3%81%84%E5%95%8F%E9%A1%8C%E3%81%AE%E5%AF%BE%E5%87%A6
Visualforceページの性能改善について


### Visualforceページの性能改善について、以下のことをまとめました。
---

* <B>SOQLについて、以下のことを注意しましょう。</B><BR>
　　1. 計算処理（例：加算など）の実装優先順位：SOQL＞Apex<BR>
　　2. データのフィルター処理の実装優先順位：SOQL＞Apex＞Visualforce<BR>
　　3. ループ内にDMLを発行しないこと。<BR>

*  <B>データサイズについて、以下の方法でデータサイズをコントロールしましょう。</B><BR>
　　1. フィルターの活用：SOQLにフィルター条件を追加することでデータを絞ることができる。<BR>
　　2. 「sharing」キーワードの活用：Apexコントローラクラスに「sharing」キーワードを追加することで、該当ユーザの権限によるデータのみアクセスできる。アクセス権限がないデータがフィルターできる。<BR>
　　3. ページングの活用：StandardSetControllerを継承して、ページングタグを利用することで、一回ロードされるデータが制御できる<BR>

* <B>Visualforceページ内のロジックを減らしましょう。</B><BR>
　　Visualforceページ内に複雑なロジックがある場合、有効なGETTERメソッドを活用して、その分のロジックをApex側に移動すること。<BR>

* <B>Lazy Loadingを活用しましょう</B><BR>
　　大きい画面に対し、全画面のリフレッシュより、非同期処理を利用して、画面の一部のみ更新すること。<BR>

* <B>ビューステートの最適化</B><BR>
　　1. 継続的に利用しないプロパティに対し、「transient」キーワードを宣言することで、ページのビューステートには含まれないから、ビューステートのサイズが縮小される。要求中に何度も再計算するには非常に大きなシステムリソースを使用する。
　　　　※例：画面から渡される画像情報を格納する変数がtransientで宣言する。<BR>
　　2. ビューステートの利用について、基本的にApexコントローラクラスに検索されるデータですので、SOQLになるべく明確な検索条件を追加して、ビューステートのサイズが縮小される。<BR>
　　3. 大量データを画面に表示される場合、ページングを利用して、１回ロードされるデータ量を減らしてビューステートのサイズが縮小される。<BR>
　　4. １つのページに複数のFORMを利用するより、\<Apex:actionRegion\>利用すること。
　　　　\<apex:actionRegion\>コンポーネントは要求時にサーバが処理するコンポーネントのみを定義する。要求が完了したときに再表示されるページの領域は定義しない。<BR>
　　　　※[\<Apex:actionRegion\>の参照リンク](https://developer.salesforce.com/docs/atlas.ja-jp.pages.meta/pages/pages_compref_actionRegion.htm)


最後に、以下のリンクにVisualforceの最適化について、詳しく紹介されるので、ご参照。
[Visualforce のパフォーマンスを最適化するベストプラクティス](https://developer.salesforce.com/docs/atlas.ja-jp.228.0.salesforce_visualforce_best_practices.meta/salesforce_visualforce_best_practices/pages_best_practices_perf_optimizations.htm)
caching_sha2_passwordによるエラーでpython3.xで動かず詰まった点について

##環境
+ OS :macOS High Sierra バージョン10.13.6
+ python :3.8.0
+ MySQL :8.0.21



##状況
python3を使って、MySQLと接続を試した。
だが、
```Authentication plugin 'caching_sha2_password' is not supported createMysqlConnecter
```
というエラーがでて先に進めなかった。

python 2.7.16だとこれを参考にして動いたのだが、
https://qiita.com/yusuke_dev/items/7f0ca12ced72363f9448

##結論
~~~python:sample.py
import mysql.connector as mydb
    conn = mydb.connect(
      host=_host,
      port=_port,
      user=_user,
      password=_passwd,
      database=_dbname,
      auth_plugin='mysql_native_password'
    )
~~~

connect関数に```auth_plugin='mysql_native_password'```を入れることでpython3.8.0でも動いた。
BEM(Block Element Modifier)とは

HTMLのクラス名を好き勝手書いてしまうと、共同での開発で修正しづらいという問題が起きてしまいます。<br>
そこで、後から改修しやすい設計にする手法の一つであるBEMについて解説していきます。

# BEMとは
Block, Element, Modifierの頭文字をとってBEMという名前になっています。

#  BEMの書き方
Block, Elementはアンダースコア二つでつなぎます。
Element, Modifierはハイフン二つでつなぎます。

例:

```qiita.css
/*Block*/
.list

/*Block, Element*/
.list__item

/*Block, Element, Modifier*/
.list__item--second
```

...少し慣れは必要そうです！

#  Block, Element, Modifierの違いについて
Block: ナビゲーションだとフォームなどの部品やヘッダー、フッターなどの大きなセクションのこと

Element: その部品を構成するための中身のこと

Modifier: 同じブロックではあるけれど、他とは状態や見た目が異なる場合に用いる。（例えば、クリックできるボタン、クリックできないボタンで他と異なるクラス名をつけるような時、Modifierを記述する。）

#  BEMのルール
Modifierがあるクラス名とないクラス名は両方記述します。
→CSSの記述が長くなり、修正しづらくなることを防ぐため。

単語はハイフン一つをつなげて記述します。(size-bigなど)

# Sassを使うと便利！

無駄な記述を無くすことができます。

```qiita.sass

.block {
 &__element {
  &--modifier {

  }
 }
 &__element-2 {
  &--modifier {
  
  }
 }
}
```

# 最後に
ルールを定めることで誰が見てもわかりやすくなることは、パフォーマンスの向上にもつながり大変便利だと感じました。
今後、意識していきたいと思っています。

最後まで記事を読んでいただきありがとうございます。今後もフロントエンドをメインにアウトプットをしていきたいと思っているのでよろしくお願い致します。
GitHubのブランチ名を変更する方法

#手順
ブランチ名を変更したい時には、以下の4stepをターミナルで行うことで解決できます。
１．変更したいブランチ名を確認
２．ローカルのブランチ名を変更
３．リモートの変更前ブランチを削除
４．変更したローカルのブランチをリモートにpush


##１．変更したいブランチ名を確認
下記のコマンドを入力するとブランチの一覧が表示されます。

```terminal:terminal
% git branch
```
変更したいブランチ名を確認し、まずはローカルのブランチ名を変更します。

##２．ローカルのブランチ名を変更
下記のコマンドを入力するとブランチ名が変更されます。

```terminal:terminal
% git branch -m 変更前のブランチ名 変更後のブランチ名
```
次に、リモートのブランチを置き換えるためにリモートの変更前ブランチを削除します。

##３．リモートの変更前ブランチを削除
下記のコマンドにより、削除出来ます。
※変更前に```:```をつける必要があります。

```terminal:terminal
% git push origin :変更前のブランチ名
```
最後に、変更したローカルのブランチをリモートにpushにします。

##４．変更したローカルのブランチをリモートにpush
下記のコマンドにより、リモートも変更できました。

```terminal:terminal
% git push origin 変更後のブランチ名
```

#まとめ
GitHubのリポジトリを変更するには、上記の方法で変更可能だと思います。
同じように悩んでいた方のお役に立てれば幸いです!
最後まで見ていただきありがとうございます！
paiza：基本メソッド ( ruby )

web系エンジニアをrubyをメイン言語として、
転職していた時の事、コーディングテストなるものに挑戦し惨敗してから
勉強しなければ！と危機感に煽られていました。

[paiza](https://paiza.jp/)
[Atcoder](https://atcoder.jp/)

といったサイトに登録し
「さぁ！勉強するぞ！」と、やる気十分だったはずが、
まずそもそも、どうやって値を受け取るんだ！
っと混乱していました。

この記事では、似た境遇の皆様に共有できれば良いなと思っております。

 また、コードの間違い修正に関しましてはコメント欄やリクエストを送信ください。
どうぞ、よろしくお願いいたします。


```text:｛文字列｝で、受け取る
# 標準入力
paiza

# 受け取る
a = gets

# 出力
p a

# 結果
=> "paiza"
```



```text:{数値}で、受け取る
# 標準入力
100

# 受け取る
a = gets.to_i

# 出力
p a

# 結果
=> 100
```


```text:{文字列かつ配列}で、受け取る
# 標準入力
100　200　300

# 受け取る
a = gets.split(" ")

# 出力
p a

# 結果
=> ["100", "200", "300"]

```

```text:｛数値かつ配列}で、受け取る

# 標準入力
100 200 300

# 受け取る
a = gets.split(" ").map(&:to_i)

# 出力
puts a

# 結果
=>[100, 200, 300]

```

```text:｛数値かつ配列｝で、受け取る
# 標準入力
1
2
3

# 受け取る
a = readlines.map(&:to_i)

# 出力
p a　

# 結果
=> [1, 2, 3]　
```

```text:{1行ずつ数値}で、受け取る
# 標準入力
1
2
3

# 受け取る
a,b,c = readlines.map(&:to_i)

# 出力
p a
p b
p c

# 結果
100
200
300
```

```text:{ループ変数を用いる。数値}で、受け取る
# 標準入力
1
2
3

# 受け取る
a,b,c = 3.times.map {gets.to_i}
 
# 出力
p a
p b
p c

# 結果
1
2
3
```





```text:{}で、受け取る
# 標準入力
# 受け取る
# 出力
# 結果
```
Python標準 ConfigParser でキー名の大文字/小文字を維持する

Python標準のライブラリ configparser でINIファイルの読み書きを行えます。
https://docs.python.org/ja/3/library/configparser.html

INIファイルとは、セクション・キー・値の構成からなる、設定ファイルなどに使われることがあるファイル形式です。
https://ja.wikipedia.org/wiki/INI%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB

configparserでは、デフォルトでキーの大文字/小文字を区別しない仕様になっています。

```python
import configparser


ini_filename = "sample.ini"
"""INIファイルのなかみ
[General]
Name = hogehoge
"""

parser = configparser.ConfigParser()
parser.read(ini_filename)

""" 大文字/小文字/混在 どうであっても読み込める """
assert parser["General"]["Name"] == "hogehoge", "混在"
assert parser["General"]["name"] == "hogehoge", "小文字"
assert parser["General"]["NAME"] == "hogehoge", "大文字"
```

これはINIファイルの読み込み/書き込みのどちらにも作用します。

RawTherapeeというソフトで使われるサイドカーファイルがINIファイル風の中身になっており、
これを一括編集しようと思ったのですが、RawTherapeeのサイドカーファイルはキー名の大文字/小文字を区別しています。
そのため、ConfigParserクラスでそのまま編集/保存までしてしまうと、キー名がすべて小文字になってしまい、
RawTherapeeでちゃんと読み込めなくなる問題がありました。

これは ConfigParserインスタンスの `.optionxform` に適宜関数をセットしてやることで解決します。
読み書き時のキー名は、`optionxform` 関数で変換した結果が使われます。

したがって、つぎのように `optionxform` を設定してやると、キー名を維持したまま、INIファイルを保存できます。

```python
parser = configparser.ConfigParser()
parser.optionxform = str
parser.read(ini_filename)

parser["General"]["Name"] = "test"

with open(ini_filename, "w") as fp:
    parser.write(fp)
```
Glueデータカタログのテーブルにデータ型decimalを指定する際の注意点（Athena）

## 概要

AthenaやRedshift SpectrumからS3ファイルに対してクエリする際にテーブル定義をGlueデータカタログに登録するかと思いますが、その際のカラムのデータ型にdecimalを指定する際の注意点についてです。

## 事象

カラムのデータ型の指定で`decimal(10, 5)`のようにprecisionとscaleの間に空白を入れると、Athenaからのクエリでは以下のようなエラーが出ます。

```
HIVE_METASTORE_ERROR: com.facebook.presto.spi.PrestoException: Error: name expected at the position 11 of 'decimal(10, 5)' but ' ' is found.
```

ちなみにRedshift Spectrumからのクエリではエラーは出ません。

## 解決策

上記のエラー文からもわかるように空白がエラー原因となっているため、空白を無くし`decimal(10,5)`のようにすれば問題ありません。
Prestoの仕様なんでしょうね。。
MySQL 8.0 で csv データのインポートで詰まった

MySQL 8.0 からはローカルファイルのデータ読み取りはデフォルトだと禁止されてるようです。
テスト用の DB 立てようとしたら詰まったのでやり方を記しておきます。

# 環境
- mysql
    - Ver 8.0.22 for Win64 on x86_64 (MySQL Community Server - GPL)
- pc
    - Windows 10 Pro

# MySQL 起動
ローカルファイルの読み取りできる状態で起動します。

```
mysql --local-infile -uroot -p
```

# csv 追加まで
以下を MySQL 上で順番に実行して csv のデータを追加します。

```sql
-- サーバー側でインポートを有効にするオプションの設定
SET GLOBAL local_infile=on;

-- データベース作成
CREATE DATABASE {データベース名} DEFAULT CHARACTER SET utf8mb4;

-- データベース選択
USE {データベース名};

-- テーブル作成
-- このデータをインポートする前提のスキーマ指定
-- https://www.kaggle.com/c/demand-forecasting-kernels-only/data?select=test.csv

CREATE TABLE {テーブル名}(
    date DATE NOT NULL,
    store int(11) NOT NULL,
    item int(11) NOT NULL,
    sales int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


-- CSV インポート
LOAD DATA LOCAL INFILE "{csvデータのパス}"
INTO TABLE {テーブル名}
FIELDS TERMINATED BY ',' ;
```

# 備考：環境変数確認
MySQL のパスが通ってなかったらGUIで環境変数を確認/追加できます。

Windows システムツール → コントロールパネルと進む
![2020-10-21_14h35_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/69d55f98-39f3-ea28-36ca-7a803075486f.png)

システムとセキュリティをクリック
![2020-10-21_14h36_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/59349532-f7df-858f-c3e8-13e3d08d41d2.png)

システムをクリック
![2020-10-21_14h36_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/0d87bdb6-b948-ec82-ee7c-d77f9f618091.png)

システムの詳細設定をクリック
![2020-10-21_14h37_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/45bc420d-0aa3-6b27-e4e7-92f61e2645aa.png)

環境設定をクリック
![2020-10-21_14h37_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/b68a32e2-c91a-5d01-5f16-d208557af826.png)

システム環境変数から Path を選択、編集をクリック
![2020-10-21_14h37_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/4a801193-124f-4ac3-4a09-a458e7c9a949.png)

MySQL 8.0 がなかったら bin フォルダのパスを追加してあげます。
![2020-10-21_14h39_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363781/500ebe1a-3628-0b3d-6d4f-591c7b17055b.png)
fatal: the remote end hung up unexpectedly（重すぎてgit cloneに失敗する時）

gitlabのリポジトリのcloneが失敗してしまう。
（途中まではうまくいくけど、止まってしまう…。）

```zsh
remote: Counting objects: 100% (975/975), done.
^Cmote: Compressing objects:   0% (1/878)
```
```zsh
fatal: the remote end hung up unexpectedly
```

参考にさせていただいた記事🙏
https://core-tech.jp/blog/article582/

###やったこと
原因は「ファイル重すぎ」。
小さなブランチをcloneするとうまくいくそうです。

```zsh
git clone -b <smaller_branch> --depth 1 <my_repo_URI>
```

例えば

```zsh
git clone -b develop --depth 1 リポジトリのURL
```

無理かな…と思ってたんですが、
「う〜ん、諦めて外付けSSDで他の人からデータもらうか」という話をしてたら
急にうまくいきました。（数分後の出来事）
きこえていたのかもしれない…笑
めでたしめでたし。
Herokuの拡張性について

# Herokuにのせているwebアプリを拡張したい！
 私はherokuを用いてwebアプリを公開していますが、アクセス数の増大が予想されたので拡張することにしました。
調べたことをまとめていきます。

## 拡張の種類
1. 垂直方向の拡張（スケールアップ）
　性能UP
2. 水平方向の拡張（スケールアウト）
　稼働数UPして分散処理

## Dynoとは
・読み方はダイノ
・コンテナみたいなもの
・Web dynoでwebアプリケーションを動かす。
・Worker dynoでDBにクエリを投げてリクエストを待つなどの、バックグラウンド処理が出来る。

## Dynoの種類
1. Free
2. Hobby
3. Standard(professional)
4. performance(professional)

| Dynoタイプ | 値段 | プロセスタイプ | 組み合わせ|オートスケール |
|:-----------:|:------------:|:------------:|:------------:|:------------:|
| Free   | 0円（時間制限あり）        |2|他のタイプの dyno と組み合せ不可|No|
| Hobby     | $7/dyno/月      |10|他のタイプの dyno と組み合せ不可|No|
| Standard1x      |  $25/dyno/月   |無制限 |Performance dyno と組み合わせ可能|No|
| Standard2x        |  $50/dyno/月   |無制限|Performance dyno と組み合わせ可能|No|
| Performance M    |  $250/dyno/月  |無制限 |Standard dyno と組み合わせ可能|Yes|
| Performance L   |  $500/dyno/月  | 無制限|Standard dyno と組み合わせ可能|Yes|
[概要](https://jp.heroku.com/dynos)
↑このページめっちゃわかりやすいので一読するのがおすすめです！

・Herokuにおけるスケールアップとはより性能の良いDynoに変更すること。
・HerokuにおけるスケールアウトとはDynoを追加すること。
（これが出来るのはprofessionalプランから）


## プロセスタイプとは
・Web dyno
・Worker dyno
・One-off dyno
の3種類があります。
（Procfileという名称のファイルで指定します。）
「web:」は一つは必要
[プロセスと dyno タイプの設定](https://jp.heroku.com/dynos/configure)

参考
-
[アクセス急増にもコマンド一発で対応！ Herokuで手に入れるアプリケーションの拡張性](https://codezine.jp/article/detail/10321)
[Heroku 運用検討](https://qiita.com/RYT/items/77b77e3b0e4f88774ef3)
[Herokuアプリケーションの仮想マシンについて](http://info-i.net/heroku-ps)
[Heroku Dynoについて(youtube)](https://youtu.be/zqv8KVGIwRI)
Vuepress BlogにJSON-LDを仕込んでみた

## きっかけ
突然ですがVuepressっていいですよね。
マークダウンとVue.jsのいいとこどりで、
簡単に記事が書けますし、レイアウトの調整もVue.jsの知識でかなりカバーできます。

WordPressなどと違って、mdファイルを手元においておけるのもうれしいです。
これで[ブログ](https://www.794562.xyz)や[マニュアルサイト](https://man.catovis.com)を書いているのですが……
SEOにあたって、JSON-LDをつけてみようと思ったのが始まりです。

## 簡単にやってしまうなら
早速ググってみたところ、[こんな記事](https://code.luasoftware.com/tutorials/vuepress/vuepress-add-json-structured-data-to-page/)を一番上に見つけました。
なんと、Frontmatterの下にscriptタグ直打ちです。

確かに簡単ではありますが、記事内でも
>NOTE: This is more of a hack than an official solutions, and does not guranteed to work in the future.

とあるように、少し裏技的な様子。

しかもこれではページごとに入力する必要があります。困った……

## vue-metaを使う

というわけで、ここからが本題、
**Vuepressでvue-metaを使ってJSON-LDを自動生成します**

まずはvue-metaのインストールから

```sh
yarn add vue-meta
```

続いてvue.use()をするために[公式ドキュメント](https://vuepress.vuejs.org/guide/basic-config.html#app-level-enhancements)をもとに.vuepressフォルダ内にenhanceApp.jsを作成します。

```enhanceApp.js
import VueMeta from '../../node_modules/vue-meta'

export default ({
    Vue, // the version of Vue being used in the VuePress app
    options, // the options for the root Vue instance
    router, // the router instance for the app
    siteData, // site metadata
    isServer // is this enhancement applied in server-rendering or client
  }) => {
    Vue.use(VueMeta)
  }
```

なんでも、node_modulesへの参照は相対パスでしておかないと、build時にコケるらしいので、そこだけ注意です。

これでvue-metaを使う準備はできました。

## Postページにscriptを仕込む

最後に、ブログの投稿ページ用のレイアウトであるPost.vueにmetaInfo()を作り込んでいきます。
この書き方は[vue-metaを用いたOGPやJSON-LD用のメタタグ生成](https://qiita.com/T0000N/items/b53ce2ad670e4c966ae8)を参考にしました。

```post.vue
<script>
import PostMeta from '@theme/components/PostMeta.vue'
import Toc from '@theme/components/Toc.vue'

function createShcemaOrg(path, fm) {
  return {
    script: [
      {
        type: 'application/ld+json',
        innerHTML: JSON.stringify(
          {
            "@context": "https://schema.org",
            "@type": "BlogPosting",
            "mainEntityOfPage": {
              "@type": "WebPage",
              "@id": "https://www.794562.xyz" + path
            },
            "headline": fm.title,
            "description": fm.description,
            "image": "",  
            "author": {
              "@type": "Person",
              "name": fm.author
            },  
            "datePublished": fm.date,
            "dateModified": fm.update,
          },
          null, 2,
        ),
      },
    ], 
  }
}

export default {
  components: {
    PostMeta,
    Toc,
  },
  metaInfo() {
    return createShcemaOrg(this.$page.path, this.$frontmatter)
  }
}
</script>
```

あとは

```sh
yarn dev
```

で開発サーバーを立ち上げると……
きちんとhead内にscriptタグが生成されていました！

[リッチリザルトテスト](https://search.google.com/test/rich-results?hl=ja)でも問題ないと表示されたので、これでいけそうですね！