OmniAICreator/Qiita-1.07M huggingface dataset:
CodeceptJSのCustom Locatorでクリックをきれいに書く

CodeceptJSの `I.click()` に文字列を渡すと、その文字列をクリックしてくれます。

```javascript

I.click('ログイン')
```

ですが、クリックしてくれないものもあります。
Qiitaのトップページを例にあげてみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/112393/3c94a3b9-e94d-669f-406f-3fa1ab5fb30f.png)

`ログイン` はクリック出来ますが `コミュニティ` はクリックできません。

```javascript

I.click('ログイン')      // できる
I.click('コミュニティ')   // できない
```

この差は何なのでしょう？
実は、 `I.click()`  にCSSでもXPathでもない文字列を渡すと、 `<a>` `<button>` などの「クリックできそうな要素」からのみ探索するので、 `<div>` や `<span>` などはクリックできなかったりします。

`I.click(locate('span').withText('コミュニティ'))` のように記述すればクリックできるのですが、これは分かりにくいですね。

というわけで、[Custom Locator](https://codecept.io/locators#custom-locators)でちょっと良い感じのやつを作ってみます。
以下のコードをプロジェクト内の任意の箇所に保存してください（例えば `./customLocators.js` など）

```customLocators.js
module.exports = () => {
  codeceptjs.locator.addFilter((providedLocator, locatorObj) => {
    if (typeof providedLocator === 'string') {
      if (providedLocator[0] === '=') {
        locatorObj.value = `.//*[text()="${providedLocator.substring(1)}"]`;
        locatorObj.type = 'xpath';
      }
    }
  });
}
```

それから、`codecept.conf.js`の中でそのコードを読み込ませます。

```codecept.conf.js

  plugins: {
    customLocator: {
      require: './plugins/locators.js',
      enabled: true,
    },
  },
```

するとあら不思議、`I.click('=コミュニティ')`のように `=` を文字列の頭に付けると、だいたい何でもクリックできるようになります。
すごいですね。
おれたちのCodeceptJSがまた便利になってしまった。


## 参考

https://codecept.io/locators#custom-locators
Swift MediaPlayer ミュージック検索で取得

# 概要
ミュージック検索で取得。
# example
## 検索用ベース
```swift
import UIKit
import MediaPlayer

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let filter1 = MPMediaPropertyPredicate(value: "BOOWY", forProperty: MPMediaItemPropertyArtist)
        let filterSet = Set([filter1])
        let mPMediaQuery = MPMediaQuery(filterPredicates: filterSet)
        
        if let collections = mPMediaQuery.collections {
            print(MPMediaType.music)
            print(collections.count)
            for collection in collections {
                print("-/\\-")
                print("\(collection.mediaTypes)")
                collection.items[0].toString()
            }
        }
    }

}

extension MPMediaItem {
    func toString() {
        print("MPMediaItem")
        let keys = [MPMediaItemPropertyAlbumTitle,
                    MPMediaItemPropertyAlbumArtist,
                    MPMediaItemPropertyArtist,
                    MPMediaItemPropertyIsCloudItem,
                    MPMediaItemPropertyAlbumTrackNumber,
                    MPMediaItemPropertyAlbumTrackCount,
                    MPMediaItemPropertyPlayCount,
                    MPMediaItemPropertySkipCount,
                    MPMediaItemPropertyTitle,
                    MPMediaItemPropertyUserGrouping]
        for key in keys {
            let value = self.value(forKey: key)
            if let value = value as? Bool {
                print("- Bool \(key):\(value)")
            }
            else if let value = value as? String {
                print("- String \(key):\(value)")
            }
            else if let value = value as? Int {
                print("- Int \(key):\(value)")
            }
        }
    }
}
```

## アーティスト名で検索
MPMediaPropertyPredicateを使用する。

```swift
let filter1 = MPMediaPropertyPredicate(value: "BOOWY", forProperty: MPMediaItemPropertyArtist)
let filterSet = Set([filter1])
let mPMediaQuery = MPMediaQuery(filterPredicates: filterSet)
```
## フィルタはAnd条件
アーティスト名2つは検索が0件になる。

```swift
let filter1 = MPMediaPropertyPredicate(value: "BOOWY", forProperty: MPMediaItemPropertyArtist)
let filter2 = MPMediaPropertyPredicate(value: "sinon", forProperty: MPMediaItemPropertyArtist)
let filterSet = Set([filter1, filter2])
let mPMediaQuery = MPMediaQuery(filterPredicates: filterSet)
```
## 検索結果をアルバム単位にする
groupingTypeを指定。

```swift
let filter1 = MPMediaPropertyPredicate(value: "渡辺美里", forProperty: MPMediaItemPropertyArtist)
let filterSet = Set([filter1])
let mPMediaQuery = MPMediaQuery(filterPredicates: filterSet)
mPMediaQuery.groupingType = MPMediaGrouping.album
```
Express の Request型・Response型を拡張して引き回す

# Express.Application型を拡張する

Request / Response の型拡張を行なったうえで、どこでもその型が適用されている状態としたい。拡張するモチーベーションとして、次のものを想定している。

- Middleware で何かを注入している

## 拡張方法

この拡張定義ファイルは tsconfig の include スコープに含まれていればどこでも良い(つまりどこで良い)。`global.Express` の namespace で Request / Response のオーバーロードをする。

```typescript
// ① Express を import

import Express from 'express'

// ② global.Express をオーバーロード

declare global {
  namespace Express {
    interface Request {
      // 拡張される何かのパラメーター
      exparam: { some: string }
    }
    interface Response {
      // 拡張される何かのパラメーター
      exparam: { some: string }
    }
  }
}

```

# 通常利用時

req / res は 拡張された Request / Request がキャストされている。同じ要領で、`next: NextFunction` も自由に定義が可能。Error Logging ハンドラーに渡す props を型キャスト出来る。この方法の場合、Request / Request そのものが拡張されるため、拡張パラメーターは optional にした方が安全。

```typescript
import Express from 'express'

export default (app: Express.Application) => {
  app.use((req, res, next) => {
    // MiddleWare で拡張する処理
    req.exparam = { some: 'any' }
    next()
  })
  app.get('/path/to/endpoint', (req, res) => {
    console.log(req.exparam)
     // (property) Requesrt.exparams: { some: string }
    res.sendStatus(200)
  })
}
```
サーバーサイド初心者がUbuntuにRailsをインストールしたのでメモ

#サーバーサイド初心者がRailsの開発環境を構築してみた

##はじめに
私は組み込み系を専攻する学生です、サーバーサイドに少し興味を持ちましたので参考書片手にRailsの開発環境を構築してみました。自分用のメモとして記事に書かせて頂きます。

環境
ubuntu 18.04.1

##rbenvのインストール
githubを使ってrbenvを入手し、パス設定と初期化処理を追加します。

```Bash 
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrc
$ echo 'eval "$(rbenv init -)"' >>~/.bashrc
```
一回再起動し、次のコマンドでインストールされているか確認

```Bash
$ rbenv -v
```



##ruby-buildのセットアップ
rubyのインストールを簡単にしてくれるプラグインをインストールし、Rubyにあらかじめ必要なパッケージをインストールしておきます

```Bash
$ git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
$ sudo apt-get install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev
```
##Rubyのインストール

以下のコマンドでインストールできるrubyのバージョンが確認できます。
最新のバージョンをインストールしましょう。
2019/3/11現在ではバージョン2.6.1が最新
※2.7.0-devはベータ版らしいので非推奨

```Bash
$ rbenv install -l
$ rbenv install 2.6.1
$ rbenv global 2.6.1
```

正しくrubyがインストールされたか確認しましょう

```Bash
$ ruby -v
$ which ruby
```
次にパッケージを管理してくれるRubyGemsを最新版にしておきます

```Bash
$ gem update --system 
$ gem -v
```

##Bundlerのインストール
```Bash
& gem install bundler
```

##Railsのインストール
以下がRailsのインストールコマンドです。

```Bash
$ gem install rails
$ rbenv rehash
$ rails -v 
```

作業するディレクトリを作成し、ディレクトリ内でアプリケーションを作成します。

```Bash
$ rails new [プロジェクト名]
$ cd [プロジェクト名]
$ rails s
```

http://localhost:3000/
にぎやかな人たちが出てきたら、成功です。
お疲れ様でした。


##あとがき
初めての投稿になりますが、私自身サーバーサイド初心者ですので間違いを見つけ次第、ご指摘をお願いいたします。
これからは定期的にアウトプットていきたいと思います。
それにしても、環境構築は大変ですね.....

##参考
https://qiita.com/hiroyuki242424/items/f64761d6363efa8bfd45
https://qiita.com/toshi726/items/f212916dfc9a103f7cfa
とあるエンジニアの問題意識 2019-03-10


# 夢中は価値最大だが、再現性が低いのが難点。
だけどフロー状態という言葉があるように、再現可能なスキルの一種類のはずだ。普段から睡眠、エネルギー管理、自分の興味関心への洞察、OSやツール類の環境改善、適度な難易度設定など、本当にたくさんの下ごしらえが必要とされるとは思う。 
# ひとくちにエンジニアリングやプログラミングと言っても、趣味趣向は千差万別に分かれるよなぁ確かに。
数学の例えは、はっとした。僕の場合は、軽量スクリプト言語やシェルを書いている時がいちばん幸福で、サーバーやモジュール関係の謎エラーで苦しんでいる時は絶望しかない気がする。

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/744








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Railsのルーティング

**resources**
---
`resources`で７つアクション（index・show・new・create・edit・update・destroy）
に７つのルートを自動で設定できる。

resources : リソース名 [,オプション]

```ruby:config/routes.rb
resources :users
```


|アクション　　　　　　 | HTTPメソッド　　　　　　　 |     URLパターン   　　 |  
|:---------|:--------------|:------------------|
|   index      |       GET        |  /users    |  
|  show        |       GET        | /users/:id   |  
| new    　　   |       GET        |   /users/new     |   
|  create      |       POST       |  /users     |   
|  edit        |       GET        | /users/:id/edit |      
|  update      | PATCHまたはPUT    | /users/:id    |     
|destroy     |       DELETE     |  /users/:id    |    

|ヘルパーメソッド　　　| URLパターン名　|    機能  　　　　 |  
|:--------------|:-------------|:----------|
| users_path      |   users    |  一覧画面    |  
| user_path       |     user     |詳細画面  |  
| new_user_path   |  new_user    | 新規登録画面   |   
| users_path     |    users      |  登録処理     |   
| edit_user_path |  edit_user    | 編集画面 |      
|user_path      | user   | 更新処理    |     
|user_path    |     user    |  削除処理    | 


**only**
---

`:only`オプションは、特定アクションのルートだけを作成する。
たとえば、only:[:index]とすると、indexのルートだけが作成される。

```ruby:config/routes.rb
resources :users, only:[:index]
```

**excep**
---

`:excep`オプションは、特定アクションのルートだけを作成する。
except:[:index, :show]とすると、indexとshow以外の5つのルートが作成される。

```ruby:config/routes.rb
resources :users, except:[:index, :show]
```

**collection**
---


ユーザー検索をおこなう、searchアクションを新規追加するなど、
全データに対するアクションに利用する場合は、resourcesに`collection`ブロックをわたす。

```ruby:config/routes.rb
resources :users do
  collection do
    get 'search'
  end
end

# onオプションを使った場合
resources : users do
  get 'search', on: :collection
end
```


**member**
---

特定のユーザーを示す id 付きのルーティングのように、特定のデータに対するアクションに利用する場合は、resourcesに`member`ブロックをわたす。

```ruby:config/routes.rb
resources :users do
  member do
    get 'preview'
  end
end


# onオプションを使った場合
resources : users do
  get 'preview', on: :member
end
```
URLパラメーターの “?guid=on” について

なんなんでしょうこれ。弊社ではこの謎のオプションがたくさんついていたのですが、コードとして特にこのパラメーターを使っておらず気になったので調べてみました。

# guid=on とは
> DoCoMoの携帯電話（ガラケー）の場合、iモードID（固有番号）をサイトに送るようにするための機能。
> 会員制サイトなどで会員登録を行うと、次回以降iモードIDで会員を区別できるので、素早くサービスを提供することが可能になる。

DoCoMoのガラケーはこのオプションが無いと、iモードIDをサイトに送る事ができずにログイン状態を保持したりすることが不可能になるのでつけているという事になる。

イケてない仕様だなぁ。。

# 今つける必要ある？
ないです。

ですが、ガラケーをサポートしている長いサービスの場合必要です。残念ながら私がやっていた仕事では必要でした。
ですが、新しい機能はスマホでしか使わないためこのオプションは不必要となり、削除することに決定しました。
ケースバイケースで、このオプションのつけるつけないの判断がいりますね！
正直、今後このオプションを使うことは無いと思います。
未来(AI)を制すプログラミングのススメ

　あなたはプログラミングに興味があってここにたどり着きましたか？そうであるなら、これからプログラミングを始めようとしているあなたの調べる手間を省くために、私が道しるべを示しましょう。
　申し遅れましたが、私はSE(しがないエンジニア)の金鱗化龍です。人工知能に仕事を奪われないために、制御する側になろうとIT業界に舞い戻りました。
　さて、今現在ホットなプログラミング言語の中で、Pythonは世界的にも市場があります、これを手っ取り早く習得するための方法をお伝えしますね。

まずは説明書を読みますか？
・[Python日本公式サイト](https://www.python.jp/)
さぁ基礎知識から始めましょう！
・[無料オンライン講座](https://paiza.jp/works/python3/primer)
面倒なインストール作業を省略して・・・
・[オンライン開発環境](https://paiza.io/)
問題なく実行出来たら評価してもらいましょう(^＿^
・[ソースコード展示会場](https://github.com/)
ローカルに保存することをお忘れなく(;^_^A
・[日本語でバージョン管理](https://ja.atlassian.com/software/sourcetree)
そしてアウトプットすることで一層確実にしましょう。
・[プログラミング成果発表の場](https://qiita.com/)

　あなたがもし幸運にも首都圏周辺にお住まいなら、Pythonを習得しただけでもIT企業から引っ張りだこになる事でしょう。しかし残念ながら地方都市ではPythonだけだと、まだまだ不安定なので更なる保証を付けないといけません。
　そこで鉄板なプログラミング言語Javaの登場です、この言語は適用範囲が広く、業界で最も使用されています。これについての詳細は、また次回の紹介を楽しみにしておいてください。それではここらへんで失礼します…。
プログラミングの認識方法

#プログラミングの認識方法

##対象者
認識を間違えてしまっている人用
自分用（認識を間違えてしまった為）



##認識を間違えたこと
例）$aに3を代入する
間違え）$aが3です。（僕が答えました。）

```
$a = 3;
```

##追記
追記していこうと思いますがもう少しお待ちください。
Railsとスクレイピングでランキングサイトを作ってみた話


こんにちは。今回は「[ゲーム実況者ランキング](https://gamer-ranking.com/)」というサイトを開設したのでその経緯などをお話したいと思います。
開設後ぼちぼちではありますが収益も発生していますので、何か個人開発を始めてみようと思っているエンジニアの方はぜひ参考にして頂ければ幸いです。
<img width="319" alt="Screen Shot 2019-03-11 at 2.50.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/250231/692324b3-3cba-e69e-1f92-1f264394dc2b.png">
[ゲーム実況者ランキング](https://gamer-ranking.com/)
## ただブログを書くだけではエンジニアの強みが活かせていないと感じた
僕はもともと勉強したことをブログに書いて情報発信をしたりしていました。
情報発信することで勉強にもなるし、収益も発生したりしていたのでそういう面では良かったのですが、問題がありました。

それは、ブログは誰でも出来ることであるが故に、競争がとても激しいということです。
参入障壁がとても低いがために、大量のブロガーがいるのです。

せっかく自分はエンジニアなのだから、エンジニアだからこそ出来ることをして、価値を生み出したいと思うようになりました。
## じゃあどうする？→「スクレイピングが良さそうだ」
ブログを書いていたということもあり、情報発信系の何かを出来ないか？と考えていました。
そこで目を付けたのがスクレイピングです。
「スクレイピングで得た情報をまとめたサイト」というものは一般のブロガーは作ることは出来ません。
データを集めて、客観的に眺めることができるサイトを作れる人というのはサイト運営者全体で見れば少数です。

また、他にも気をつけたことがあります。それは、エンジニアは技術にこだわった自己満なプロダクトを作ってしまいがちだということです。
本人はそのプロダクトに価値を感じるが、ほとんどの人にとっては興味がないプロダクトです。

僕は**「価値の創造」**を意識して、スクレイピングを活用して今までは存在していなかった、多くの人が認める価値を生み出せないか？を考えました。
## 収益面など総合的に考えてランキングサイトに決定
スクレイピングをすることで最も簡単に作ることが出来るのがランキングサイトです。
僕は、YouTuberのランキングサイトはあるものの、YouTube上のゲーム実況者やゲームについてのランキングサイトがないことに注目しました。
他にも色々案はあったのですが、**ゲームが好きな人の数が多い**ことと、将来的にゲームの広告を載せられることを考え、総合的にこの案が一番だと結論付けました。
## スクレイピング、サイト作成、デプロイ
簡単にですがサイトを作成のために踏んだ手順を紹介します。
まずは、スクレイピングやYouTubeのAPIでデータを集めることに集中しました。
そして、各ゲーム実況者の登録者ランキング、各実況者が実況しているゲームランキング、ならびに各ゲームがどの実況者に最も実況されているかといったデータを取得しました。
次に、Ruby on RailsとVueでささっとサイトを作成して、Herokuでデプロイをしました。
そして出来たサイトがこちらです。[ゲーム実況者ランキング](https://gamer-ranking.com/)

すでに述べていますが、デプロイ後すでに収益も発生しているのでサイトの方針があながち間違っていなかったのかなと思います。
## 最後に
スクレイピング最高！ぜひあなたもスクレイピングをして、興味深いデータを集めてみてはいかがでしょうか。きっと何かに活用できるはずです。

[ゲーム実況者ランキング](https://gamer-ranking.com/)
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
はじめてのC++【14日目】

#はじめに
今日は時間が取れなく、一節だけ。
##ロベールのC++
###06-05　private

```inArray.cpp
#include <iostream>
#include <array>
#include <algorithm>
#include <cstdlib>
class inArray {
public:
  std::array<int,100> m_array = {0};
  inArray();
  int Get(int i);
  void set(int i,int value);
  void checkindex(int i);
};

int inArray::Get(int i){
  checkindex(i);
  return m_array[i];
}
void inArray::set(int i, int value){
  checkindex(i);
  m_array[i] = value;
}

void inArray::checkindex(int i){
  if(0 <= i && i < 100){

  }else{
    std::cout << "インデックスは不正です" <<std::endl
              << "値" << i << std::endl;
    exit(EXIT_FAILURE);
  }
}
```
コンパイルエラー出てきた。std;;arrayの代入の仕方が間違っている。
今日は遅いので明日また続きやる。

publicで外部公開
privateで内部限定

#終わりに
中身がない内容になってしまった。
【vue+webpack】単一コンポーネント(.vue)での簡易的なルーティング

##状況
クライアントサイドのフレームワークは入門レベル。
現在vue+webpackでチュートリアル以降、自分用アプリを作って練習中。

##やったこと
SPAはちょっとまだいいかなと思ってvue-routerは入れなかったんだけど、若干ルーティング的なことがしたくなった。
.vueファイルを使う単一コンポーネントの場合にそのまま使える例がみつからなかったので、自力でできるだけ簡単に実装した。

##環境
vue-cliで作成。

```
vue -V
2.9.6
vue init webpack xxx
```

##内容
###フォルダ構成
生成されるファイル群のうちsrcフォルダ内のみ表示。

```
D:.
│  App.vue
│  main.js
│  simpleRouter.js ←ルーティング情報を持つ
│
├─assets
│      logo.png
│
└─components
        cmpA.vue　←ルーティング先
        cmpB.vue　←ルーティング先
        cmpC.vue　←ルーティング先
        cmpP.vue　←親
```

###動き
押すとふつうに切り替わる感じ。親コンポーネントと呼んではいるものの、移動はページ単位。

初期表示
![1_ini.PNG](https://qiita-image-store.s3.amazonaws.com/0/342812/bd89fd65-dfe4-5493-f096-d3226dffb7a9.png)

[cmpAを表示]クリック
![2_A.PNG](https://qiita-image-store.s3.amazonaws.com/0/342812/d18005eb-fe70-975a-9a1a-8ae65593bc9a.png)

[cmpBを表示]クリック
![3_B.PNG](https://qiita-image-store.s3.amazonaws.com/0/342812/317d1fdc-4004-78b9-7ab5-e37eb28600b8.png)

[cmpCを表示]クリック
![4_C.png](https://qiita-image-store.s3.amazonaws.com/0/342812/29fd6292-d367-98b0-46f9-74156606cf69.png)


###ソース

####ルーター
といっても実際に飛ばす動きはしないので単にルーティングテーブルみたいな感じか。
リンク先のパス名とコンポーネントを持たせる。

```javascript:simpleRouter.js
import A from './components/cmpA'
import B from './components/cmpB'
import C from './components/cmpC'

export default {
    '/A': A,
    '/B': B,
    '/C': C
}
```

####リンク先になるコンポーネントファイルたち

```html:cmpA.vue
<template>
    <div>コンポーネントＡ</div>
</template>

<script>
export default {
    
}
</script>

<style scoped>
div {
    color:green;
}
</style>

```

```html:cmpB.vue
<template>
    <div>コンポーネントＢ</div>
</template>

<script>
export default {
    
}
</script>

<style scoped>
div {
    color:blue;
}
</style>

```

```html:cmpC.vue
<template>
    <div>コンポーネントＣ</div>
</template>

<script>
export default {
    
}
</script>

<style scoped>
div {
    color:red;
}
</style>
```


####呼び出し元になるコンポーネントファイル
ここで実際にルーティング。
単純にパス名取ってルーティングテーブルからコンポーネントを引っ張る。

```html:cmpP.vue
<template>
    <div id="Parent">
        <a href="/">親コンポーネント</a><br/>
        <a href="/A">cmpAを表示</a>
        <a href="/B">cmpBを表示</a>
        <a href="/C">cmpCを表示</a>
        <component :is="cmp"/>
    </div>
</template>

<script>
import simpleRouter from '../simpleRouter.js'

export default {
    data() {
        return {
            cmp: simpleRouter[window.location.pathname],
        }
    }
}

window.addEventListener('popstate', () => {
  app.currentRoute = window.location.pathname
})
</script>
```

##おわり
自分用なのでこのくらいで十分ですね。部分的な更新とかぬるぬる遷移するようなやつはまた別にやりましょう。
Not Foundくらいは対応しないといけないと思う。
サッパリ系ビスケットプログラミング#5マリオ風ゲーム/重力と左右移動

SEの方の間でも評価が上昇傾向のビジュアルプログラミング言語、Viscuit（以下ビスケット）でマリオ風のゲームを作成していきます。#4で作ったステージに、割れたメガネを使ってコントローラのプログラムを追加します。割れたメガネについては#1をご参照ください。

※ビスケットのコーディングは全て描画で行います。こちらの記事はビスケットでのコーディングを簡潔に紹介するため、敢えてサッパリした描画のプログラムにしております。こちらをベースに、お好みの描画でオリジナリティーの高いプログラムに仕上げてくださいm(_ _)m


#重力と左右移動

##【ステージ、コントローラー、プログラム解説】
ステージ:マリオがジャンプ→キノコをゲットして巨大なマリオに→土管IN-OUT→地下でコインゲット→土管IN-OUT→フラッグ→クリア…という流れです
![025BE6A0-A6ED-4D2E-BED2-0A8A255CC531.png](https://qiita-image-store.s3.amazonaws.com/0/373284/2aad2e7c-901c-8735-8f56-c789fb556f97.png)
前回は左のステージに画像のようなステージを配置しました。下向き↓は、重力センサーです。こちらが配置されているところではマリオが落下します。
今回は、重力落下→十字キーで左右移動をさせるプログラムを作ります。


###コントローラー（十字キーとAボタン）
Aボタンと十字キーは#1〜3のシューティングゲームでも紹介しました。
このマリオ風ゲームでは左右、左上&右上、下の5方向の命令を使います。
左右は歩行、左上&右上はジャンプの方向、下は土管に入る命令です。

今回は、左右のキーでマリオを水平移動させるプログラムを作って行きます。


###重力の設定（メガネ２つ）
![2670F32F-9B86-4AEE-85C0-17DC7D7C54E1.jpeg](https://qiita-image-store.s3.amazonaws.com/0/373284/d015232a-7c5e-2c3d-db25-3d0c2378c9c0.jpeg)
オレンジの↓は重力センサーです。と言ってもただ↓を描いただけで、特別なものではありません。
天地創造の際は、まずはステージに重力を与えて、落下→着地ができるかチェックします。
（マリオは小と大の両方を描画しておきます。）
前回の＃４でステージに重力センサーを配置しています。
まず、左のメガネにマリオ小を入れ、その下に重力センサーを入れます。
次に、右のメガネに重力センサーを入れ、その下にマリオ小を入れます。
一般的なプログラム風に訳すと
　「もしマリオ小の下に重力センサーがあれば、マリオ小は１マス下に行く」
という意味になります。
マリオ大も同様に作っておきます。（このマリオ風ゲームの製作を進めていく際、左右にジャンプした格好の大小マリオを追加していきます。こちらについては、次回＃６ジャンプで解説します。）


###重力のテスト（画像上:落下前 画像下:落下後）
![490AD97E-3EC4-4D3B-B0D2-CAA031747A7E.jpeg](https://qiita-image-store.s3.amazonaws.com/0/373284/2c36091b-0235-d825-5c9e-5ffb112fef21.jpeg)
![6C4C1AC1-A30C-4739-B385-730F65ADC626.jpeg](https://qiita-image-store.s3.amazonaws.com/0/373284/280015cf-7ebc-6430-3540-ff941021e746.jpeg)
画像のように高いところにマリオを配置します。
落下後の画像のように落下して着地できれば重力の設定ができました。


###左右の移動（画像上:右移動 画像下:左移動 それぞれ小マリオと大マリオ用）
![701FA3CB-6502-47C8-B6EF-123B70B73BA5.jpeg](https://qiita-image-store.s3.amazonaws.com/0/373284/a4a02f5d-f017-c93b-259b-4f5cf02d3cd7.jpeg)
![FDEF276C-5C20-4369-ACB2-C4C3ABCC79D0.jpeg](https://qiita-image-store.s3.amazonaws.com/0/373284/f3d1454c-8d7a-a6ea-0942-c6cc3cba146d.jpeg)
メガネは割れたメガネを（右向き3つ＋左向き3つ）×2=12個　準備します。
以下、解説していきます。


###マリオ小(大)の右移動（割れたメガネ2分割3つ×2セット＝6個）
![9497F4A8-07FD-4953-962E-0B7CB6E216F6.jpeg](https://qiita-image-store.s3.amazonaws.com/0/373284/ae6e9755-6bd4-e0be-e13b-4fdefa7e5858.jpeg)
ステージブロック、ハテナブロック、割れないブロックの上を左右に移動するために、プログラムを作っていきます。
まず、左のメガネ下段には十字キーを入れ、十字キー右にタッチマークを配置、左のメガネ上段にはステージブロックを入れ、1マス上には重力センサーを配置、1マス左にはマリオ小をステージブロックとオフセットして配置します。
次に、右のメガネ下段には十字キーを入れ、右のメガネ上段には左のメガネと同じ場所にステージブロックを配置し、1マス上にはマリオ小を配置、さらに1マス左には重力センサーをステージブロックとオフセットして配置します。
この作業は、割れないブロック上での右移動とハテナブロック上での右移動でも必要ですので、ブロックを差し替えた同じプログラムを作ります。
マリオ大の右移動も同様に作っておきます。


###マリオ小(大)の左移動（割れたメガネ2分割3つ×2セット＝6個）
![E48FA803-3C24-4AB7-A221-D9FF1099760C.jpeg](https://qiita-image-store.s3.amazonaws.com/0/373284/e73ef714-da63-5b17-91fd-6772927b93df.jpeg)
右移動と同様に作ります。

一般的なプログラム風に訳すと
 「もしマリオ小(大)の左(右)側にステージブロック(割れないブロック、ハテナブロック)があれば、
　 左(右)ボタンが押された時、マリオ小(大)が1マス左(右)に移動する。」
という意味になります。

これで自由落下→左右移動ができるようになりました。次回は、いよいよ「ジャンプ」です。
2つのベクトル集合の中で距離が小さい組み合わせを求める

毎回忘れるのでメモ。

1つのベクトル集合$X$内のベクトル間距離の場合、距離行列が対称行列なので、`triu_indices`で狭義上三角行列のインデックスを取得して、その部分だけ`argsort`する。

```py

import numpy as np
from scipy.spatial import distance_matrix

sample_num = 100
dim = 8
X = np.random.randn(sample_num, dim)
D = distance_matrix(X, X)
ti = np.triu_indices(sample_num, 1)
sorted_indices = np.argsort(D[ti])
ix, iy = ti[0][sorted_indices], ti[1][sorted_indices]
print(D[ix, iy])
```

2つのベクトル集合$X$, $Y$内のベクトル間距離の場合、`ravel`でflattenして、`argsort`して、`unravel_index`で戻す。

```py
import numpy as np
from scipy.spatial import distance_matrix

sample_num_x = 100
sample_num_y = 200
dim = 8
X = np.random.randn(sample_num_x, dim)
Y = np.random.randn(sample_num_y, dim)
D = distance_matrix(X, Y)
ix, iy = np.unravel_index(np.argsort(np.ravel(D)), (sample_num_x, sample_num_y))
print(D[ix, iy])
```

類似度の場合は$D$をマイナスにする。

Top-kだけが欲しいケースがほとんどだと思うが、その場合`argpartition`してからソートしても良い。
Google V8 JavaScript Engine - サンプルコードのビルド


Google V8 JavaScript Engine のビルドしてみたのでメモ

https://v8.dev/docs/embed の内容のそのままといえばそのままである。

MacOS環境でV8のビルド・サンプロコードのビルド・実行をしているので、プラットフォームによっては若干差分がある。

# Use Python 2.7
3系だと途中でつまずくので要注意. なんらかの手段で2.7系に切り替えておく
https://qiita.com/LittleWat/items/166f976cccf30bc63e62

# Install depot_tools
```
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
$ export PATH=`pwd`/depot_tools:"$PATH"
```

# Get the V8 source code, including all branches and dependencies:
```
$ mkdir ~/v8
$ cd ~/v8
$ fetch v8
$ cd v8

# 適当に最新のtagを利用する
$ git checkout refs/tags/7.5.10
```

# Create a build configuration using the helper script:
```
$ tools/dev/v8gen.py x64.release.sample
$ gn args out.gn/x64.release.sample
=========== ひとまず下記のデフォルトの状態でOK
  1 is_component_build = false
  2 is_debug = false
  3 target_cpu = "x64"
  4 use_custom_libcxx = false
  5 v8_monolithic = true
  6 v8_use_external_startup_data = false

v8_monolithic: がビルド実行によって出力されるスタティックライブラリとして出力される
```

# Build static library
```
$ ninja -C out.gn/x64.release.sample v8_monolith

# ライブラリが「obj」配下に出来ていればとりあえずOK
$ ls -lh ./out.gn/x64.release.sample/obj/ | grep \\.a$                                                                                                                [~/v8/v8]
-rw-r--r--    1 xxx  yyy   2.3M  libv8_libbase.a
-rw-r--r--    1 xxx  yyy   2.7M  libv8_libplatform.a
-rw-r--r--    1 xxx  yyy   1.9G  libv8_monolith.a
```
マシンのCPU性能によると思うが、かなり時間がかかるため、要注意.

# Build Sample Code

「./samples/hello-world.cc」
というV8エンジンを使ってHello, World!の出力を行うサンプルコードが存在するため、これを利用する。

```
$ g++ -I. -Iinclude samples/hello-world.cc -o hello_world -lv8_monolith -Lout.gn/x64.release.sample/obj/ -pthread -std=c++0x

# サンプルコードの実行
$ ./hello_world
Hello, World!
3 + 4 = 7
```

とにかくサンプルコードを動かすだけのビルドは、時間がかかるだけでかなり簡単にできる。
中身を追ってみたり、wrapperなライブラリ作って他言語のランタイムからJavaScript実行させたりはまたあとで

# 参考URL

- https://v8.dev/docs/embed
- https://v8.dev/docs/source-code#using-git
- https://qiita.com/pirosikick/items/d5a96f8875313907db35
- http://d.hatena.ne.jp/rti7743/20101215/1292437763
- https://qiita.com/LittleWat/items/166f976cccf30bc63e62
ソフトウェアラジオ（SDR）受信機を使ってFlightRadar24にFeed提供した話

#はじめに
もともと飛行機が好きなので、FlightRadar24を眺めるのは大好きなのだが、
スポッターでもないし月額5,000円のサブスクリプションはちょっとなぁと思ってました。

そんなとき、上司から

 "受信機つくって自分でそれっぽいの作れるらしいぞ。
　というか、受信した情報を[FlightRadar24.com](https://www.flightradar24.com/)に提供したら
　全機能をタダ使えるらしいぞ"

という素敵情報がもたらされたので、とりあえずやってみることにしました。

主に下記の情報を参考にしました。
[Flightradar24をビジネスクラスにアップグレード！設定編](https://wporpt.blog.so-net.ne.jp/2017-01-12)

#前提
 - Windows10でやった
 - そのうちラズパイに移行するための実験（24時間動かすとかじゃなくてとりあえずやっただけ）
 - やったことは上記サイト様のトレースです。感謝。

#準備
用意することは3つ

　1-1. FlightRadar24のアカウントを作る
　1-2. USBのSDR受信機をアマゾンでポチる
　1-3. fr24feedをインストールする

## 1-1. FlightRadar24のアカウントを作る
　まず１つめのFlghtRadar24のアカウントを作るですが、
　気をつけるのはBasicで作ること。有料にしたら意味ないので。

## 1-2. USBのSDR受信機をアマゾンでポチる
　２つめはアマゾンで結構安く売ってるのでそれを買う。
　私はこれ買いました。大体1500円くらい。
　　⇛　[SDR USBドングル](https://www.amazon.co.jp/gp/product/B013S9L05S/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)

## 1-3. fr24feedをインストールする
　３つめはこのソフトウェアをダウンロードして、任意の場所に解凍しておく。
　　⇛　[fr24feed](https://www.flightradar24.com/share-your-data)
　今回はWindowsなのでWindowsのタブから、環境にあったものを選択。
　<img width="819" alt="fr_tutorial1.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/71046/d906bc74-c98d-03bf-85b0-5f87291fc789.png">


#設定手順
　用意が揃ったらやることは３つ

　　2-1. SDR受信機をセットアップする
　　2-2. fr24feedの設定
　　2-3. 果報を寝て待つ

##2-1. SDR受信機の設定
　まずSDR受信機をセットアップするが、
　Windowsの場合USBをつなぐと勝手にドライバを設定してくれるが、
　今回はラジオを聞きたいわけでもテレビを見たいわけでもないので、
　勝手にドライバを入れられると困る。

　ドライバを専用のものに書き換えるソフトがあるのでこれを利用する。詳しくはリンク先を。
　　⇛　[ドライバの設定](http://blog.livedoor.jp/bh5ea20tb-youpapa2/archives/40226092.html)

##2-2. fr24feedの設定
　やること
 　1. FlightRadar24.comのアカウントのemailを入れる
 　2. シードは持ってないので何もしない（勝手に入る）
 　3. 最寄りの空港を選択する（例：羽田空港　RJTT）
 　4. 受信機の種類を選択する（今回はDVBT Stick (USB) を選択）
 　5. ブラウザで見るときのポート設定
 　6. ログの保管期間を決める
 　7. fr24feedを終了する
　※先述の参考サイトを見て実施した。
　fr24feedを再起動したら完了。

##2-3. 果報を寝て待つ
　 `[feed][i]sent 0,1 AC`
　みたいなのが出てれば成功です。

　ログに　”Connection Terminated” が表示されている場合、
　Firewallなどで通信が遮断されているので、設定を解除すること。

　ちゃんとFeedがFlightRadar24.comにアップロードされている。
　そのうち、アカウントの種類がBasicからBusinessに変わる。

#結果
fr24feedで受信した結果。
<img width="204" alt="fr24_own.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/71046/b5129813-752e-ae4c-39ef-0f34cbf06211.png">

受信成功してる！

同じタイミングで見たFlightRadar24.com
<img width="266" alt="fr24.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/71046/3fdd82f7-4125-ea4a-ffb7-d65ddc9726db.png">

そして、アカウントの種類がBusiness(通常、月額5,000円)になった！
<img width="87" alt="fr24_bus.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/71046/0f22917d-d5e1-3650-e350-4e5b6480c900.png">


#感想
投資額1,500円で、月額5,000円のサービスをフルに使えた！
非常にお得！
Laravelでキーワード検索の配列を作成するミドルウェア

# はじめに

LaravelのミドルウェアはコントローラーにPOSTなどで送られてきたデータに対して、送る前に予め何らかの処理をさせることができる。

今回は、その性質を利用して、キーワード検索用に配列にする処理を作成する。

## 要件

キーワード検索フォームは、`キーワード１ キーワード２`というようにスペースで区切って検索対象にするワードを入力する使い方が多い。このため、単純にスペースで分割すればいいと考えがちだが、使う人は全角スペースも使うことを考慮しなければならない。

また、複数回スペースを入力されたり、同じキーワードが複数回入力されたときにそのままSQLパラメータとして使うのは非効率的である。

この手の処理は検索系ではどこでも使うので、通常は、共通のライブラリなどを参照するようにすることを考えるが、Laravelのミドルウェア機能を使って、透過的に使用することで、コントローラーのコードをすっきりさせることが可能である。

## 実際作ってみた

```php:KeywordExploder.php
<?php
/**
 * キーワードを配列化
 *
 * @author    Logue <logue@hotmail.co.jp>
 * @copyright 2019 Logue
 * @license   MIT
 */

namespace App\Http\Middleware;

use Closure;

class KeywordExploder
{
    /**
     * キーワードを空白文字で分割し配列にする。
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure                 $next
     *
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $keyword = $request->input('keyword');
        $ret = [];

        if (!empty($keyword)){
            // +を半角スペースに変換（GETメソッド対策）
            $keyword = str_replace('+', ' ', $keyword);
            // 全角スペースを半角スペースに変換
            $keyword = str_replace('　', ' ', $keyword);
            // %はSQL実行時にLIKEのパラメータとして使うのでスペースにする。
            $keyword = str_replace('%', ' ', $keyword);
            // 取得したキーワードのスペースの重複を除く。
            $keyword = preg_replace('/\s(?=\s)/', '', $keyword);
            // キーワード文字列の前後のスペースを削除する
            $keyword = trim($keyword);

            if (!empty($keyword) || $keyword !== '') {
                // 半角カナを全角カナへ変換
                $keyword = mb_convert_kana($keyword, 'KV');
                // 半角スペースで配列にし、重複は削除する
                $ret['keyword'] = array_unique(explode(' ', $keyword));
            }
        }

        $request->merge($ret);

        return $next($request);
    }
}
```

直訳するとキーワード発破者になってしまうが、これは`explode`命令で配列にしているからであって深い意味はない。

## 使い方

ダウンロードした`KeywordExploder.php`を`app/Http/Middleware`内に置き、`Kernel.php`の`$routeMiddleware`に以下の行を追加。

```
'keyword' => \App\Http\Middleware\KeywordExploder::class,
```

次に、`routes/web.php`の検索処理のルーティング部分に`->middleware('keyword')`と入れる。

あとは、コントローラーやモデル側のキーワード検索のSQLを発行する処理の部分で

```php
$keywords = $request->input('keyword');
if(!empty($keywords)) {
    foreach ($keywords as $keyword) {
        $query->where('name','like','%'.$keyword.'%')
    }
}
```

みたいに`foreach`で回して使用する。
JSで生成されるページをRSelenium +rvestでスクレイピング

#はじめに

ちょっと趣味で、Fashionsnap.comの[ストリートスナップの一覧ページ](https://www.fashionsnap.com/streetstyle/?page=2)から、各スナップページへのURLを取得したと考えました。
rvestやwgetでページを取得してみましたが、JSで生成されている部分のソースが取得できず、うまくスクレイピングできませんでした。

いろいろ調べているとRSeleniumを使うといい感じにスクレイピングができました。
メモとして残しておこうと思います。

#RSeleniumについて
webページはURLが不規則であったり、クリックをしないとファイルがダウンロードできない場合があります。
この様なページに対して、Seleniumを用いることで、コマンドでクリックやスクロール等の全ての操作を行うことができます。
Seleniumは、Webアプリケーション用テストツールであり、ブラウザの操作をシミュレート(自動化)して、Webアプリケーションの画面周りのテストを実施することができます。
そして、RSeleniumは、SeleniumをRから実行できるパッケージです。


#スクレイピング
dockerでseleniumのイメージを持ってきます。

```terminal
docker pull selenium/standalone-chrome
```

ここからはR上でやります。
dockerイメージからseleniumサーバを立ち上げます。

```R
system("docker run -d -p 4444:4444 selenium/standalone-chrome", intern = T)
```

立ち上がったかは、http://0.0.0.0:4444/ にアクセスして次のようにページにアクセスできるかを確認します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/197919/7462d604-5912-cb3f-2510-f540f8e6227e.png)

次にRSelenium::remoteDriverを利用してブラウザ（Headless Chrome）のオブジェクトとします。


```R
library(RSelenium)
browser = remoteDriver(remoteServerAddr = "localhost", port = 4444, browserName = "chrome")
```

ブラウザを立ち上げます。

```R
browser$open()
```

ブラウザが生成できたので、目的のページにアクセスします。
アクセス後にSys.sleepを入れてページの読み込みを待つのが良いようです。

```R
page <- 3
url <- paste0("https://www.fashionsnap.com/streetstyle/?page=",page)
  
browser$navigate(url)
Sys.sleep(5)
```

ページのソースを取得します。

```R
pagesource <- browser$getPageSource()
```

最後に取得したソースをhtmlファイルに保存します。

```R
page_html <- paste0("get_snap_page",page,".html")
write(unlist(pagesource), page_html)
```

ここからはrvestパッケージを使った処理です。(rvestの説明は割愛)
全aタグのherfの要素を取得します。

```R
url_list <- read_html("get_snap_page3.html") %>% 
  html_nodes("a") %>% 
  html_attr("href") %>% 
  as.data.frame() %>% 
  mutate(URL = as.character(.)) %>% 
  select(URL) %>% 
  filter(str_detect(URL, pattern = "https://www.fashionsnap.com/streetstyle/2")) 
```

```R
> head(url_list)
                                                         URL
1 https://www.fashionsnap.com/streetstyle/2019-03-09/114260/
2 https://www.fashionsnap.com/streetstyle/2019-03-08/114671/
3 https://www.fashionsnap.com/streetstyle/2019-03-08/114670/
4 https://www.fashionsnap.com/streetstyle/2019-03-08/114717/
5 https://www.fashionsnap.com/streetstyle/2019-03-08/114677/
6 https://www.fashionsnap.com/streetstyle/2019-03-08/114718/
```

できました。
これで分析ができるようになりそうです。

#参考
- https://qiita.com/yutarogollila/items/5e0933eda59d67d4b39e
- https://dichika.hateblo.jp/entry/20140106/p1
Community Cloudのライセンス選定とレコードの共有について

#概要
本記事は、SalesforceのCommunity Cloudにおけるライセンスの選定とそれぞれにおけるレコードの共有方法を簡単に整理したものです。

#ライセンスの選定
まず、前提ですが、外部ユーザとしてログインを必要としない、認証されていない (ゲスト) ユーザ向けの公開知識ベースとしてコミュニティを使用する場合は、コミュニティライセンスを購入しなくても構築することができます。(Enterprise 組織、Performance 組織、および Unlimited 組織である必要有り)

外部ユーザとしてログインが必要である場合のコミュニティライセンスの選定は、ざっくり下記の観点で行います。
1. リード、商談、見積、キャンペーンへアクセスが必要なユーザである → パートナーコミュニティライセンス(**Partner Community**)
2. レポート、ダッシューボード、自社以外の取引先に紐づくレコードへのアクセスが必要なユーザである → カスタマーコミュニティプラスライセンス(**Customer Community Plus**)
3. それ以外の場合 → カスタマーコミュニティライセンス(**Customer Community**)

#レコードの共有
2.の判定で「**自社以外の取引先に紐づくレコードへのアクセスが必要なユーザ**」かどうかの判定が入っているのは、レコードの共有方法がライセンスによって下記のように異なっているからである。

##パートナーコミュニティライセンス、カスタマーコミュニティプラスライセンス
- ロール(*1)
- 共有ルール
- レコードの直接共有

## カスタマーコミュニティライセンス
- 共有セット(*2)
- 共有グループ(*3)

*1 パートナーユーザのロール

- パートナーユーザのロールはパートナー取引先の所有者の下に作成される
- ロールの階層数は、1~3の間でのみ設定可能である
- 自分よりも下位のユーザ所有または共有する全てのデータを参照、編集できる
- 各ロール名には、先頭にパートナー取引先名が自動的に付与される
- スーパーユーザアクセスが割り当て割れたユーザには、同じロールに属する他のユーザまたはそのユーザの下位のユーザが所有するデータにアクセスできる

*2 共有セット

- ユーザの取引先、取引先責任者と一致する取引先、取引先責任者に関連づけられたレコードへのアクセス権を付与する
- ユーザおよび対象レコードから取引先または取引先責任者の間接参照をサポートする共有セットのマッピングを介してレコードへのアクセス権を付与できる

*3 共有グループ
Salesforce ユーザはロール階層内に存在するのに対し、大規模コミュニティユーザ(カスタマーコミュニティユーザ)はロール階層内に存在しないため、共有グループを使用して、大規模コミュニティユーザが所有するレコードにアクセス可能な Salesforce の他の外部ユーザ、またはSalesforce内部ユーザを指定できる

#まとめ
Community Cloudのライセンスとレコードの共有について、個人的に混乱していたので簡単に整理しましたが、他にも様々な観点でのできることやできないことがあります。導入時にはしっかりと要件を見極めてライセンス選定およびアクセス制御の設計を行う必要があります。

#参考
コミュニティユーザライセンス
https://help.salesforce.com/articleView?id=users_license_types_communities.htm&type=5

パートナーユーザロール
https://help.salesforce.com/articleView?id=networks_partner_roles_overview.htm&type=5

共有セット
https://help.salesforce.com/articleView?id=customer_portal_sharing_set.htm&type=5

共有グループ
https://help.salesforce.com/articleView?id=networks_sharing_light_users.htm&type=5
オフラインリアルタイムどう書く E31 の実装例( python )

問題の名前 : ぐるぐる数
問題 : http://nabetani.sakura.ne.jp/hena/orde31rotnum/
実装リンク集 : https://qiita.com/Nabetani/items/d139d5ef70aa23c2d038

次回のイベントは 4/6。最終回にするかも。
see https://yhpg.doorkeeper.jp/events/88379

で。

[MikuriyaHiroshi さんのアイディア]( https://qiita.com/Nabetani/items/d139d5ef70aa23c2d038#comment-da9d83eaa0aaea54a8d3 )をもとに、Python で書いてみた。

```python:pytohn
import json
import sys

def digits(b,x):
  r=[]
  while True:
    if x==0:
      return r
    r.insert(0, x % b)
    x //= b

def less( a, b ):
  if len(a) != len(b):
    return len(a)<len(b)
  return a<b

def impl( b, upper, head, nextnums ):
  sum=0
  for x in nextnums:
    cand = head + [x]
    if less(cand, upper):
      sum+=1+impl(b, upper, cand, [x, (x+1) % b] )
  return sum

def count(b,x):
  if b==2:
    return x
  return impl( b, digits(b,x), [], range(1,b) )

def solve( src ):
  s=src.split(",")
  b = int(s[0])
  x = int(s[1],b)
  y = int(s[2],b)+1
  cx,cy = [ count(b,s) for s in [x,y] ]
  return str(cy-cx)

with open(sys.argv[1], "r") as file:
  data = json.load(file)
  for case in data["test_data"]:
    actual = solve( case["src"] )
    ok = actual == case["expected"]
    print( ("ok" if ok else "**NG**"), case["src"], actual, case["expected"] )
```

python2 でも python3 でも動いた。0.5秒かからないぐらい。

アイディアとしては、どんどん桁を増やしていく感じ。
前の数が決まっていれば、直後の数は二通りしかないので簡単に増やせる。
計算としては無駄になるけど、下限のチェックを省略してソースコードを簡単にした。

なお。
「2進数なら単に引き算する」というショートカットをやめると、30秒以上かかる。

あまり python には慣れていないんだけど、python らしくなっているだろうか。
RaspberryPiにWindowsからファイル転送

##モチベーション
こちら（[Raspberry Pi ssh接続](https://qiita.com/atmaru/items/50e4d9e0b212cbcd7624)）を実施して、windowsからラズパイを触れるようになった。コマンドラインはいいんだが、ファイルを書き換えをしようとすると結局ラズパイを直接触っているいる自分がいた。ファイルはwinsowsで書き換えてラズパイに転送、ということがしたいので、WinScpを導入。

##環境
- RaspberryPi3B+
- Raspbian 9.8
- raspi-configからSSHサーバー機能がONになっていること（[Raspberry Pi ssh接続](https://qiita.com/atmaru/items/50e4d9e0b212cbcd7624)参照）

##WinScpのインストール
～省略（笑）～

##WinScpの設定
ホスト名：ラズパイのIP
ポート番号:22
ユーザー名：pi
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/27a98120-00b9-c5d8-1359-40ced0a117fa.png)

ログイン
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/955e3a5a-410e-dd8f-a16a-39d4d39c15d1.png)
はい
アクセスできました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/29032/5fd98502-5f43-b788-0e43-ee3f9214ff4d.png)
Vuexのactions内で逐次処理を行いたい

Vuexのactionsの中で逐次処理を行いたいことがあり若干書き方に悩んだので備忘録として残しておきます。

### 仕様
- axiosなどを用いて非同期にAPIを叩く=>結果を使って何かしらの処理をする(ex. 取得したデータのexport)
- ↑の処理を結果として取得しうる件数に応じて複数回ループさせたい(ex. 結果が1000件で1度に100件ずつ取得したい場合 => 10回処理を回す)
- ↑の一連の処理をVuexのactionsのなかで行いたい

### 実装

```js

const store = new Vuex.Store({
  state: {
    num: 1,
    fetchSize: 100
  },
  mutations: {
    processStepByStep(state, data) {
      // 何かしらの処理
    },
    setNumber(state, data) {
      state.num = data;
    },
    setTotal(state, data) {
      state.total = data;
    }
  },
  actions: {
    async process({ commit, state }) {
      do {
        // APIリクエストを発行しリソースを取得する, this.$axiosの第２引数でstateを渡せば何件取得するかを指定できるという想定
        const res = await this.$axios.get('sample/url', {query: state});
        // 何回ループを回すのか閾値を取得, res.totalでリソースの合計件数を取得できる想定
        const threshold = Math.ceil(res.data.total / state.fetchSize);
        // res.dataで返り値を取得して何かしらの逐次処理を行う
        commit('processStepByStep', res.data);
        // state.numを更新
        commit('setNumber', state.num++);
      } while (state.num <= threshold)
    }
  }
});
```

### 解説
- axiosなどを使ってHTTPリクエストを発行するとその返り値はPromiseなので単純に変数には格納できない
    - => `await式` を使えば変数に格納して同期処理をしているかのように扱うことができる
- 1回以上複数回ループする可能性がある場合 `do-while構文` が便利
    - `state.fetchSize` で1回のAPIリクエスト実行で取得する件数を指定しているのでこの件数以上取得できるようであればループが複数回実行される
- 1件あたりのリソース取得件数, リソースの取得開始位置は外部変数なのでstateで定義し直接actionsのなかで扱わないようにする

### 終わりに
`Promise.all()` とかを使った方がいいのかなと最初考えたのですが余計な一時変数が増えたりしそうだなと思ってawaitを使った処理に落ち着きました、もっといい書き方がありそうなので思いついたら適宜更新します
Scratch画面からmicro:bitエッジ接続機器を制御する方法

#■はじめに
***Scratch Link***ってmicro:bitのボタンやセンサーとの連携はできるようだが、Scratchからmicro:bitに向けては、LED表示の操作しかできないようです。でもせっかくの連携機能なので、***micro:bitに接続した機器をScratchの画面から操作したい***。。。。。ということで、またまたハックにチャレンジして成功してしまいました。***Scratchの画面から、micro:bitの特定ピンをON/OFFすることに成功***したので、その方法を紹介します。

#■今回やること
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234533/6d565bd4-bca0-c83d-d5e0-13dd0255e94a.png)
#■このピンをON/OFFさせる仕組み　(ここが本記事の肝)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234533/383bd2f0-4ff0-042b-57c6-770da11e5468.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234533/2baeef7c-b3a7-9e74-c3da-bf2f4d2a7e33.png)
#■全16通りについてLチカで試してみました
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/microbit?src=hash&amp;ref_src=twsrc%5Etfw">#microbit</a> <a href="https://twitter.com/hashtag/ScratchLink?src=hash&amp;ref_src=twsrc%5Etfw">#ScratchLink</a><br>Scratch Linkでmicro:bitのLEDを操作してエッジのColピンをON/OFFする方法、Col1,2,3.7の4ピンの組み合わせ全16パターンでも動作するかLチカで確認してみた。複数でも特に変な電圧降下とかないみたいで、正常動作確認した。 <a href="https://t.co/4jvk5dAjjn">pic.twitter.com/4jvk5dAjjn</a></p>&mdash; Google Homer (@google_homer_) <a href="https://twitter.com/google_homer_/status/1104739193920479232?ref_src=twsrc%5Etfw">2019年3月10日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
#■注意事項
意図しない場合でも、LEDに何か表示さえされればピンが反応してしまいます。モーター等の可動機器を接続している場合は特に注意してください。対応プログラムを起動した後に、制御対象の機器の電源を入れる事を推奨します。
#■利用例
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234533/a978da8e-5082-8a66-ab26-2b75d7abca18.png)
###デモ動画
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/microbit?src=hash&amp;ref_src=twsrc%5Etfw">#microbit</a> <a href="https://twitter.com/hashtag/ScratchLink?src=hash&amp;ref_src=twsrc%5Etfw">#ScratchLink</a><br>Scratch Linkでmicro:bitのLEDを操作しエッジのColピンをON/OFF→光MOS FET→micro:bitからDCモーターに供給した電源をスイッチング。<br>micro:bitのLEDの特定表示パターンでエッジのColピンをデジタル制御できることがわかった。 <a href="https://t.co/XDDbrq6AGi">pic.twitter.com/XDDbrq6AGi</a></p>&mdash; Google Homer (@google_homer_) <a href="https://twitter.com/google_homer_/status/1104628171708624896?ref_src=twsrc%5Etfw">2019年3月10日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#以下は、この仕組みの元となっているmicro:bitの挙動を調査した結果です。興味のある方だけ見ていただければと思います。何かに応用できるかもしれないと思い記述しました。
#■LED表示とColピンの関係
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234533/e55536df-a733-3acc-59ce-d7cb5141988b.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234533/cd9cc7a7-87a7-9bf1-83cf-9c3f42cfcec8.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/234533/021c6ece-78bb-0964-b5a2-a9e348422448.png)
println is not console.log in Scala.js

Scala.jsの`println`は`console.log`ではなくラップされたもので、`toString`が呼ばれてしまう。

```scala
val obj = js.Dynamic.literal(xxxx = 1)
println(obj)                        // => [object Object]
js.Dynamic.global.console.log(obj)  // => { xxxx: 1 }
```

# おまけ

`js.Object`を出力するのには`console.log`が適切そうだけど、case classを出力したい場合はprintlnを使うほうが便利。

```scala

case class Hoge(xxxx: Int)
val obj = Hoge(1)
println(obj)                                 // => Hoge(1)
js.Dynamic.global.console.log(obj.toString)  // => Hoge(1)
```

case classは何らかの方法でjs側で扱えるものに変換しなけれぼ`console.log`で出力することはできない。js側でObjectとしてそのまま使うことはできない。
【備忘録】vimのコマンド集

*常時追記していきます

現役エンジニアの方が「vim超使いやすい！」「もうvim以外使えない。」なんておしゃられている記事やツイートをよくみます。

ドットインストールや大手プログラミングスクールなど、初心者向けの講座ではテキストエディタは「atom」を用いている場合が多く、とっつきやすいエディタですね〜

vimはとっつきやすさで言うとatomには及ばないなと僕自身プログラミングを始めた当初は思っていたのですが、プログラミングの師匠に我慢してvimを使えと言われてしばらく使っているとvimにどんどんハマっていきました、、、（笑）

ってなわけで、あくまでも自分用の「備忘録」としてよく使うコマンドや、便利なコマンドをまとめていきま〜す！

##起動編
```
#基本
$ vi ファイル名 ・・・ファイルを指定して起動
$ vi ファイル１ ファイル２ ファイル3... ファイルn ・・・ファイルを複数起動
$ vi -R ファイル名 or $ view ファイル名 ・・・読み込み専用で起動

#初期表示位置を指定してからの起動
$ vi ファイル名　・・・最後の行から起動
$ vi +行数 ファイル名　・・・指定の行から起動
$ vi +/文字列　・・・文字列が最初に見つかった場所から表示

#その他
$ vi -r ファイル名 ・・・壊れたファイルをリカバリする
```

##移動編
###カーソル移動
```
#1文字移動
h or [BackSpace] ・・・ ←
j or [Ctrl]+[n] ・・・ ↓
k or [Ctrl]+[p] ・・・ ↑
l ・・・ →

#数字指定移動
数字[h] or 数字[BackSpace] ・・・ 数字 ←
数字[j] or 数字[Ctrl]+[n] ・・・ 数字 ↓
数字[k] or 数字[Ctrl]+[p] ・・・ 数字 ↑
数字[l]　・・・ 数字 →

#行移動
[^] ・・・今いる行の先頭
[$] ・・・今いる行の最後
[gg] ・・・1行目の先頭
[G] ・・・最終行の先頭
[Enter] ・・・次行の先頭位置へ
[:数字] ・・・指定表へ移動

#単語移動
[w] ・・・1語次へ
[b] ・・・1語前へ
[e] ・・・単語末尾へ
```
###画面移動
```
#１画面移動
[control] + [f] ・・・１画面次へ (forward)
[control] + [b] ・・・１画面前へ (back)

#半画面移動
[control] + [d] ・・・半画面次へ (down)
[control] + [u] ・・・半画面前へ (up)
```
##終了編
SQL Developer オブジェクトを選択した際に別のタブで開く

・メニューバー ＞ ツール ＞ プリファレンスを選択
・プリファレンスダイアログ　＞　データベース　＞　オブジェクト・ビューアを選択
・「データベース：オブジェクト・ビューア」　＞　「オブジェクト・ビューア・ウィンドウの自動固定」にチェックを入れる
・一番下の「OK」ボタンを押す
hyperledger-fabricにブロックチェーンを学ぶ（1/9）ブロックチェーンとは

~~[グレイトフル・デッドにマーケティングを学ぶ](https://www.amazon.co.jp/%E3%82%B0%E3%83%AC%E3%82%A4%E3%83%88%E3%83%95%E3%83%AB%E3%83%BB%E3%83%87%E3%83%83%E3%83%89%E3%81%AB%E3%83%9E%E3%83%BC%E3%82%B1%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%82%92%E5%AD%A6%E3%81%B6-%E3%83%87%E3%82%A4%E3%83%B4%E3%82%A3%E3%83%83%E3%83%89%E3%83%BB%E3%83%9F%E3%83%BC%E3%82%A2%E3%83%9E%E3%83%B3%E3%83%BB%E3%82%B9%E3%82%B3%E3%83%83%E3%83%88/dp/4822248526)~~

⇒ hyperledger-fabricにブロックチェーンを学ぶ（1/9）ブロックチェーンとは
　 [hyperledger-fabricにブロックチェーンを学ぶ（2/9）サンプルを動かす](https://qiita.com/ctrlzr/items/550a2a019c3c763d4f47)
　 [hyperledger-fabricにブロックチェーンを学ぶ（3/9）ブロックを見る]
(https://qiita.com/ctrlzr/items/487e4055151aab9a5591)
　 [hyperledger-fabricにブロックチェーンを学ぶ（4/9）kafkaを入れる](https://qiita.com/ctrlzr/items/d8d50d909a9a75cbf5b6)
　 hyperledger-fabricにブロックチェーンを学ぶ（5/9）可視化する


ブロックチェーンネットワークは、オープン、コンソーシアム、プライベートの３タイプに分けられる。[ブロックチェーン比較](https://medium.com/mold-project/%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%83%81%E3%82%A7%E3%83%BC%E3%83%B3%E6%AF%94%E8%BC%83-%E3%83%91%E3%83%96%E3%83%AA%E3%83%83%E3%82%AF-%E3%83%97%E3%83%A9%E3%82%A4%E3%83%99%E3%83%BC%E3%83%88-%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%82%B7%E3%82%A2%E3%83%A0%E5%9E%8B-490853ff0cfd)
　オープン：誰でもアクセス可能
　コンソーシアム：認証された人のみアクセス可能
　プライベート：一人だけアクセス可能

hyperledger-fabricはコンソーシアムになる。
![image.png](https://ctrlzr.sakura.ne.jp/img/ameblo/nanio.gif)
何を言っているのか分からねーと思うので

#### システム構成
１組織の最小構成は以下のようになる。
※１枠が一つのサーバで、dockerで構築する。peerとDBで最小構成とするのは現実とかけ離れ過ぎる気がしてやめた。
![bcn.jpg](https://qiita-image-store.s3.amazonaws.com/0/63018/1b8a8406-0652-b6f9-fc0f-46e0bde183c4.jpeg)

- caはCertificate Authorityの略で、peerにアクセスするための認証を担う。
- peerはブロックチェーンを持っている。すべてのpeerで同じブロックチェーンを持つ。チェーンコードは検証に参加する場合に必要。
- DBは標準でstatedbがバンドルされている。CouchDB、BerkeleyDBが選択できる。CouchDBはdocker image。BerkeleyDBはOracle製品。

#### DBには何が入っているのか？

ブロックチェーンは実行したメソッドと引数しか保持していない。つまり、
ポルナレフからイギーに10円送金するメソッドをsend(ポルナレフ,イギー,10)とすると、ブロックチェーンが保持しているのはsend(ポルナレフ,イギー,10)だけで、ポルナレフとイギーがいくら持っているかは、ブロックチェーンでは分からない。
ポルナレフの所持金を見るには、DBからポルナレフをキーに取得する必要がある。

#### チェーンコードは何をするのか？

ポルナレフからイギーに10円送金するとき、手数料をとられるケースを考える。
送金額の1%を手数料とすると、send(ポルナレフ,イギー,10)では、ポルナレフの所持金から10.1円を引き、元締めに0.1円足し、イギーに10円を足す。
この一連の処理を行うのがチェーンコードだ。
チェーンコードが実行されるとブロック生成される。つまり、
ブロックがチェーン状に連なる。

#### ブロックチェーンで知ったかぶりをする

**DBに保持されているのは現在の値、ブロックチェーンに保持されているのは履歴**
これさえ言えれば、いかにも知った風は装えるだろう。
チェーンコードについては上記だけでは足りないので、知ったかぶりをするときに触れてはいけない。

つづく（システム構築の予定）
JavaScriptでundefinedを判定する時の注意点

JavaScriptでundefinedを比較する時の注意点です。
## JavaScriptでundefinedを比較する時の注意点
`typeof`を使い、比較するのよりも直接`===`で`undefined`比較するのが良いです。
下に例と解説を載せます。

```javascript
console.log(typeof foo === "undefined"); // true
console.log(foo); // エラー
const foo = undefined;
console.log(foo); // undefined
```

このように、まだ宣言していない変数を評価するとエラーが発生してしまいます。
ですが、`typeof`で調べればこのエラーの心配はありません。
しかし、そのような場合はエラーだとはっきりわかった方が良いので、`===`を使って比較するべきです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
Python: Numbaでクラスの高速化

[前回の続き](https://qiita.com/nabenabe0928/items/a02964d8b48619b1e348)．

numbaでクラスの高速化．
ただし，クラスの継承はできない模様．また，単純にNumbaに対応させようとしても，意外とコードの手直しが必要がなことは難点であるが，一応投稿．

ひとまず，書き方は以下の通り．

```py
spec = [
        ("メンバ変数1", メンバ変数1の型),
        ("メンバ変数2", メンバ変数2の型),
        ....
        ("メンバ変数n", メンバ変数nの型)
	]

@jitclass(spec)
class ...():
...

```

```py
from numba import jit, f8, b1, i8, void
from numba import jitclass
import numpy as np
import random

spec = [
        ("width", i8),
        ("array", f8[:,:])
	]

@jitclass(spec)
class test():
  def __init__(self, w):
    self.width = w
    array = np.array([random.random() for i in range(self.width)])

  def start(self):
    cnt = 0    
    for a in self.array:
      cnt += a
    
    print(cnt)

if __name__ == "__main__":
  cls = test(10000000)
  cls.start()
```
Carloでホットリロードしながら開発するためのwebpack-dev-serverの設定

話題の Carlo で何か作ってみようと思い、Vue CLI で作ったプロジェクトの開発モードと組み合わせようとして、環境設定に少しつまづいたのでメモ。

# Carlo設定
```javascript:main.js（Carlo起動スクリプト）
// Tell carlo where your web files are located.
app.serveOrigin('https://localhost:8080')
```
これにより localhost の内容が Carlo で表示されるようになります。
※開発中は上記の設定で、ビルド後は `app.serveFolder(__dirname)` 等を使用するよう、環境変数などで分岐を入れることになると思います。


# webpack-dev-server設定
```javascript:vue.config.js
module.exports = {
  devServer: {
    disableHostCheck: true,
    headers: {
      'Access-Control-Allow-Origin': 'https://domain'
    },
    host: 'localhost',
    https: true
  }
}
```
今回 Vue CLI なのでこのファイル名ですが、他の場合も `webpack.config.js` に同様の設定を追加すれば動くと思います。

# 経緯
最初、デフォルト設定の `http://localhost:8080` を Carlo で読み込むように設定して起動したら画面が真っ白になっていて、 DevTools を開いたらJS等が読み込めていませんでした。
コンソールで location を調べると、 `https://domain/index.html` となっていたので、とりあえず HTTPS に変更してみたところ、画面は表示されましたがHMR部分でエラーが出ました。
あとはエラー内容をググりながら、 host → disableHostCheck → headers の順に追加したところで、ようやく HMR が動くようになりました。


# おまけ
Carlo を立ち上げたときに Chrome DevTools も開く設定。（Chrome の起動オプションです。上記の Carlo の設定同様、開発モードのみ有効になるように調整する必要がありますね）

```javascript:main.js（Carlo起動スクリプト）
  const app = await carlo.launch({
    args: ['--auto-open-devtools-for-tabs']
  })
```

また、localhost を HTTP 化した後に、「この接続はプライバシーが保護されません」という Chrome の警告画面が出るようになり、毎回許可するのが面倒だったので、上記 args に `--allow-insecure-localhost` を入れていたのですが、いま試しにはずしたら警告は表示されなくなっていた……。devServer の設定を https だけに戻しても警告は出ないので、一度設定したら出なくなるのかも？
Linuxの時刻合わせ

# はじめに

例えばシステムに障害が起きた時など、ログを確認する時には日時が非常に重要です。
複数のサーバーでシステムを構成している場合、それぞれのサーバーの時刻がバラバラだと、障害時に状況の把握や原因究明の足枷となる可能性があります。

以下は、自宅で運用しているサーバーで使っている時刻合わせのスクリプトと、その設定方法です。
本番環境では負荷に耐えられるNTPサーバーを指定したり、時刻合わせの間隔を調整する必要があるので、スクリプトや設定を適宜修正する必要があると思いますが、何かの参考になれば幸いです。

# 使用した環境

* OS：CentOS 6.10

# 事前準備

* 時刻合わせに使うntpdateパッケージをインストールしておきます。
* ntpと異なり、ntpdateコマンドは「NTPサーバーとの時刻差が大きくてもエラーとならない」のが特徴です。

```shell
[root@kumotori ~]# yum install ntpdate -y
```

# 時刻合わせ用スクリプト

* 時刻合わせに使うNTPサーバーは、googleのPublic NTPサーバー（time.google.com）を指定しています。
* `/sbin/clock --systohc`は「ハードウェアクロックをシステムクロックに合わせる」という設定です。
 * ハードウェアクロック：マザーボード上で管理される時刻で、OSをシャットダウンしても消えませんが、マザーボード上の電池（ボタン電池）が切れると消えてしまいます。
 * システムクロック：OSが管理する時刻で、OSがシャットダウンすると消えてしまいます。

```shell:ntpdate.sh
#!/bin/sh

/usr/sbin/ntpdate -s time.google.com
/sbin/clock --systohc
```

# タイムゾーンの設定

# スクリプトの配置

* 任意のフォルダに上記のスクリプトを配置しています。
 * 私は`/root/scripts`というフォルダを作って、そこに上記のスクリプトを配置しています。
* 配置した後、スクリプトに実行権限（x）を付けておきます。
* 最後に`crontab -e`で、crontabに「毎時30分に上記のスクリプトを実行する」と設定して完了です。

```
[root@kumotori ~]# chmod 744 /root/scripts/ntpdate.sh 
[root@kumotori ~]# ls -l /root/scripts/
合計 4
-rwxr--r--. 1 root root 75  3月 10 15:48 2019 ntpdate.sh
```

```:crontab
### ntpdate.
30 * * * * /root/scripts/ntpdate.sh
```
【Unity】EditorGUIUtility.SetIconSizeを使うよりIconSizeScopeを使おう

#概要

EditorGUIUtilityにはGUILayout.LabelなどGUIContentで表示するアイコンのサイズを変更できるSetIconSizeという関数があります。この関数を呼ぶことで、この場面ではアイコンを小さくしたい、この場面では大きくしたいなど状況に応じて変更を行うことができます。

ただ、デフォルトのサイズに戻したいときに、変更前にGetIconSizeでデフォルトのサイズを取得して変数に保持しておくのは手間に感じました。これを改善できないか調べた所IconSizeScopeを使うことで、上記の問題が解決しそうだということがわかりました。

#IconSizeScopeとは

IconSizeScopeとは、GUI.Scopeを継承したScopeです。
GUI.Scopeはusingを使うことでコンストラクタで初期化処理を、using内の処理が終わったあとに呼ばれるIDisposable.Dispose()で解放処理を呼ぶことができるものです。
IconSizeScopeではコンストラクタにVector2を渡すことでアイコンのサイズを設定し、Disposeで変更前のサイズに戻してくれます。

#実装

例として32x32の大きさでアイコンを表示し、それ以降はデフォルトのサイズで表示するように実装したいと思います。まずIconSizeScopeを使わなかった場合はこうなります。

```cs:NoneIconSizeScopeTest.cs

//あらかじめデフォルトのサイズを取得
var defaultIconSize = EditorGUIUtility.GetIconSize();

//32x32で表示するように設定
EditorGUIUtility.SetIconSize(new Vector2(32,32));

//アセットの表示に使われているアイコンを持ってきて表示
var texture = AssetDatabase.GetCachedIcon("アセットのパス");
GUILayout.Label(texture);

//デフォルトのサイズに戻す
EditorGUIUtility.SetIconSize(defaultIconSize);

```
事前にデフォルトのサイズを取得しないといけなかったり、最後に元のサイズに戻さないと行けなかったりと意識しないといけない所がありますね。

ではIconSizeScopeを使うとどうなるかというと、こうなります。

```cs:IconSizeScopeTest.cs

//using内では32x32のサイズで表示するように設定
using(var iconSizeScope = new EditorGUIUtility.IconSizeScope(new Vector2(32,32)))
{
    //アセットの表示に使われているアイコンを持ってきて表示
    var texture = AssetDatabase.GetCachedIcon("アセットのパス");
    GUILayout.Label(texture);
}

//usingの外に出たためDisposeが呼ばれ、以降はデフォルトのサイズで表示される

```

意識しないといけなかった所がなくなって、呼び出すだけでよくなったためシンプルな構造になりました。
また、usingを使っているためこの中では32x32のサイズになっていると明示的に確認できるようになったため、他のアイコンも一緒に表示したいときにもこの中に入れれば表示されるというのがわかりやすくなったのも良い点だと思いました。

#まとめ

IconSizeScopeはGUI.Scopeを継承しているため、コンストラクタでアイコンのサイズを変更し、解放処理で元のサイズに戻すことができました。
Scope系は他にもあると思いますので、調べたらまた記事にしたいと思います。

#参考
[IconSizeScope][1]
[1]:https://docs.unity3d.com/ja/current/ScriptReference/EditorGUIUtility.IconSizeScope.html