OmniAICreator/Qiita-1.07M huggingface dataset:
Prism コードサンプル学習：04-ViewDiscovery

# Prism コードサンプル学習：04-ViewDiscovery

## はじめに

以下の記事の続きです。
<https://qiita.com/mngreen/items/f03d9a15eee1ed77f387>

## 04-ViewDiscovery

本サンプルではRegionManagerクラスを用いて、コントロールを探し出して適応させるサンプルのようです。

```xml
<Window x:Class="ViewDiscovery.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        Title="Shell" Height="350" Width="525">
    <Grid>
        <ContentControl prism:RegionManager.RegionName="ContentRegion" />
    </Grid>
</Window>
```

```csharp
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow(IRegionManager regionManager)
        {
            InitializeComponent();
            //view discovery
            // (補足：ViewAはUserControl型で定義されたコントロール)
            regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA));
        }
    }
```

- 03-CustomRegionsでは既存のStackPanelに対してUI要素を追従させられるようにしていたのに対し、今回のサンプルではUserControlの型によって適応させている
- regionManager.RegisterViewWithRegionメソッドは[こちら](https://github.com/PrismLibrary/Prism/blob/master/src/Wpf/Prism.Wpf/Regions/RegionManager.cs#L313)
  - メソッド内部ではDIでIRegionViewRegistryのインスタンスを取得して利用している。
  - IRegionViewRegistryを継承しているのは[RegionViewRegistry](https://github.com/PrismLibrary/Prism/blob/master/src/Wpf/Prism.Wpf/Regions/RegionViewRegistry.cs)
    - 型情報からDIでViewのインスタンスを返している。(https://github.com/PrismLibrary/Prism/blob/8ae9e655657d64637150d1bf7491fe24d7b41298/src/Wpf/Prism.Wpf/Regions/RegionViewRegistry.cs#L86)
    - ただ、先程の呼び出しタイミングは分かっていない。また、同じアセンブリ内であれば、ViewとViewModelの型情報を集めてくれるという記事があったが、その回答にはなっていない。
      - ここが型情報をかき集めている？<https://github.com/PrismLibrary/Prism/tree/master/src/Wpf/Prism.Wpf/Modularity>
        - <https://github.com/PrismLibrary/Prism/blob/master/src/Wpf/Prism.Wpf/Modularity/DirectoryModuleCatalog.netcore.cs>
        - <https://github.com/PrismLibrary/Prism/blob/master/src/Wpf/Prism.Wpf/Modularity/DirectoryModuleCatalog.net45.cs>
      - アセンブリを必要に応じて読み込んでいる
        - [遅延ローディングする仕組み](https://qiita.com/mngreen/items/ce65e306bdcc4ea2382b)
        - 上記の仕組みを利用している [FileModuleTypeLoader.LoadModuleType()](https://github.com/PrismLibrary/Prism/blob/master/src/Wpf/Prism.Wpf/Modularity/FileModuleTypeLoader.Desktop.cs)
          - 読み込めていない場合は上記の遅延ローディングの仕組みで読み込み
          - IsSuccessfullyDownloaded()メソッドを読むとlock文が利用されていることからマルチスレッド動作を想定していることがわかる
        - さらに呼び出し元をたどるとModuleManager.LoadModule()メソッドから呼び出される
          - ModuleManagerFixtureクラスでLoadModule()メソッドのUTがあるので、読み深めるのもありかもしれない

深く読みすすめるにはまだ理解が浅いので、本記事ではここまでにしておき、他のサンプルも読み進めた後に戻って来ようと思います。

## おわりに

今回はRegionManagerクラスのソースコードを中心に読みました。
UTなどを実行させてみたりしたものの、仕組み全体をもう少し知らないとわからないようです。
それを明らかにできるように引き続き読んでいきます。
次回、05-ViewInjectionについて見ていこうと思います。
JavaScriptで画像プレビュー実装、画像サイズを統一したい【初心者】

画像投稿があるアプリを作成し、プレビューの実装をしたところ、、
[![Image from Gyazo](https://i.gyazo.com/4449f6c7b696f41adda7fc187135ab96.png)](https://gyazo.com/4449f6c7b696f41adda7fc187135ab96)

**画像でかすぎる！！！**
、、、となったので自分への備忘録として。

今回のプレビューの実装ではrails、Javascriptを使っています。

```javascript
document.addEventListener("DOMContentLoaded",function(){
  const ImageList = document.getElementById("image-list");
  if (!ImageList){ return false;}
  document.getElementById("item-image").addEventListener("change", function(e){
   const imageContent = document.querySelector('img');
   if (imageContent){
     imageContent.remove();
   }
 
   const file = e.target.files[0];
   const blob = window.URL.createObjectURL(file);

   const imageElement =  document.createElement('div');
   const blobImage = document.createElement('img');
   blobImage.setAttribute('src', blob);
  imageElement.appendChild(blobImage);
  ImageList.appendChild(imageElement);
  });
});
```

該当箇所のrailsはこちら↓

```ruby

<div class="img-upload">
      <div class="weight-bold-text">
        画像
        <div id="image-list"></div>
        <span class="indispensable">必須</span>
      </div>
      <div class="click-upload">
        <p>
          クリックしてファイルをアップロード
        </p>
        <%= f.file_field :image, id:"item-image" %>
      </div>
    </div>

    <%# 以下省略 %>

```


既に、JavascriptでHTML要素を取得はできているはず、、ということは
①JavaScript内でサイズを指定する
②JavaScript内にクラスを設定し、CSSでサイズ指定をする

この２択かと思い、いろいろ検索、、、すると！
Javascriptでクラスを追加できそうだ。
（↓こちらとっても参考にさせていただきました。ありがとうございました）
https://techacademy.jp/magazine/27026

ということでクラスを追加

```javascript

document.addEventListener("DOMContentLoaded",function(){
  const ImageList = document.getElementById("image-list");
  if (!ImageList){ return false;}
  document.getElementById("item-image").addEventListener("change", function(e){
   const imageContent = document.querySelector('img');
   if (imageContent){
     imageContent.remove();
   }
 
   const file = e.target.files[0];
   const blob = window.URL.createObjectURL(file);

   const imageElement =  document.createElement('div');
   const blobImage = document.createElement('img');
   blobImage.setAttribute('src', blob);
  blobImage.classList.add('preview-size');  ←こちらを追加しました
  imageElement.appendChild(blobImage);
  ImageList.appendChild(imageElement);
  });
});
```

そしてCSSに

```css
.preview-size{
    height: 150px;
    width: auto;
  }
```

を追加すると、、、

[![Image from Gyazo](https://i.gyazo.com/4f994076a056d5a6c3a077e8703db942.png)](https://gyazo.com/4f994076a056d5a6c3a077e8703db942)


###できた!!!
モチベーションを上げるために柴犬を使ってテストをしていましたが、
柴犬のことが嫌いになりそうなぐらいだったので、本当によかった。。。

もっと効率的な方法もありそうなので
引き続き勉強していきます！
間違い等あればコメントいただければと思います
IMPORTFEED関数、GASを使ってお気に入りのサイトから情報収集

# 概要
スプレッドシートのIMPORTFEED関数やGASを使って、フィードURLから簡易的な情報収集ができるということで勉強として少し使ってみました。

# IMPORTFEED関数
IMPORTFEED関数は、フィードURLをもちいてWebサイトの情報をスプレッドシートにインポートできる関数です。
Web制作に関する情報を紹介しているサイト「[コリス](https://coliss.com/)」に対して、使ってみます。


### 1. フィードURLを探す
データを取得したいWebサイトでフィードURLを探します。
開発者ツールを開き、「feed」や「rss」で単語検索すると、サイト側で設定していればそれらしきものがヒットすると思います。
見つかりました。👉　```href="//coliss.com/feed/"```

### 2. スプレッドシートで関数を使う
スプレッドシートでIMPORTFEED関数を下の形式で使います。

```txt
=IMPORTFEED(フィードURL, [クエリ], [見出し], [アイテム数])
```

| 引数 | 省略の可否 | 説明 |
|---|---|---|
| フィードURL | 必須 | フィードURLを指定する |
| クエリ | 省略可 | 取得するデータの内容を指定する |
| 見出し | 省略可 | 先頭行に列見出しを含めるかを指定する |
| アイテム数 | 省略可 | 直近のアイテムから順に、取得する数を指定する |

たとえば、
```=IMPORTFEED("https://coliss.com/feed/","items title",false,1)```
では、このサイトの最新記事タイトルを1件取得して表示させることができます。
引数をかえれば記事の概要、記事URLなども取得することができ、記事の更新とともにスプレッドシートも更新されます。

![sheet.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890454/5f477e57-7106-e6ab-fd1d-4c3e1c471453.png)

# GASを使って
parserと併用すればGASでもフィードURLから情報を取得することができます。
下記ではコリスの最新記事タイトル1件をスプレッドシートに書き出しています。
記事タイトル取得の箇所は用いるparserによってかわってくると思います。

```JavaScript
async function mainFunction() {
  // スプレッドシート
  const sheet = SpreadsheetApp.getActiveSpreadsheet();
  const feedUrl = "https://coliss.com/feed/";
  
  // RSSフィード（XML）取得
  const feed = getFeed(feedUrl);
  
  // 記事タイトルを取得
  const information = await getInformation(feed);
  
  writeInformation(information, sheet);

}
  

// RSSフィード（XML）取得
function getFeed(feedUrl) {
  
  const response = UrlFetchApp.fetch(feedUrl);
  xml = response.getContentText(); 
  
  return xml;
}

// rss-parserを用いて最新記事タイトルを取得
async function getInformation(feed) {
  
  // 別ファイルrss-parser.gsを呼び出し、インスタンスを生成
  const parser = new RSSParser();
  const parsedFeed = await parser.parseString(feed);
  const title = parsedFeed.items[0].title;

  return title;
}

// スプレッドシートに書き出し
function writeInformation(information, sheet) {
  
  const sheet1 = sheet.getSheetByName('シート1');
  sheet1.getRange(1, 1).setValue(information);
}


```

他のツールとの連携を行ったり、トリガーを設定すれば毎日決まった時間に関数を実行させることもできます。
自分好みの仕様にしてオリジナルの情報収集ツールをつくることができそうです。

---
[:christmas_tree: FORK Advent Calendar 2020](/advent-calendar/2020/fork)
:arrow_left: 12日目 [ポスト IE 時代に備えて](/megurock/items/ffb1ce938dc304829a36) @megurock さん
:arrow_right: 14日目 [GCS へのファイルアップロードをトリガーにBigQueryにデータをインポートする。](/shuhei4009/items/74619946d60665daedf8) @shuhei4009 さん
モバイルゲームの海外配信時におけるQA体制構築の注意点

# この記事について
本項目はモバイルゲームの海外配信時のQAに関する記事です。
私自身の経験をもとに、国内配信のみのQAと特に異なる項目を共有します。

# 概要
海外配信時のQAでは主に下記の点に注意すべきだと感じました。

 - **新規開発段階**
  - QAの担保領域の定義
  - 人員の確保 
  - 検証端末の確保

 - **運用段階**
  - 関係部署との連携体制の構築
  - 計数管理体制の整備

# 新規開発段階
#### QAの担保領域の定義
国内配信のみのQAの場合、検証範囲は機能や表示が主となります。
それに対し海外配信時のQAでは**言語周りの品質担保**が焦点となりやすいです。

過去の事例では具体的に下記項目について
開発チームや翻訳チームと担保責任の整理を行いました。

 - 該当の言語で表示されているか
 - 文章の内容が間違っていないか
 - 文章のニュアンスがあっているか

担保範囲によりQA側でアサインすべき人員や必要な工数が変化するため
この整理は早いタイミングで行うと良いと感じました。


#### 人員の確保
人員をアサインする際にも念頭に置いておく要素がありました。
現地環境での検証や言語の詳細な検証を行う際に
協力会社の海外拠点の方をスポットでアサインする機会がありました。
その際、**「〇日前までにアサインを決める必要がある」**というルールが国によって異なっており
国内配信のみのQAの際よりも細かなアサインスケジュールの管理を要求されました。

このルールは認識から漏れるケースが多く
**開発チームにも周知したうえで**アサインルールを定める必要がありました。
(翻訳チームの認識から漏れるケースは少なかったです)

#### 検証端末の確保
海外市場における端末(スマートフォンやタブレット)を100%カバーすることは不可能です。
そのためどこまでの検証環境で検証するかを開発チームと認識合わせする必要があります。
こちらの記事に中国における端末選定の記載があるので、ぜひ参照ください。
https://qiita.com/ohisama_rin/private/162d234a645755112b4f


# 運用段階
#### 関係部署との連携体制の構築
国内配信のみのQAにおいて、運用段階へ移行する際に**改善体制を強化**するケースが多いです。
海外配信時のQAも例外ではなく運用段階から本格的な改善体制の構築を行いました。

国内配信のみのQAと異なるのは**連携体制の種類**です。
実装された機能だけでなく翻訳された文章も一つのアウトプットなので
QAから見ると開発チームと翻訳チームのそれぞれと連携を行う必要があります。
そのため改善のための連携体制や会議体が下記の3種類になることがありました。
手間にはなってしまいますが、目的ごとに体制を構築することで
連携漏れの防止や対象者を明確にした議論が行いやすくなります。
(状況によって1つの会議体で複数種類の連携を行うこともあります)

 - 開発チーム ⇔ QAチームの連携
 - 翻訳チーム ⇔ QAチームの連携
 - 開発チーム ⇔ 翻訳チーム ⇔ QAチームの連携

#### 計数管理体制の整備
言語ごとに異なる課題があるケースが多いため、海外配信時のQAでは言語ごとの計数管理体制の構築が必要です。
加えて開発チームと翻訳チームのそれぞれに共有するデータを下記のように分けて管理/共有しています。

 - **to開発チーム**
  - どの施策で障害が多いか
  - 月ごとの障害推移がどうなっているか
 
 - **to翻訳チーム**
  - どの言語で障害が多いか
  - どの単語に関する指摘が多いか


# 最後に
この記事は以上となります。
今後、海外配信時のQAの機会は増えてくると思いますので
少しでも気づきになれば幸いです。
書いた覚えのないバリデーションが発生してしまう



下記の記述で解決したため、メモ_φ(･_･

●外部キーのバリデーション
Rails4まではアソシエーションを定義した時のbelongs_toの外部キーでnilを許可しないようにbelongs_to :user, required: trueなどのバリデーションを手動で定義していました。
ですが、rails5からは自動でnilを許可しないバリデーションが定義されるようになりました。
これを意図的に外すには下記のように定義します。

```:モデル
belongs_to :user, optional: true
```

▼下記ページより引用しました
pikawaka
https://pikawaka.com/rails/validation
Diagnostics over Internet Protocol

# DoIP
診断用プロトコルに関する覚書。

## メッセージ
|Ethernet header|TCP/UDP header |DoIP Message |
|---|---|---|
|MACヘッダ |IPヘッダ+TCP/UDPヘッダ？？|DoIPヘッダ+Payload|

## DoIPヘッダ
|項目 |Position (Byte) |Length (Byte) |
|---|---|---|
|Protocol version |0|1|
|Inverse protocol version |1|1|
|Payload type |2|2|
|Payload length|4|4|
|Payload type specific message content |8|...|

## Payload Type
### 外部ツールからの受信
|値 |Name |Connection Kind|
|---|---|---|
|0x0001|Vehicle Identification request message|UDP|
|0x0002|Vehicle identification request message with EID|UDP|
|0x0003|Vehicle identification request message with VIN|UDP|
|0x0005|Routing activation request|TCP|
|0x0008|Alive Check response|TCP|
|0x4001|DoIP entity status request|UDP|
|0x4003|Diagnostic power mode information request|UDP|
|0x8001|Diagnostic message|TCP|

### 外部ツールへの送信
|値 |Name |Connection Kind|
|---|---|---|
|0x0000|Generic DoIP header negative acknowledge|UDP/TCP|
|0x0004|Vehicle announcement message/vehicle identification response|UDP|
|0x0006|Routing activation response|TCP|
|0x0007|Alive Check request|TCP|
|0x4002|DoIP entity status response|UDP|
|0x4004|Diagnostic power mode information response|UDP|
|0x8002|Diagnostic message positive acknowledgement|TCP|
|0x8003|Diagnostic message negative acknowledgement|TCP|

## 参考
https://automotive.softing.com/fileadmin/sof-files/pdf/de/ae/poster/DoIP_faltblatt_softing.pdf
https://www.autosar.org/fileadmin/user_upload/standards/classic/4-3/AUTOSAR_SWS_DiagnosticOverIP.pdf
【Grasshopper】MeshをSurfaceにする方法

# Surface、BrepからMeshへは簡単にできるけど
Grasshopper上でSurface、BrepからMeshへ変更するときは、Surface（Brep）の後ろにMeshをつなぐだけで書き換えてくれます。とても便利ですね！ただ、このメソッドは不可逆的？というか、Meshの後ろにSurfaceをつけても自動で処理してくれません。そんなときに使えるメソッドをご紹介します。
![aaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610425/71e489ba-1167-9473-c583-6926d0fb5beb.png)


# 解決策（Face Boundaries → Boundary Surface → Brep Join）
「Face Boundaries → Boundary Surface → Brep Join」が一番簡単だと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610425/fa69e7e4-7b33-17f3-6b8d-7e6da10378e6.png)

Mesh spliteなどでうまくいかないときは、一度Surfaceにして処理するとうまくいくことがあります（経験談）ご参考まで。
OpenWrtのブリッジ化メモ

##OpenWrtのブリッジ化メモ

LuCIの「インターフェイス」を開く
「LAN」インターフェイスの編集
一般設定タブを開く
静的IPアドレスの指定
ゲートウェイのIPを指定
DNSのIPを指定
デバイス設定タブを開く
インターフェイスに「eth1」を追加する
DHCPサーバータブを開く
DHCOを無効にする（checkBoxにcheckを入れる）
チェックなしの適用

##設定環境
ルーター：WZR-HP-G300NNH
バージョン：OpenWrt 19.07.4 r11208-ce6496d796
LuCIは日本語化済み
Ubuntu 20.04 + Quartus Prime 19.1 + ModelSim intel starter edition

# Quartus PrimeからModelSimを呼び出したい
- そもそもコマンドラインからModelSimを起動することすらすんなりできない。
- [こちら](https://qiita.com/osamu620/items/2957ab357004d18785bb "Intel HLS compiler 19.1 + Ubuntu 20.0.4 LTSでサンプルをビルドしてModelSimで波形を見る")の記事を参照してターミナルから`vsim`でModelSimを起動できるようにする。
- 以下の内容はその後の話。

# ModeSimをQuartusメニューから起動できない問題
Quartus PrimeのメニューからRTL simulationを選ぶとModelSimのウインドウが開いてシミュレーションが実行されるはずだが、少なくともUbuntu 20.0.4 LTSではそうはいかない。一瞬ウインドウのようなものが表示されるがすぐ消えて、以降ダンマリである。

# 問題の原因
Linux版のModelSimはやたらと古いライブラリに依存している。その中のひとつにフォント関係の`freetype`がある。[こちら](https://qiita.com/osamu620/items/2957ab357004d18785bb "Intel HLS compiler 19.1 + Ubuntu 20.0.4 LTSでサンプルをビルドしてModelSimで波形を見る")の記事では古いバージョンのfreetypeの入手方法とModelSimへの環境変数`LD_LIBRARY_PATH`を経由したライブラリの場所の伝達方法に言及しているが、この設定はターミナルから`vsim`コマンドでModelSimを呼び出した時にしか有効にならない。

# 解決方法
`QUARTUS_ROOT_DIR`をquartusがインストールされたディレクトリとする。（Quartus Prime Lite 19.1のデフォルトだと`/home/ユーザ名/intelFPGA_lite/19.1/quartus`)また、ModelSimがインストールされているディレクトリ(デフォルトだと`/home/ユーザ名/intelFPGA_lite/19.1/modelsim_ase`))を`MODELSIM_DIR`としておく。

```
cd QUARTUS_ROOT_DIR/adm
vi eqnv.sh　（エディタは何でも良い）
```

で、ファイルの最後の方に
`export LD_LIBRARY_PATH=$QUARTUS_BINDIR:$LD_LIBRARY_PATH`という記述があるので、これを

```
export LD_LIBRARY_PATH=MODELSIM_DIR/lib32:$QUARTUS_BINDIR:$LD_LIBRARY_PATH
```

と修正する。

適当なプロジェクトを開き、Quartus PrimeからRTL simulationを選んでModelSimのウインドウが表示され、シミュレーションが動けばOK。
【訂正】RequestHeaderを使わなくても良さそう【備忘】SpringBootでJSONをPOSTする時はRequestHeaderを設定する

# 2020/12/14訂正
私の理解が間違っていました。

なぜか、第3引数で指定する型を、第2引数の型を指定するものだと思っていました。
正確には、第3引数は、**戻り値の型を指定する**でした。

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#postForObject-java.net.URI-java.lang.Object-java.lang.Class-

```diff
@PostMapping("/hoge")
fun hoge() : String {
  val uri = "foo"
  val human = Human("30","Nobkov","male")
  // jsonに変換する必要なし
-  val mapper = jacksonObjectMapper()
-  val json = mapper.writeValueAsString(human)
-  val response = restTemplate.postForObject(uri, json, String::class.java) as String
// 「as String」を使わなくても良いが「String?」になっていたので、一応キャスト
+  val response = restTemplate.postForObject(uri, human, String::class.java) as String
  return "index"
}
```

# はじめに
どーも、のぶこふです。
タイトル通りですが、だいぶ躓いたので備忘として残しておきます。
（日本語での解決サイトも特に見当たらなかったので）

もう少し詳細に書くと、ACA-PyのCloudAgentのAPIに対して、Webアプリからリクエストを投げたのですが、まーエラーが返ってきて、なんじゃらほい、といった感じです。
Swaggerからだと問題なく動いたのですが、まったく同じJsonを文字列として投げてもダメだったので、RequestHeaderを設定したら、うまく行ったよ。と言うことです。

# なにがおこっていたのか？

SpringBoot＋Kotlin＋JsonでPostをしようとしたら、次のような記述になると思います。

```kotlin
@PostMapping("/hoge")
fun hoge() : String {
  val uri = "foo"
  val human = Human("30","Nobkov","male")

  val mapper = jacksonObjectMapper()
  val json = mapper.writeValueAsString(human)

  val response = restTemplate.postForObject(uri, json, String::class.java) as String
  return "index"
}

data class Human(
  @JsonProperty("age")
  val age : String = "",
  @JsonProperty("name")
  val name : String = "",
  @JsonProperty("sex")
  val sex : String = "",
)
```

ところがどっこい、これだと次のようなエラーが発生したのです。

```
422 Unprocessable Entity: [{"age": ["Missing data for required field."],"name": ["Missing data for required field."],"sex": ["Missing data for required field."]}
```

「いや、設定しとるわっ！！」

# なんやかんやありまして

原因としては、受け手がJSONを要求していたからなのかなーと思いつつ、対応方法は次の通りです。

```diff

@PostMapping("/hoge")
fun hoge() : String {
  val uri = "foo"
  val human = Human("30","Nobkov","male")

  val mapper = jacksonObjectMapper()
  val json = mapper.writeValueAsString(human)
+ // setting header
+ val header = HttpHeader()
+ header.contentType = MediaType.APPLICATION_JSON
+ val entity = HttpEntity(json, header)
+ val response = restTemplate.postForObject(uri, entity, String::class.java) as String
- val response = restTemplate.postForObject(uri, json, String::class.java) as String
  return "index"
}
```

# おわりに

やっぱり、調べ物しているより、コード書いているのが良い。

今回はここまでです。
ありがとうございました。


# 参考
https://www.it-swarm-ja.tech/ja/java/post-json%E3%81%AEresttemplate%E3%82%92%E4%BB%8B%E3%81%97%E3%81%9F%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88/970758999/
サポートモジュール/使い方と注意点

サポートモジュール

説明）繰り返しをしている統合テストコードをまとめることができるメソッド。RSpecに用意されているメソッド等をまとめる機能。

使用方法）specディレクトリにディレクトリを用意して、同ディレクトリ内にファイルを作成する。そのファイル内に、まとめたいコードをメソッド名を設定して記述していく。その際、以下の作業が必要となる。

作業）rails_helper.rbのコメントアウトの消去
　　　（コメントアウトの付け方外し方はcommandキー　＋　/キー）
      (rails_helperとは、railsにおいてRSpecを使用する際に共通の設定を書いておくファイルのこと。)
　　　モジュールの設定
ABC 079C Train Ticket をPythonで解いてみた。

# はじめに

今回はAtCoderの『ABC 079C Train Ticket』をPythonで解いてみました。
# 問題

[ABC 079C-Train Ticket](https://atcoder.jp/contests/abc079/tasks/abc079_c)

# 方針
- "+"か"-"が入るパターンを全探索（再帰）
- "+"と"-"で分岐
- 合計が7にならば数式を出力させる
 
# 実装

準備として入力を変数に代入します

```python
s = input()
```

次に再帰の関数を定義していきます。

- "+"と"-"で分岐するように全探索し、その中に合計7になる数式が見つかれば式を出力して終了する。
- 合計値を出力するので戻り値を分岐した数式の和となるように設計する

```python
def dfs(i, f, sum):
    # 全検索
    if i == 3:
        # 合計が7になる数式
        if sum == 7:
            # 式を出力して終了
            print(f + "=7")
            exit()
    else:
        # + と - で分岐する
        dfs(i + 1, f + "+" + s[i + 1], sum + int(s[i + 1]))
        dfs(i + 1, f + "-" + s[i + 1], sum - int(s[i + 1]))
```

最終的に再帰の関数に初期値を設定してprintで出力します。

```python
dfs(0, s[0], int(s[0]))
```

# 答え

```python
def dfs(i, f, sum):
    if i == 3:
        if sum == 7:
            print(f + "=7")
            exit()
    else:
        dfs(i + 1, f + "+" + s[i + 1], sum + int(s[i + 1]))
        dfs(i + 1, f + "-" + s[i + 1], sum - int(s[i + 1]))
s = input()
dfs(0, s[0], int(s[0]))
```
今回は『全検索(再帰)』 『条件式』が分かれば解けた問題でした。
APN Ambassador Program は世界標準！

こんにちは。アマゾン ウェブ サービス ジャパンのパートナーソリューションアーキテクトの大林です。

[Japan APN Ambassador Advent Calendar 2020](https://qiita.com/advent-calendar/2020/japan-apn-ambassador) が、日本の APN Ambassador の皆様が著者になり 12 月 1 日に始まり、本日は、11 日目となります。

11 日目の本日は、「APN Ambassador Program は世界標準！」と題しまして、3 日目の [APN Ambassador ってなんだ？] (https://qiita.com/keizoa/items/343af854447f53f7570b) をもう少し深掘りした内容をお届けできればと思います。

なお、本投稿内容につきましては、私個人の意見であり、所属企業・部門見解を代表するものではないことご了承いただけると幸いです。

##APN Ambassador とは？
詳細は、[APN Ambassador ってなんだ？] (https://qiita.com/keizoa/items/343af854447f53f7570b) の投稿をご覧いただければと思いますが、こちらのブログの一部を引用すると、こんな感じですね。

>APN とは AWS Partner Network の略称です。 APN Ambassador Program とは世界中の APN Consulting Partner から卓越した技術力を持ち、社外への情報発信（セミナーでの発信、Blog や書籍での発信）をしているメンバーが、日本のみならず世界中の APN パートナーの中から選出される Program です。

ここでポイントとして改めてお伝えしたいのは、「世界中のAPNパートナーの中から選出されるプログラム」という点です。

##APN Ambassador Program は世界共通のプログラム
APN Ambassador Program は世界中の APN パートナの中から選出される世界共通のプログラムとなります。世界共通の基準で選抜され、認定されます。

また、認定を継続するためには、毎年、世界共通で定められた基準を満たしていただく必要があり、そのためには、継続的にブログやホワイトペーパー、記事やプレゼンテーションなど様々な方法で発信を継続していただく必要があります。日本からは、2020 年 12 月現在、20 名の方が APN Ambassador として選出されており、様々な方法で発信を継続していただいております。

活動自体のイメージは、[Japan APN Ambassador Advent Calendar 2020] (https://qiita.com/advent-calendar/2020/japan-apn-ambassador) の 7 日目の投稿である「[クラメソとブログと登壇とアンバサダーとハマコー] (http://xn--o9jaaa30aqci2aq8evbznj3fvg9azk4c2f3he6125t50rf/)」が参考になりますので、オススメです。

今回の [Japan APN Ambassador Advent Calendar 2020] (https://qiita.com/advent-calendar/2020/japan-apn-ambassador) も、APN Ambassador であるアイレット株式会社の栄野川さんがリードとなり、自発的に推進いただいた施策であり、日本の APN Ambassador が投稿している内容となります。12 月 25 日の最終日までぜひお楽しみいただければと思います！

##世界中の APN Ambassador が同じことをやっている
実際に、世界中の APN Ambassador はどんな活動をしているのでしょうか？

世界中の APN Ambassador の活動の一部を取り上げたブログがあるのでご紹介します。

[APN Ambassadors Are Passionate About Sharing Their AWS Technical Expertise] (https://aws.amazon.com/jp/blogs/apn/apn-ambassadors-are-passionate-about-sharing-their-aws-technical-expertise/)

こちらのブログの「What Have Our APN Ambassadors Been Up To?（意訳：APN Ambassador のこれまでの歩み）」のセクションで、世界中の APN Ambassador の投稿内容の例があげられています。

日本からも以下のように取り上げられています。

>Japan

>* [Applying Spot Instances with AWS Batch to Optimize Costs] (https://aws.amazon.com/jp/blogs/psa/apn-ambassadors-blog-002/) – By Yutaka Hiroyama, iret

>引用：[APN Ambassadors Are Passionate About Sharing Their AWS Technical Expertise] (https://aws.amazon.com/jp/blogs/apn/apn-ambassadors-are-passionate-about-sharing-their-aws-technical-expertise/)

こちらは、日本語の APN Blog に寄稿いただいたものとなりますが、株式会社BeeX 那須さん、株式会社サーバーワークス 城さんにも寄稿いただいています。[こちら] (https://aws.amazon.com/jp/blogs/psa/tag/ambassador-blog/)のリンクから一覧を参照することができます。

先日、APN Ambassador Global Summit という世界中の APN Ambassador が一同に集まるイベントがオンラインで開催され、日本の APN Ambassador からも日々の活動が評価され、5 名の方が表彰されました。

##さいごに
2020 年も残すところあと一ヶ月を切りましたが、APN Ambassador のみなさまは、来年も継続的に活動いただくことと思います。日本のエンジニアが、日本国内のみならず世界で活躍できるようなサポートをこれまで以上にさせていただければと思っております。

まずは、[Japan APN Ambassador Advent Calendar 2020] (https://qiita.com/advent-calendar/2020/japan-apn-ambassador) を残り14日、お楽しみください！
JS study-const add = x => y => x + y

There is a piece of JavaScript codes below:


const add = x => y => x + y
var c = add(1)(2);
When executed, c is equal to 3 in the runtime. Why?

Let’s debug in Chrome.

1. Only one argument, 1. Pay attention to the highlight part in line 19. It means argument x is set to 1.

/wp-content/uploads/2015/12/clipboard1_854423.png



Check in console, x = 1, y is not available at this time.

/wp-content/uploads/2015/12/clipboard2_854424.png

And here below gives us a hint that add(1)(2) will first bind x to 1, and return a new function f(y) = x + y = 1 + y.

/wp-content/uploads/2015/12/clipboard3_854425.png

2. when clicking step into again, pay attention to the highlight part in line 21. It means now the function f(y) = 1 + y is executed, and this time, the argument y, is set as 2.

/wp-content/uploads/2015/12/clipboard4_854429.png

And the argument x’s value 1 is still preserved in the context via Closure.

/wp-content/uploads/2015/12/clipboard5_854430.png

So finally we get 3 as result. So const add = x => y => x + y just creates a curried function which has exactly the same function as below:


function add(x){
  return function(y){
  return x + y
  }
}
Nuxt.jsでobject-fitしたvideoコンポーネントを作る

# 手順1
https://github.com/constancecchen/object-fit-polyfill/blob/master/dist/objectFitPolyfill.min.js
ここでjsをダウンロードして、`static/assets/js/object-fit-polyfill.min.js`に配置

# 手順2
`nuxt.config.js`でjsファイルを読み込ませる

```javascript:nuxt.config.js
export default {
  head: {
    script: [
      { src: '/assets/js/object-fit-polyfill.min.js', body: true }
    ]
  }
}
```

# 手順3
ビデオコンポーネントの作成

```html:components/atoms/video.vue
<template lang="pug">
.a-video(:class="{'is-cover': cover}")
  video.a-video-movie(v-bind="bindMovie")
</template>

<script>
export default {
  props: {
    src: { type: String, required: true },
    poster: { type: String, required: false, default: '' },
    autoplay: { type: Boolean, required: false, default: false },
    loop: { type: Boolean, required: false, default: false },
    playsinline: { type: Boolean, required: false, default: false },
    muted: { type: Boolean, required: false, default: false },
    ext: { type: String, required: false, default: 'mp4' },
    res: { type: Boolean, required: false, default: false },
    cover: { type: Boolean, required: false, default: false }
  },
  computed: {
    bindMovie() {
      return {
        src: this.srcset(),
        poster: this.poster,
        autoplay: this.autoplay,
        loop: this.loop,
        playsinline: this.playsinline,
        muted: this.muted,
        type: 'video/mp4',
        'data-object-fit': this.cover ? 'cover' : false
      }
    }
  },
  methods: {
    srcset() {
      const res = this.$store.getters.innerWidth < 768 ? '_sp' : '_pc'
      return `${this.src}${this.res ? res : ''}.${this.ext}`
    }
  }
}
</script>

<style lang="stylus" scoped>
.a-video
  line-height 0

  &.is-cover
    position relative
    overflow hidden
    width 100%
    height 100%

    .a-video-movie
      position absolute
      width 100%
      height 100%
      top 0
      left 0
      object-fit cover
</style>

```

あと、初期化時やリサイズ時、良きタイミングでこれ使う

```javascript
objectFitPolyfill()
```

```javascript
mounted() {
  objectFitPolyfill()
  window.addEventListener('resize', objectFitPolyfill())
}
```

# 参照

- [object-fit-polyfill](https://github.com/constancecchen/object-fit-polyfill)

# Nuxt.jsのそのほか

- [Nuxt.jsを使う](https://qiita.com/oblivion/items/3488e41af630a3b07ff6)
Angularでハイライト実装




Angularでハイライト機能の実装をしたので記録用として残します。
今回は [angular-text-input-highlight](https://github.com/mattlewis92/angular-text-input-highlight#installation "angular-text-input-highlight") を参考に実装。

##　 開発環境
- Angular6(Typescript)

##　使用したライブラリ
- angular-text-input-highlight

##  実装
### npmからインストール

```
$　npm install --save angular-text-input-highlight
```

### アプリのどこかにスタイルシートを含める
```angular:angular.json
"styles": [
node_modules/angular-text-input-highlight/text-input-highlight.css
],
```
### moduleに追記する

```typescript:sample.module.ts
import { NgModule } from '@angular/core';
import { TextInputHighlightModule } from 'angular-text-input-highlight';


@NgModule({
  imports: [
    TextInputHighlightModule
  ]
})
export class SanpleModule {}
```
### htmlの実装
ハイライトの関数を呼び出すために仮でボタンを設置

```html:sample.component.html
 <button class="btn" (click)="addTags()">
   <i aria-hidden="true">ハイライトボタン</i>
 </button>
 <div mwlTextInputHighlightContainer class="form-group" >
   <textarea
    mwlTextInputElement
    rows="4"
    class="form-control"
    [(ngModel)]="sampleText"
    #textarea
    >{{ sampleText }}
  </textarea>
  <mwl-text-input-highlight
   [tags]="tags"
   [tagCssClass]="'bg-blue'"
   [textInputElement]="textarea"
   >
  </mwl-text-input-highlight>
 </div>
```

### cssの実装

```css:sample.component.scss
 .bg-blue {
   background-color: lightblue;
 }

.bg-pink {
  background-color: lightcoral;
}
textarea {
 width: 500px;
}
```
### tsファイルの実装

```typescript:sample.component.ts
 import { ViewEncapsulation } from '@angular/core';

import { HighlightTag } from 'angular-text-input-highlight';

@Component({
  selector: 'app-sample',
  templateUrl: './sample.component.html',
  styleUrls: ['./sample.component.scss'],
  encapsulation: ViewEncapsulation.None,
})

export class SampleComponent implements {
  sampleText: string = 'Hello @mattlewis92 how are you today?\n\nLook I have a #different background color!';

  tags: HighlightTag[] = [];

  public addTags(): void {
    this.tags = [];

    const matchMentions = /(@\w+) ?/g;
    let mention;
    // tslint:disable-next-line
    while ((mention = matchMentions.exec(this.sampleText))) {
      this.tags.push({
        indices: {
          start: mention.index,
          end: mention.index + 1,
        },
        data: mention[1],
      });
    }

    const matchHashtags = /(#\w+) ?/g;
    let hashtag;
    // tslint:disable-next-line
    while ((hashtag = matchHashtags.exec(this.sampleText))) {
      this.tags.push({
        indices: {
          start: hashtag.index,
          end: hashtag.index + hashtag[1].length,
        },
        cssClass: 'bg-pink',
        data: hashtag[1],
      });
    }

 }

```
#### 補足
- matchMentions はハイライトさせたい文字を正規表現で記載する。
- 下記でthis.sampleTextと記載している部分がハイライトさせたい文章全体。

> while ((mention = matchMentions.exec(this.sampleText)))

### 動作確認
**ボタンを押す前**　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411666/776f35aa-9f18-6f86-c19f-3c4a977bce4b.png)
**ボタンを押した後**　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411666/10431879-b996-85ac-270b-7afdf0d4870e.png)


# 　おわりに
他にもAngularでハイライトが可能なライブラリがありましたが、これが一番スムーズに実装できました。
【備忘録】フレームワークとは？

# フレームワークとは？
```
webアプリケーションを作る際に必要な基本的な機能が、あらかじめ用意されているプログラムの雛形。
```
なるほど。私が勉強したものだと Ruby on Rails がそれに当たるのか。
確かに rails new のコマンドで新規ディレクトリを作成すると、中に色々なファイルができていたっけ。

### フレームワークを使う理由は？
簡単にアプリケーションを作るために必要なのはわかったけど、他にも理由があるのだろうか。

・開発時間の短縮
・ある程度の質
・開発後のメンテナンス
・複数人での開発に便利

なるほど・・・正直ピンときません。

フレームワークはなんですか？って聞かれたときや、フレームワークはこれを使います。って言われた時にドギマギしないように、覚えておく。
JavaScriptフレームワークのバリデーション機能を関数提供する実装

# フレームワークによくあるバリデーション機能を関数で提供する

※こちらでフレームワークっぽく色々実装したバージョンを公開しました
https://qiita.com/ikuo0/items/dd0bda8a84cdd1ae43e2

JavaScriptフレームワークによくあるオートバリデーション機能を作ります。
フレームワーク全体の使い方を覚えるのは面倒だけどオートバリデーションは欲しいという人向けに一例として1行テキストの場合の実装例だけを書きます。
フレームワークを使わずに済むなら使いたくないというひねくれた人向けのお話です。JQueryを使っています。

## 実装

``` javascript
function addAutoSyncronizedToText(obj, id, opt) {
    var $elm = $(id);
    var minLength = "min" in opt ? opt["min"]: false;
    var maxLength = "max" in opt ? opt["max"]: false;
    obj[id] = "value" in opt ? opt["value"]: "";
    var $warn = $("<div>", {// 警告メッセージ用のDIV
        "css": {
            "display": "none",
            "position": "absolute",
            "border-style": "solid",
            "border-width": "2px",
            "border-radius": "5px",
            "border-color:": "#000000",
            "background-color": "#ffffff",
            "color": "#ff0000",
            "font-weight": 800,
        }
    });
    $("body").append($warn);
    $elm.on("change", function() {
        $warn.hide();
        var val = $elm.val();
        obj[id] = val;
        var warnText = false;
        if(minLength && val.length < minLength) {
            warnText = String(minLength) + "文字以上必要です";
        }
        if(maxLength && val.length > maxLength) {
            warnText = String(maxLength) + "文字以下です";
        }

        if(warnText !== false) {
            var pos = $elm.offset();
            var x = pos.left;
            var y = pos.top + $elm.outerHeight();
            $warn.text(warnText);
            $warn.css({"top": y, "left": x});
            $warn.show();
        }
        
        if("onChange" in obj) {
            obj["onChange"].apply(obj, [id, val]);
        }
    });
}
```

## 使い方

``` javascript
// 使い方
var obj = {
    "onChange": function(id, value) {
        console.log("id", id);
        console.log("value", value);
    }
};
addAutoSyncronizedToText(obj, "#name", {"min": 1, "max": 15});
```

変数 obj に "#name" 等のＩＤと完全に連動したキーで値が保存されます、全体を一括でバリデーションする事はできませんが１つ１つについては自動的にバリデーションして警告を出す事が可能です。
改造してエラーの有無を obj に残しても良いと思います。

## 実際の見え方
![00.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104691/b766037c-8db6-e4a9-f563-33476e4abbe1.png)

![01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104691/4a0ca14d-aa54-c00e-e134-9ad2417199cb.png)

![02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104691/831b0a26-8d51-3a70-90c0-e456a84658dc.png)


以上です。
Unity ShaderGraph レシピまとめ

| 記事 | 　 |
|:---|:-:|
| [シンプルなグリッド](https://qiita.com/Teppy/items/34d8ea7de87f94458ab2)  |  ![スクリーンショット 2020-12-10 0.07.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/ad3b01a7-d184-c980-ae5d-54098b38b0b1.png) |
| [シンプルなグリッド（色指定）](https://qiita.com/Teppy/items/d584b040900debb354f4) |  ![スクリーンショット 2020-12-10 1.01.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/b506aefb-0154-a7c7-c035-a84501b12d4a.png) |
| [市松模様](https://qiita.com/Teppy/items/dc8720b22dcaf6c2ed66) | ![スクリーンショット 2020-12-11 0.45.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/f97c8f2b-1846-dca2-4541-f322ff496767.png)　 |
| [水玉模様](https://qiita.com/Teppy/items/f5d0de77e91b2af932e9) | ![スクリーンショット 2020-12-11 1.55.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/535a239b-b16b-7ec3-ca3d-6bb584b3a4a8.png)　 |
| [HEX柄](https://qiita.com/Teppy/items/7c3960f7f237c9a67d86) | ![スクリーンショット 2020-12-18 1.07.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/e8b13df3-3285-be94-3c5b-fac0e59924c9.png) |
| [ランバート反射ライティング](https://qiita.com/Teppy/items/28f653b8a9bcf845556f) | ![gif_animation_008.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/6e40f2de-77f1-7f35-8b2f-7bb7788de34b.gif)
| [トゥーンシェーディング](https://qiita.com/Teppy/items/16dbbbe67147bab6ab23) | ![gif_animation_007.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/8f4948bd-ab9f-254f-7713-6ca4b1fc3384.gif)
| [リムライト](https://qiita.com/Teppy/items/1c463acba460ee3c5856) | ![gif_animation_009.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/4a0eb046-33c6-6cb1-074b-4f3081852358.gif) |
| [半透明](https://qiita.com/Teppy/items/06baca3b5532ec006f03) | ![スクリーンショット 2020-12-28 15.30.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/1a1ffa87-0400-b6c7-3d4c-ff4b7592d205.png) |
| [薄膜シェーダ（アルファ値版）](https://qiita.com/Teppy/items/f307004241cf97539fac) | ![gif_animation_010.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/75d957ab-91af-5192-8a70-ecabcab1bbb6.gif) |
| [薄膜シェーダ（テクスチャ版）](https://qiita.com/Teppy/items/40e85620510329ad6c56) | ![gif_animation_011.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/3d5155f0-7368-54f2-9e90-d30993b23e36.gif) |
| [グレースケールフィルタ](https://qiita.com/Teppy/items/330f8c4fe18a0c75de69) | ![gif_animation_017.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198311/2ac46137-1fff-12a6-1080-9def35978eb2.gif) |
| [text](url) |  |
【Rails】simple-calendar　カレンダーから直接日付を取得する

# はじめに
本記事は、 駆け出しエンジニアの第一歩！[AdventCalendar2020 11日目の記事](https://qiita.com/advent-calendar/2020/programming-beginner)です。
RailsでSimple-calenderを導入した時につまづいた点に関して記事にします。

今回の記事のようなケースに陥ることはあまりないと個人的には思います。というのも日付のカラムがあれば事足りるからです。

また、created_atから日付情報を取得するという手もあるが、今回はそうではない（違う日付の登録もできるような）仕様にしたいのでしません。

私の場合、計算された合計値を保存するテーブルがないにもかかわらず、合計値をカレンダーに出力したため、日付情報のない単なる数字のリンクができるだけでした。そのため、カレンダーから直接日付情報を取ってくる必要がありました。

# 開発環境
IDE：Cloud9
Ruby：2.6.3
Rails：5.2.4
simple-calendar：2.4.1

# 困っていること
カレンダーに表示されている総カロリーのリンクをクリックすると、その日付ページの詳細情報が表示されるようにしたい。しかし、総カロリーは合計値を表示しているだけなので、総カロリーが属するテーブルがなく、日付の情報を取得することができない。
やりたいこととしては、viewの情報（日付）をcontrollerへ渡したい。
![スクリーンショット 2020-12-11 15.15.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869111/d8c864ce-bf17-008a-fe4b-042760d7ecc8.png)
![スクリーンショット 2020-12-11 16.05.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869111/843d9910-1619-8eb9-bbf0-c7b63c8597b2.png)


# 解決までの道のり
まず、カレンダーのviewは以下のようにしました。（<%= date %>は確認のため付けてるだけです。）

```ruby:view
総カロリー：<%= link_to sum, users_my_page_show_path %> kcal
<%= date %>
```
カレンダーに<%= date %>を出力するようにすると、カロリーの後ろに日付が表示される。つまり、パラメーターとして拾ってこれていないだけで、日付の情報は確かにある。
![_2020-11-18_10.04.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869111/e9c08e8f-0ae0-f825-edfe-589a54ddc8dd.png)
今のままでは当然、どのリンク先もusers_my_page_pathに飛ぶだけで意味がない。どのリンクにカーソルを合わせても以下のように表示されるだけである。
![_2020-11-18_10.03.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869111/77a0bbb8-6ccc-313f-83e7-dde5cefbf4b3.png)

そこで、リンクの引数に（date）を追加してみる。するとカーソルを合わせた日付の情報がurlに乗っていることが確認できた！

```ruby:view
総カロリー：<%= link_to sum, users_my_page_show_path(date) %> kcal
<%= date %>
```
![_2020-11-18_10.03.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869111/09a0ef42-a560-4303-d3f2-871de0a454fa.png)

この状態でコントローラ側をデバックした後、リンクをクリックし、パラメーターのありかを突き止める。
paramsを入力すると、乗っているパラメーターを見ることができる。どうもformatというところに日付の情報が入っているらしい。
![_2020-11-18_10.06.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869111/82bd8fce-f3c6-8c12-a046-e08734800112.png)
結果、コントローラで以下のように定義してあげることで、カレンダーから直接日付を取得することができた。あとは、表示したい詳細情報に@day_paramsを渡してあげれば、カレンダーの日付に基づいた内容を表示できる。

```ruby:controller
def my_page_show
  @day_params = params[:format]
end
```
# 参考記事
https://poyopoyo0.hatenablog.com/entry/2016/02/29/100431
# まとめ
参考記事の方が参考になるかもです。
【kotlin】Gsonでenumを使う

以下のようにFruit enumを持つ、PersonというデータクラスをGsonでjson文字列に変換する例を考えます。

```kotlin

enum class Fruit(val value: String) {
    appleKey("appleValue"),
    bananaKey("bananaValue");
}

data class Person(val name: String, val favoriteFruit: Fruit) {
}
```

単純に変換すると次のようになります。

```kotlin

val jsonString = Gson().toJson(person);
Log.d(TAG, "${jsonString}")
// 出力
// {"favoriteFruit":"appleKey","name":"Jack"}
```

favoriteFruitに `appleKey` とenumのキーの値が文字列で入ってきています。
これで良ければ良いのですが、enumの値の方(appleValue)に変換してjsonを出力したいことが多いです。

以下のようにSerializerを登録することで実現できます。

```kotlin

val jsonString = GsonBuilder()
        .registerTypeAdapter(Fruit::class.java, object : JsonSerializer<Fruit> {
            override fun serialize(src: Fruit?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement {
                src?.let {
                    return JsonPrimitive(it.value)
                }
                return JsonNull.INSTANCE
            }
        })
        .create()
        .toJson(person)
Log.d(TAG, "${jsonString}")
//出力
//{"favoriteFruit":"appleValue","name":"Jack"}
```

enumの値 `appleValue` を使ってjson文字列を作成することができました。
RSpecのインスタンス変数をletに置き換え

# はじめに
ポートフォリオにおいて、RSpecを使った統合テストを実装したのですが、
インスタンス変数はletで置き換えたほうが良いよとアドバイスをいただき、早速修正してみました！

# letのメリット（インスタンス変数と比較）
## 遅延評価
- 遅延評価とは、必要なときだけ評価されること（代入した変数が参照されたタイミングで評価されるもの）。
- 必要ないときまで処理しなくていいので、余計な処理をしなくてすむ。
- 無駄な初期化の時間をなくすことができる。
- 結果、作業量もメモリも少なく済みパフォーマンスが上がる。

# いざ、置き換え
修正前

```ruby:spec/system/posts_spec.rb
before do
  @user = create(:user)
  login_as(@user)
end
```

修正後

```ruby:spec/system/posts_spec.rb
let(:user) { create(:user) }
before do
  login_as(user)
end
```

factoryファイルを元にDBにユーザ情報を作成、前者は@user、後者はuserという変数に代入されている。
上記の＠userは、ログインするためだけに作成しており、毎回無駄な処理をさせてしまっていた。。。

# letの注意点
遅延評価があだになることがあるらしい。
letの遅延評価は各it,example内で定義したものが呼ばれない限り、実行されなくなるとのこと。たしかに、以下を実行したところ、エラー発生。

修正前

```ruby:spec/system/posts_spec.rb
context '投稿編集' do
 it '自分以外のユーザーの投稿は編集できない' do
   @post = create(:post)
 end
end
```

修正後（エラーあり）

```ruby:spec/system/posts_spec.rb
context '投稿編集' do
 let(:post) { create(:post) }
 it '自分以外のユーザーの投稿は編集できない' do
  # @post = create(:post)
 end
end
```

そこで、` let`を` let!`に変更

再修正後（エラーなし）

```ruby:spec/system/posts_spec.rb
context '投稿編集' do
 let!(:post) { create(:post) }
 it '自分以外のユーザーの投稿は編集できない' do
  # @post = create(:post)
 end
end
```

` let!`にした場合、テストを行う前(before doと同じタイミング)に実行され、itごとに変数が初期化されるとのこと。

# 終わりに
遅延評価ありがたい！そして` let`使いやすい！
ローカル変数を` let`で置き換えるのもアリとのことなので、これから` let`をどんどん取り入れていきたい。
ただし、使用するときは、以下のような遅延評価ゆえの動きも意識していこうと思う！

```ruby:失敗例
let(:blog) { Blog.create(title: 'RSpec必勝法', content: 'あとで書く') }

it 'ブログの取得ができること' do
  expect(Blog.first).to eq blog
end
```

```ruby:成功例
let!(:blog) { Blog.create(title: 'RSpec必勝法', content: 'あとで書く') }

it 'ブログの取得ができること' do
  expect(Blog.first).to eq blog
end
```

# 参考サイト
- [RSpecのletを使うのはどんなときか？（翻訳）](https://qiita.com/jnchito/items/cdd9eef2ed193267c651)
- [letの遅延評価で困る具体例](https://qiita.com/namitop/items/4d0a490cfd52e74d6f48)
- [使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」](https://qiita.com/jnchito/items/42193d066bd61c740612)
- [RSpecのletでcreateした時に気をつけること　〜遅延評価〜](https://qiita.com/marlion7/items/3e72aed204083c97d44d)
- [rspec 基本まとめ　let など （基本+α編）伊藤さんの記事より抜粋](https://qiita.com/tech-aki/items/0fcb9fa5e0f0bd5ec3b4)
- [遅延評価とは何か](https://qiita.com/BooookStore/items/2627f33764dbabbcf55f)
- [【小ネタ】LINQの「遅延評価」「即時評価」って何が違うの？](https://qiita.com/4_mio_11/items/dec20929f189bb2b1a8e)
Nuxt.jsでstore使う

# 作成

コマンドで`store`ファイルのテンプレートを作成する

```shell
$ touch store/index.js
```

ファイルの内容を書き換える

```javascript:store/index.js
export const state = () => ({
  counter: 0
})

export const mutations = {
  setIncrement (state) {
    state.counter++
  }
}

export const actions = {
  setIncrement (context) {
    context.commit('setIncrement')
  }
}

export const getters = {
  getCounter(state) {
    return state.counter
  }
}
```

# 使用

```javascript
// stateの取得
this.$store.state.count

// mutationsの実行
this.$store.commit('setIncrement')

// actionsの実行
this.$store.dispatch('setIncrement')

// gettersの実行
this.$store.getters.getCounter
```

# Nuxt.jsのそのほか

- [Nuxt.jsを使う](https://qiita.com/oblivion/items/3488e41af630a3b07ff6)
【OpenCV】覚えておくと得した気がするちょっとしたこと：cv2.WaitKey()

今まで何気にルーチンワークになってた処理が、ちょっとした工夫ですごく使いやすくなって目から鱗、みたいなことが時々あります。都度、覚え書きにしておこうと思い立ちまして。

# OpenCV のウィンドウ トラックバーの動きをスムーズに
画像処理やってて、パラメータをウィンドウに付けたトラックバーで動かしながらリアルタイムに挙動を見る、というのはよくやります。この時、画像処理が重たいとトラックバーの動きがぎこちなくなって、ストレスを感じます。ちょっと工夫して改善してみました。
# 実行環境
２０２０年１２月現在、一般的な環境と言っていいと思います。
`Python 3.7.4`
`OpenCV 4.4.0`
`MacOS 11.0.1`
# トラックバー移動の遅さにストレスを感じる例
何でもいいんですが、重い画像処理の例として、Lookup Table を使わずに、forループでガンマ補正をかけるっていうのをやってみます。素材は `lena.png` で。
***実際やらないですが、あくまで分かりやすい例として・・・***

まず、画像をグレイスケールで読み込み、それを表示するためのウィンドウを作ります。

```python:
import cv2

def nothing(x):
    pass

img_gray = cv2.imread('lena.png',0)

cv2.namedWindow('lena gamma',cv2.WINDOW_NORMAL)
cv2.createTrackbar('gamma','lena gamma',200,300,nothing)
```

createTrackbar の引数で指定するコールバック関数をnothingと定義してます。何もしません。

次に、トラックバーで指定したガンマの値で画像にガンマ補正をかけます。

```python:
while(cv2.getWindowProperty('lena gamma',cv2.WND_PROP_VISIBLE)>0):
    gamma = cv2.getTrackbarPos('gamma','lena gamma') / 100
    if gamma == 0:
        gamma = 1/100
    img_gamma = img_gray.copy()

    for i in range(img_gamma.shape[0]):
        for j in range(img_gamma.shape[1]):
            img_gamma[i,j] = int(255 * (pow(img_gamma[i,j]/255,1/gamma)))
```

せっかくの numpy の高速さが台無しな感じがよく出てます。
gamma の値は、見た目をよくするため、トラックバーで指定するのは100倍値としました。なので、getTrackgbarPos で取ってきた際に、100分の1 にしてます。

そして、結果を表示します。while ループの続きですね。

```python:
    cv2.imshow('lena gamma',img_gamma)
    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        break

cv2.destroyAllWindows()
```
同じディレクトリに lena.png を置いて実行すると、こんな感じのウィンドウが出てきます。
![スクリーンショット 2020-12-11 14.50.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260381/887c43ac-3788-2eb7-5743-182b786cb15e.png)
下の方のトラックバーでガンマの値を 0.01 〜 3.00 の範囲で指定できて、リアルタイムで画像が更新されるわけですね。
ただ、画像処理が重すぎて、トラックバーがなかなかうまく動いてくれません。精神的イライラ感がつのり、使えたもんじゃないです・・・

# ちょっとした改善策
この例では、根本的な改善は、ルックアップテーブルなど使えば簡単なんですが、場合によってはアルゴリズムの高速化が難しい場合だってあります。そんな時の折衷案的な改善策です。

この例では、

> key = cv2.`waitKey(1)` & 0xFF

 と、whileループを高速回転させてますが、これを低速回転にすれば、単位時間あたりの画像処理の回数が減って CPU がトラックバーの移動にさく余力ができるようです。

例えば、

> key = cv2.`waitKey(200)` & 0xFF

としてあげると、まぁ許せる程度にはトラックバーがスムーズに動いてくれるようになりました。

- ただし、画像の更新頻度は 0.001秒 から 0.2秒に大幅ダウンですね。でも、人間の感覚では十分許容できる範囲だと思います。

# まとめ
OpenCV でウィンドウのトラックバーの動きが鈍いとき、とりあえず簡易に その場しのぎする方法でした。処理にリアルタイム性が厳しく求められる場合は使えませんが、現実解としてはありじゃあないかと思います。
UIStepperの値を設定する。最小、最大

#### 0.UIstepper
appleのドキュメントをGoogle日本語訳すると。”スロットマシン”のメタファーと書いてありました。


####1. コード

```
  @IBOutlet weak var Label: UILabel!
    
    @IBAction func UIstepper(_ sender: UIStepper) {
        //attrbutesインスペクタでも指定可能
        //AnyObjectの時は　let stepper = sender as! UIStepper　でキャスト
        
        //Double型
        sender.minimumValue = 0
        sender.maximumValue = 100
        sender.stepValue = 5
        
        //Bool型
        sender.autorepeat = true
        sender.wraps = true
        sender.isContinuous = true
        let num = Int(sender.value)
        
        Label.text = String(num)
    }
```

####2.解説
UIstepperは最大値、最小値、ステップを変更できます。
他にもBool型でautorepeat(長押し)、wraps(maxまで進むと0に戻る)、Continuous(継続的なイベント)などもあり変更できます

UIstepperの値はsender.Valueで取得できました。

####3.関連記事
[Qlita](https://qiita.com/koogawa/items/67f446e731f3f5959d05[Qlita])
[Qlita]
[Qlita]
####4.最後に
スロットマシンってなんやろ。
always_combのセンシティビティリストの罠

always_combは便利なSystemVerilogのブロックですが、ちょっと意外な落とし穴があった。
自分用メモ。

```verilog
always_comb begin
  a = b;
  b = c;
end
```

だと、bはセンシティビティリストに入らない。要注意。
a,bが出力ポートでlogicだと、書けてしまったりする。
上記のような記述は、そもそも怪しい記述ではあるけれど。

always_combは同じブロックでwriteした変数を中間変数とみなすらしい。
always_comb は常に入力から出力まで一直線の関数形式を意識すること、と、いつものDaveさんが言っていた。

https://verificationacademy.com/forums/systemverilog/sensitivity-list-alwayscomb-block
https://electronics.stackexchange.com/questions/343041/systemverilog-sensitivity-list-of-always-comb

問題はinterfaceで、

```verilog
always_comb begin
  a = INT.x;
  INT.y = b;
end
```

のように書くと、これはINT全体がひとつの変数と認識されるらしく、INTがセンシティビティリストに入らないよ、という警告が等価性検証で警告される。
xが入力ポートで、yが出力ポートで意味的に全く問題がないにも関わらず、だ。
実際は、シミュレーターも分かっていて問題は出ない場合があるけど、厳密にはかなり危ない記述となる。

回避するには always @* を使うしかない。

結論：SystemVerilog のinterfaceは使わない。
realsense-rosからのrgbデータとdepthデータを同期させてみた

## 経緯
最近realsenseの入力ノードである[realsense-ros](https://github.com/IntelRealSense/realsense-ros)(intel公式)に触れる機会があったのですが、あることに気が付きました。**あれ、これってrgbデータとdepthデータがセットでメッセージとして送られてないやん**、と。自分は下のような状態を期待していました。
![Screenshot from 2020-12-11 14-37-59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663246/8fc6ff2b-8366-2ed1-47e0-dc1293413bbe.png)
しかし、実際は下のようにrgbデータとdepthデータは別々のノードでpublishされていました。
![Screenshot from 2020-12-11 14-41-41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663246/2fe191d1-9e54-7882-e284-c763fc5778e5.png)
これでは、同じ瞬間に撮影されたrgbデータとdepthデータをセットとして使いたい場合、不便です。そこで、自分が思いついた方法は２つあります。1つは同じタイムスタンプのrgbとdepthのmessageを結合してpublishする方法です。もう１つは、受け取るノード側で、同じタイムスタンプのrgbとdepthのmessageが来た場合のみcallback関数を呼ぶというものです。今回は2つ目の方法を、ROSの[message_filters](http://wiki.ros.org/message_filters)を使ってやってみた手順を共有します。

## 手順
### 1. realsense-ros側の設定
まず入力ノードであるrealsense-ros側での設定をしていきます。rs_camera.launchのenable_syncというパラメーターをtrueにします。これにより、rgbとdepthで同じタイムスタンプがあった場合、同じタイミングでまとめてpublishしてくれます。ただし、同じタイムスタンプが無い場合もどちらか１つだけでpublishするので、以下のようにソースコードを変更しました。if文を加えて、publishするvectorのサイズが2(rgbとdetphが揃っている)の場合のみpublishするようにしています。

```base_realsense_node.cpp
void BaseRealSenseNode::frame_callback(rs2::frame frame)
{
    ~~省略~~
    if (frames_to_publish.size() == 2)
    {
        for (auto it = frames_to_publish.begin(); it != frames_to_publish.end(); ++it)
        {
        
        }
    }
}
```
これにより、pubilshされるrgbとdepthのメッセージのタイムスタンプは同じになりました。次に、メッセージを受け取るノード側の処理を書いていきます。

### 2. message_filtersによる同期処理
メッセージのタイムスタンプは同じですが、rgbとdepthでノードは別々です。そこで、message_filtersを使います。message_filtersは複数のメッセージタイムスタンプが同じ場合、指定のcallback関数を呼び出せるというものです。最大9つまで同期させることができます。[公式](http://wiki.ros.org/message_filters)に詳しい説明が書いてあります。今回は公式通りにやってみました。

```sample.cpp
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
#include <message_filters/sync_policies/exact_time.h>
#include <sensor_msgs/Image.h>
#include <sensor_msgs/CameraInfo.h>
 
using namespace sensor_msgs;
using namespace message_filters;
 
void callback(const ImageConstPtr& rgb_msg, const ImageConstPtr& depth_msg)
{
  // Solve all of perception here...
}
 
int main(int argc, char** argv)
{
  ros::init(argc, argv, "vision_node");
 
  ros::NodeHandle nh;
  message_filters::Subscriber<Image> rgb_sub(nh, "/camera/image_raw", 1);
  message_filters::Subscriber<Image> depth_sub(nh, "/camera/depth_raw", 1);
 
  typedef sync_policies::ExactTime<Image, Image> MySyncPolicy;
  // ExactTime takes a queue size as its constructor argument, hence MySyncPolicy(10)
  Synchronizer<MySyncPolicy> sync(MySyncPolicy(10), rgb_sub, depth_sub);
  sync.registerCallback(boost::bind(&callback, _1, _2));
 
  ros::spin();
 
  return 0;
}
```

これで、rbgとdepthからのメッセージのタイムスタンプが同じ場合のみcallback関数が呼ばれるようになりました。ただ、気をつけてほしいのは、受けとり側のノードをクラスとして作成している場合、subscriberをどこで初期化すればいいかわかりませんでした。クラスのコンストラクタで初期化してみましたが、うまくいかなかったので、クラスでやるのをやめました。もし、やり方を知ってる方いらしたら教えていただきたいです。タイムスタンプが近い場合にcallback関数を呼び出したい場合は、ApproximateTime Policyを使えばいけます。

## まとめ
ROS面白くなってきました。

**間違いや質問、ご意見等ありましたらお気軽にコメントください。頑張って答えますので(笑)。**