OmniAICreator/Qiita-1.07M huggingface dataset:
Solidityで文字列のlengthを取得する方法

## 前提
Solidity v0.5.0 において
現状、文字列(String)にはlengthメソッドが存在しない。
しかしながらbytesにはlengthメソッドが存在している。

## 方法
そのため、文字列を一度bytesに変換してから、そのbytesのlength(uint)を取得することで文字列のlengthを取得する。
string -> bytes -> uint

## 環境
* Solidity 0.5.0


## サンプルコード
　以下にそのコードを記載しているので、Remixなどで試していただきたい。
例えば、"hoge"という文字列を与えると、lenは4になる。

``` solidity
pragma solidity ^0.5.0;
contract StrLen {   
    function getStrLen(string memory _str) public returns(uint) {
        uint len = bytes(_str).length;
        return len;
    }   
}
```



## サンプルを動かした結果

```
getStrLen("hoge")

len: 4
```

<img width="720" alt="スクリーンショット 2018-12-26 15.32.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/93401/8592fe7d-c280-2196-0bb4-c4c1459bcc65.png">



ただし、文字列に平仮名などを与えると当然想定外の数値が返ってくるので注意。

```
getStrLen("ぽよ")

len: 6
```

<img width="720" alt="スクリーンショット 2018-12-26 15.33.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/93401/f47cb151-db52-ce11-7266-d3fb96c2cf53.png">
Fusion 360 をコツコツとマスターする（3）スケッチとボディとコンポーネント


# SketchとBodyとComponent、そしてAssembly

##　SketchとBodyとComponentの関係

前回のポストでシリンダーを作成した段階でのプロジェクトの内容。

<img src='https://qiita-image-store.s3.amazonaws.com/0/103139/266d96d2-fa86-1ef4-1b38-070dc9133bb8.png' width='626' />

電球アイコンのオン・オフとマウスの選択でボディーとスケッチの違いが分かります。

まずはボディー（シリンダー）

<img src='https://qiita-image-store.s3.amazonaws.com/0/103139/4672adbe-a8a7-3d9d-b2ed-182d324ce7f1.png' width='517' />

次にスケッチ（円）

<img src='https://qiita-image-store.s3.amazonaws.com/0/103139/aa4c50a5-1ab6-562a-bda6-1361e9a31800.png' width='562' />

コンポーネントというと、一番上の（Unsaved）という名前のものがこのプロジェクトに含まれる唯一のコンポーネント。

<img src='https://qiita-image-store.s3.amazonaws.com/0/103139/2beea10e-68af-1bec-dafd-ea1635afb529.png' width='570' />

ここでまず押さえておきたい関係は

- スケッチからボディーが作られる
- コンポーネントはスケッチとボディーを含む

という点。

## BodyをComponentにする（推奨しない方法）

では、このボディー（シリンダー）を元にしてComponentを新規作成してみます。

<img src='https://qiita-image-store.s3.amazonaws.com/0/103139/ad6325bc-1b1d-5a41-5819-fa5302984fd8.png' width='519' />

二つの重要な変更が加えられました。

まずは、新しいコンポーネント（Component1:1)が作成されたこと。

ボディー（シリンダー）はそのままボディーとして存在しますが、その位置が作成されたコンポーネントの一部として変更されています。

この新しいコンポーネントには`Origin`というフォルダーも存在することに注意。これはコンポーネントの重要な特性です。

重要な変更点のもうひとつは、トップレベルにあったコンポーネントがコンポーネントからアセンブリに変換されたということ。アイコンが白いキューブから、三つのキューブから成るものに変更されたことに着目。

<img src='https://qiita-image-store.s3.amazonaws.com/0/103139/a9a549cb-7d0a-4619-2ca5-5d341592a24d.png' width='587' />

アセンブリは複数のコンポーネントからなる機械全体を含んでいて、コンポーネントはお互いに何等かの動きのある関係をもつことが出来る部品として機能するのです。

## Componentを最初から作ってBodyを作る（推奨される方法）

では、結果としては同じになる（しかし重要な点で異なる）コンポーネントとアセンブリの作成の手順を見ていきます。

まずは空の新規デザイン（プロジェクト）から始めます。

<img src='https://qiita-image-store.s3.amazonaws.com/0/103139/e0739b41-f8e2-d482-52d7-1451d9c925d2.png' width='469' />

次に、いきなり新規のコンポーネントを加えます。

<img src='https://qiita-image-store.s3.amazonaws.com/0/103139/bbafea47-7712-2428-f360-f77a230b0f17.png' width='468' />

すると、トップのコンポーネントはアセンブリとして変換され、その下部に部品としてComponent1:1が加えられました。

このコンポーネントにやはりシリンダーを加えてみます。

<img src='https://qiita-image-store.s3.amazonaws.com/0/103139/a91b1905-6481-5051-53bb-fa646190e67a.png' width='629' />

完成しました。

二つの流れで一つのコンポーネントを含むアセンブリを作成しましたが、その流れの違いはこうです。

非推奨
1. プロジェクトを作成
2. スケッチを作成
3. ボディーを作成
4. ボディーからコンポーネントを作成

推奨
1. プロジェクトを作成
2. コンポーネントを作成
3. スケッチを作成
4. ボディーを作成

この二つの流れで異なるのはコンポーネントを作成する以前の作業です。非推奨ではスケッチの作成とボディーの作成はトップレベルのコンポーネントに対しての動作なので、ヒストリーもそのように記録されています。何しろ新しいサブのコンポーネントは存在していなかったので。

<img src='https://qiita-image-store.s3.amazonaws.com/0/103139/f9e06f92-a815-e85a-1353-0e2730122636.png' width='298' />

対照的に、推奨されるパターンの場合、スケッチ作成とボディー作成の操作は新規で作成したコンポーネントに対して行われています。よって、ヒストリーもそのように記録されています。

<img src='https://qiita-image-store.s3.amazonaws.com/0/103139/8e53d954-1172-8057-f630-482c49ca344d.png' width='297' />

Fusion 360はヒストリーが表示されるだけでなく、ヒストリーに示されるタイムラインをさかのぼることも出来ます（Gitのコミットと同じだと考えて差し支えないでしょう）。しかし、非推奨のヒストリーを使ってタイムラインをさかのぼるとスケッチとボディーの作成が最新の状態でのコンポーネントとは別のものになってしまします。もっと複雑な操作をしていたとしたらどうでしょう、大変なことになります。

ということで、覚えておくべきことは一つだけ。ちょっとしたお試しプロジェクト以外は、かならず新規プロジェクトを作成したらすぐに新規コンポーネントを作ること。
[Azure入門]Azure IaaSのネットワーク①~VM上でパブリックIPが表示されなかった件~

Azureの入門書レベルに記載している当たり前のことなのですが、
久しぶりに触れてびっくりしたことをゆるゆるまとめて腹落ちさせていこうと思うので
お付き合いいただければ:wink:


同じ仮想NW上に配置したAzure2台のVMでPINGを実行したい。
やりたいことはただそれだけでした。

ただそれだけだったのですが・・・

###パブリックIP(XXX.XXX.XXX.XXX)でssh接続

```
C:\Users\user1>ssh user1@XXX.XXX.XXX.XXX
Enter passphrase for key 'C:\Users\user1/.ssh/id_rsa':
user1@webhst001:~$
```



### ip address show(or ifconfig)を実行
SSH後ip address showを確認。


```
$ ip address show
:上略
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0d:3a:f1:26:d4 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.4/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever
:下略
```

**ん!?パブリックIP(XXX.XXX.XXX.XXX)でアクセスしているのにプライベートIP(10.0.0.4)しかないぞ。。**
pingをするその前に混乱。。

###なぜパブリックIPがないのーーー!?
AzureのVMは下記ページのパブリックIPの説明部分にもありますが
プライベートIPのみをもっていてNAT(正確にはNAT)しているからパブリックIPはVM上のNICには割り当てられていないんですね。

###パブリックIPはどこで割り当てられているのか
技術的にはここまで単純ではないのですが、概念としては下記のようになっており、
パブリックIPはロードバランサ(Azure LoadBalancer)によって割り当てられています。


![スライド1.PNG](https://qiita-image-store.s3.amazonaws.com/0/297303/8049ff5e-a2bf-03c3-897d-bfe91d63299d.png)

たとえばPC1(yyy.yyy.yyy.yyy)からhost1(xxx.xxx.xxx.xxx)へsshをする場合、
ロードバランサがhost1(xxx.xxx.xxx.xxx)の22番ポートへのアクセスを
10.0.0.4の22番ポートへ変換してくれるので通信ができるんですね:open_mouth:
神様、仏様、ロードバランサ様です💛


### 詳細が知りたい方は・・
公式ではなくちょっと古いので現行と差があるかもしれませんが、こちらの2記事が良記事でした。
私もまだ詳しく読めていないのですが、Azure Load Balancerというのは機材の名前ではなくサービス名で複数の機材の集合体ということを知るだけでも勉強になります:relaxed:

・[Azureのロードバランサ事情 - ロードバランサの中ってどうなっているの？]( https://qiita.com/yuhattor/items/60e4547019473761be3f)
・[ロードバランサのアーキテクチャいろいろ](
http://yunazuno.hatenablog.com/entry/2016/02/29/090001)


### 本題のpingは・・
今回はAzureの超基本であるパブリックIPはNAT変換されるということをまとめましたが、
次回はpingをして遊んでいきたいと思います:relaxed:
FLEXBOXの2行目以降での不足分を javascriptで補う

まずは以下の画像を御覧ください。
FLEXBOX（justify-content:space-between）で子要素を並べたものです。
![スクリーンショット 2018-12-26 15.04.09.png](https://qiita-image-store.s3.amazonaws.com/0/126335/3ddb8555-f6a2-a4d8-458f-dd65458bec55.png)

本来であれば、2列目の画像は左詰めになってほしいところですが、space-betweenの影響で画像3枚の均等割付になってしまいます。
これを左詰めにするには、最大数（画像の場合は4枚）になるよう不足している分だけの空要素を追加してあげないと期待通りの表示になりません。
ちなみに余りが1（画像が5枚の場合）の時は勝手に左に詰めて表示されます。

```javascript
function flexCompletion(parentDOMId, maxCount, childDOM){
  document.addEventListener('DOMContentLoaded', function(){
    var parentDOM = document.getElementById(parentDOMId);
    var childCount = parentDOM.childElementCount;
    var addCount = maxCount - childCount % maxCount;
    if(addCount > 1){
      for(var i = 0; i < addCount; i++){
        var element = document.createElement(childDOM);
        parentDOM.appendChild(element);
      };
    }
  }, false);
};
flexCompletion('js-photoframe', 4, 'span');

```

以上。
Action_Cableを用いたチャットアプリのメモ -1

##目的
マッチングアプリを作成するにあたって、トークルームを実装したい。
ActionCableについてあとで見返して分かるようにメモ。

グループの作成までを目標にする。


##参考にしたサイト
Rails 5の目玉機能「Action Cable」で双方向通信を実装（１）
https://codezine.jp/article/detail/10153

##手順
####1. railsアプリの作成
省略する。

注. 後ほどActionCable作成時にcoffeeスクリプトが作成され、その中でjqueryを用いる。
そのため、Gemfileに `gem 'jquery-rails'`を追記。


####2. controllerの作成
チャットの入力、表示のためのcontrollerとviewsを用意する。

`bin/rails g controller talkRooms index`

```erb:app/views/talk_rooms/index.html.erb
<div id="talk_rooms">
</div>
</br>
<form>
    <label>
        発言する: <input type="text" data-behavior="speak_talk_rooms">
    </label>
</form>

```
`#talk_room`の中には発言された内容が入る。


####3. modelの作成
投稿者のIDと内容を保存するため以下のコマンドを実行する。

　`bin/rails g model talk_room user_id:integer message:text`

####4. channelの作成
ここからがActionCableの出番！。
`rails g channel`でジェネレートする。
第一引数はチャネル名
第二引数は自動で追加したいメソッドを指定する。
`rails g contoller`と似ていますね。

`bin/rails g channel talk_room speak`
ここではcontroller,modelと名前を合わせて第一引数に`talk_room`を、第二引数には`speak`を指定。

####4. クラインアント側（送信）
```coffee:app/assets/javascripts/channels/talk_room.coffee
（略）
  speak: (message) ->
    @perform 'speak', message: message #引数にmessageを追加

  $(document).on 'keypress', '[data-behavior~=speak_talk_rooms]', (event) ->
    if event.keyCode is 13
     App.talk_room.speak event.target.value
     event.target.value = ""
     event.preventDefault()
```
このcoffeeスクリプトはクライアント側から呼び出される。
`@perform`のあとの`'speak'`は`channels/talk_room_channel.rb`の中の`speak`メソッドを示している。
keypressイベントの`App.talk_room.speak`では`talk_room.coffee`内のspeakメソッドを呼び出している
修正する点は、speakメソッドの引数に`message: message`を追加する。

注. `app/assets/javascripts/talk_rooms.coffee`と勘違いしやすいかも。

keypressイベントでは、`'data-behavior~=speak_talk_rooms'`に対して、keyCode=13(returnキー)の入力を取得し、フォーム内の内容を取得している。
取得後はフォームの内容を空にして、送信を中断する。

####5.　サーバ側での処理
```rb:app/channels/talk_room_channel.rb
class TalkRoomChannel < ApplicationCable::Channel
  def subscribed
    # stream_from "some_channel"
    stream_from 'talk_room_channel'
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end

  def speak
    ActionCable.server.broadcast 'talk_room_channel', message: data['message']
  end
end
```
`subscribed`メソッドでは、どこに配信するかを指定している。これをストリームといい、`stream_from`で指定する。
また`speak`メソッドでは、第一引数`talk_room_channel`に対してサーバ側から第二引数の発言メッセージを配信する。
先程クライアント側で引数に指定した`message: message`は`data['message']`で取り出せる。

####6. クライアント側（受信）
```coffee:app/assets/javascripts/channels/talk_room.coffee
（略）
 received: (data) ->
    # Called when there's incoming data on the websocket for this channel
    $('#talk_rooms').append '<div>' + data['message'] + '</div>'
（略）
```

クライアント側（coffeeスクリプト）でreceivedメソッドを用いる。
最初に`talkRooms/index.html.erb`に用意した`#talk_rooms`タグ内に`data['message']`を追加する。

####7. 続き
> https://qiita.com/susiyaki/items/f73ee633c45894dd7f2a
Amazon VPC と他ネットワーク機器とのVPN接続

###1.カスタマーゲートウェイの作成###

a.「カスタマーゲートウェイ」から「カスタマーゲートウェイの作成」をクリック。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/a5e4e812-c777-d15d-c248-2e7cef6afa4f.png)

b.以下のとおり入力し、「カスタマーゲートウェイの作成」をクリック。

|項目|説明|
|----------|-----------|
|名前|適当な名前を入力します。|
|ルーティング|「動的」を選択する場合は、「BGP ASN」も入力しますが、今回は「静的」で作成していきます。ほとんどは「静的」かと。|
|IP アドレス|対抗側のアドレスを入力します。|

![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/5c824bbf-65bf-8f0c-b6b0-6cce5fcc849b.png)

c.以下のとおり作成されれば、作成完了です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/1f9fb14f-42c5-630a-740c-9cfd6522db1e.png)


---


###2.仮想プライベートゲートウェイの作成###

a.「仮想プライベートゲートウェイ」から「仮想プライベートゲートウェイの作成」をクリック。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/e174ba6b-6bf1-3ebf-3a1c-7a62336fafe8.png)

b.以下のとおり入力し、「仮想プライベートゲートウェイの作成」をクリック。

|項目|説明|
|----------|-----------|
|名前|適当な名前を入力します。|
|ASN|Amazon のデフォルト ASN|

![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/f15c3250-301e-d330-799d-3f832f06ea40.png)

c.以下のとおり作成されれば、作成完了です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/90155bb8-f6c8-f269-e281-ffce5c789bac.png)


---


###3.Site-to-Site VPN 接続###

a.「Site-to-Site VPN 接続」から「VPN接続の作成」をクリック。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/92fb04b3-5595-8abd-56f8-b2074a577058.png)

b.以下のとおり入力し、「VPN接続の作成」をクリック。

|項目|説明|
|----------|-----------|
|名前タグ|適当な名前を入力します。|
|仮想プライベートゲートウェイ|「2.仮想プライベートゲートウェイの作成」で作成したものを選択|
|カスタマーゲートウェイ |既存 |
|カスタマーゲートウェイ IP | 「1.カスタマーゲートウェイの作成」で作成したものを選択|
|ルーティングオプション | 静的|
|静的 IP プレフィックス　|IP Prefixes　を入力　|

![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/0925cf14-9fce-3c6b-83e2-dae3aaa2d245.png)

c.以下のとおり作成されれば、作成完了です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/ecb3c3fd-e31d-fcff-62ea-f501037ce8f8.png)


---


###4.設定のダウンロード###

「設定のダウンロード」で、対抗側のコンフィグが表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/a1b0beb7-94ad-8c73-129c-345e23d3e3d2.png)



###5.注意事項###

- 仮想プライベートゲートウェイはイニシエータではないため、カスタマーゲートウェイがトンネルを開始する必要があります。
- [AWS re:Invent 2016: Deep Dive: AWS Direct Connect and VPNs (NET402)](https://www.youtube.com/watch?v=Qep11X1r1QA) カスタマゲートウェイ側から生成されたトラヒックでトンネルが確立されるたびに、暗号パラメータがネゴシエートされ、これらのパラメータに基づいてトンネルが確立される。
MacへのSolidity(solc)のインストール or アップデート

いつも忘れるのでメモ。
installもupdateも↓でOK。

```bash
brew update
brew upgrade
brew tap ethereum/ethereum
brew install solidity
brew link --overwrite solidity
```

# エラーが出る場合

以下のエラーが出た場合はxcodeのバージョンを上げる。

```bash
==> Installing solidity from ethereum/ethereum
Error: Your Xcode (9.0) is too outdated.
Please update to Xcode 10.1 (or delete it).
Xcode can be updated from the App Store.
```
jQueryで超簡単モーダル表示

#実装したいこと
indexでeach文で表示させてる記事の➕ボタンを押すと
モーダル表示出来るようにしたいです。
具体的にいうと、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/301628/2b5496ca-1564-316a-e3d7-6be28c2de436.png)

これの➕ボタンを押すと

![image.png](https://qiita-image-store.s3.amazonaws.com/0/301628/6bb6d0e1-24d4-579a-9807-ff776a5d812e.png)

このようにモーダルが出てくるようにしたいです。


#まずはビューを編集

```ruby:index.html.haml
<i class="fa-plus">
</i>
<div class="modal-background">
  <div class="modal">
    <div class="escape">
　　　　　　　　　　　&times;
    </div>
  </div>
</div>
```

fa-plusは➕ボタンのことです。
modal-backgroundはモーダル表示させた時の後ろの
modalは表示させたいモーダルのことです。
escapeは❌ボタンのことです。

次にcssです。

#cssを編集

```css
.modal-background{
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 100;
  text-align: center;
  display: none;
}

.modal{
  position: absolute;
  top: 50%;
  left: 50%;
  -ms-transform: translate(-50%,-50%);
  -webkit-transform : translate(-50%,-50%);
  transform : translate(-50%,-50%);
  background-color: $whitecolor;
  border-radius: 4px;
  width: 360px;
  min-height: 450px;
}
```

modal-backgroundのdisplay: none;がキモですね。
<b>これにより、通常の画面ではモーダルが表示させないようにしてます。</b>
➕ボタンを押したらjQueryでモーダルを表示させてやるって感じですね。

また、モーダル表示させたら基本的に背景の灰色は画面いっぱいにしてあげたい&下にスクロールした時にはみ出ないようにしたいので
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
をしてあげてます。
z-indexで、ボックスの重ね位置を手前にしています。

modalは、これは位置を決めているだけです。

#jQueryをいじる

```javascript:modal.js

$(document).on('turbolinks:load', function(){
  $(function(){

    $('.fa-plus').on('click', function(e){
      e.preventDefault();
      $(this).siblings().fadeIn();
    });

    $('.escape').on('click', function(e){
      e.preventDefault();
      $('.modal').fadeOut();
    });

  });
});

```

こんな感じですね。
fa-plus(➕ボタン)をクリックすると発火するようにしてます。
$('.modal').fadeIn();
でやればいいのでは？と思われるかもしれませんが、
今回は、<b>each文で記事を一つずつ表示させてます。</b>

もし、$('.modal').fadeIn();と書いてしまうと記事の分だけモーダルが表示されてしまいます（記事がもし１００個あったら、モーダルも１００個表示される）

これを防止するために
＄（this）で他のfa-plusとは違うということを認識させて
$siblings()で兄弟要素であるmodalを取得してます。
そして、fadeInでmodal-backgroundのdisplay:noneを解除してあげてます。

#終了！ありがとうございました！
MacでTex環境を構築【その１】

MacでTeX環境を構築する方法について書いていきます。

# MacTeX 2018 をダウンロード＆インストール

 [ここ](http://ftp.jaist.ac.jp/pub/CTAN/systems/mac/mactex/)から
mactex-20180417.pkg (2018/12/26現在) をダウンロード.
ダウンロードした MacTeX をインストール.

# .styファイルのダウンロード
今回はjlisting.styのダウンロードを例にとって説明します.
特にダウンロードしたいstyファイルがない場合は飛ばしてください.

## jlisting.sty をダウンロード

jlisting は日本語を含むソースコードを表示するために必要.

1. [ここ](http://prdownloads.sourceforge.jp/mytexpert/26068/jlisting.sty.bz2)よりjlisting.styをダウンロードし解凍.

1. styファイルの保存場所の確認
listing.styと同じ場所に保存するため以下のコマンドでファイルの場所を検索する.
    
    ```
    kpsewhich listing.sty
    ```

1. 解凍したstyファイルを先程確認したディレクトリに移動.
移動先は先程確認したディレクトリ.

    ```
    sudo mv jlisting.sty /usr/local/texlive/2018/texmf-dist/tex/latex/listing/
    ```

    platex実行時に jlisting の権限がないと言われたらchmodで権限を付与.

    ```
    sudo chmod +r /usr/local/texlive/2018/texmf- 
    dist/tex/latex/listing/jlisting.sty
    ```

1. 変更を反映させる.

    ```
    sudo mktexlsr
    ```


# 確認

以下のような TeX ファイルを作成.

```test.tex
\documentclass{jarticle}
\usepackage{listings,jlisting}

\lstset{
language = C++,   
breaklines = true,
numbers = left,
frame = tbrl,
tabsize = 4,
captionpos = t
}

\title{Mac で Tex 環境を構築}
\author{}
\date{}

\begin{document}
\maketitle

\section{Test}

MacTeX Test.
TeX テスト。

\section{ソースコードの表示}
\begin{lstlisting}
#include <iostream>
using namespace std;

int main(){
    int a = 0;
    cout << a << endl; # aを出力
    return 0;
}
    
\end{lstlisting}

\end{document}
```

コンパイル.

```
platex test.tex
dvipdfmx test.dvi
```

正しくPDFファイルが作成できたら成功.



# フォントのエラーでpdfを作成できない場合

ヒラギノフォントの埋め込みをする必要があります.
[ここ](https://github.com/munepi/bibunsho7-patch/releases)よりdmgファイルをダウンロードします.
dmg ファイルダウンロード後，中の app ファイルを起動するだけでヒラギノフォントが利用できるようになります．
素晴らしいですね.munepiさんに感謝です.
Galaxyのadminとしてユーザーを削除する(GDPR対応)

# Galaxy上でユーザーを削除する

[Galaxy のadminとしてユーザーを追加する](https://qiita.com/percipere/items/24b026531e344d5bb6f0)では、登録したユーザーをGUI上で削除する方法は提供されていない事に触れた
さて、そうなるとこのシステムはEUのGDPR(General Data Protection Regulation)に準拠しない事になる
そのような事態への対策は、ベータ版の段階ではあるけれども一応なされていて、galaxy.yml内で設定可能となっている

## enable-beta-gdprの利用
[Galaxy configurationのenable-beta-gdpr](https://docs.galaxyproject.org/en/latest/admin/config.html#enable-beta-gdpr)を利用する事でEUのGDPRを意識した運用がある程度可能になっている

> Enables GDPR Compliance mode. This makes several changes to the way Galaxy logs and exposes data externally such as removing emails and usernames from logs and bug reports. It also causes the delete user admin action to permanently redact their username and password, but not to delete data associated with the account as this is not currently easily implementable. You are responsible for removing personal data from backups. This forces expose_user_email and expose_user_name to be false, and forces user_deletion to be true to support the right to erasure. Please read the GDPR section under the special topics area of the admin documentation.

上記に記載されている通り、ログファイルやバグレポートにユーザー名やメールアドレスを出力しない事に加えてadmin権限でユーザーの削除が可能だ
ただし、ユーザーのデータは消去しないのでそこは適切に対処する必要がある
詳細は[GDPR compliance](https://docs.galaxyproject.org/en/latest/admin/special_topics/gdpr_compliance.html#gdpr-compliance)参照の事

実際にユーザーの消去が可能になっている事を確認してみよう

##ベータ版GDPR機能の有効化

galaxy.ymlの`enable-beta-gdpr`を書き換える代わりに
dockerで`-e GALAXY_CONFIG_ENABLE_BETA_GDPR=True`を指定してGalaxyを起動してみる

```bash
$ docker run -d --rm \
    -p 8080:80 -p 8021:21 -p 8022:22 -p 8800:8800 \
    --volumes-from galaxy-store \
    --privileged=true  \
    -e GALAXY_CONFIG_ENABLE_BETA_MULLED_CONTAINERS=True \
    -e GALAXY_CONFIG_REQUIRE_LOGIN=True \
    -e GALAXY_CONFIG_ALLOW_USER_CREATION=False \
    -e GALAXY_CONFIG_ENABLE_BETA_GDPR=True \
    -e ENABLE_TTS_INSTALL=True \
    bgruening/galaxy-stable
```

## ユーザーの無効化(Delete機能)
このサーバーにadminでログインし、Adminのメニューから`Users`をクリックすると"Delete"や"Undelete"の機能が利用できるようになっていることが確認できる
![Screen Shot 2018-12-26 at 13.57.13.png](https://qiita-image-store.s3.amazonaws.com/0/213053/92d73405-a180-2d5a-43e5-47b3e737c0ae.png)

"Delete"をクリックするとEmailとUser Nameがハッシュ値に置き換わる
![Screen Shot 2018-12-26 at 14.10.16.png](https://qiita-image-store.s3.amazonaws.com/0/213053/c17ee5d4-586c-62c4-9473-3520029ffdfd.png)

ユーザーが削除(無効化)されているどうかは、このリストをずっと右にスクロールすると表示される"Status"のコラムが"deleted"となっている事で確認できる
![Screen Shot 2018-12-26 at 14.29.01.png](https://qiita-image-store.s3.amazonaws.com/0/213053/49405392-fb9b-9762-be22-4e8c418c832a.png)



## ユーザーの有効化(Undelete機能)
ハッシュ値になってしまったユーザーを選択して"Undelete"を行うとユーザーが復活する
ユーザー名の右のドロップダウンリストから"Undelete"又は、ユーザーリストのチェックボックスをクリックしてリストの下部の"Delete"ボタンをクリックする
![Screen Shot 2018-12-26 at 14.10.25.png](https://qiita-image-store.s3.amazonaws.com/0/213053/84ff0c44-b068-8fc0-ce51-f5054c477898.png)

リストの上部にUndeletedが成功したと表示される
![Screen Shot 2018-12-26 at 14.10.29.png](https://qiita-image-store.s3.amazonaws.com/0/213053/982d6543-6272-614d-77fe-0defd58682e0.png)
右にスクロールすれば"Status"のコラムの"deleted"表示が消えている事も確認できる


今回はここまで:smile:
C++ Builder XE4 > Tips > 列挙子の定義が分からない (例: TeeChartのGridのStyleの定義) > デザインで変更して.dfmで検索

```txt:動作環境
C++ Builder XE4
```

### 疑問点

- TeeChartのGridの定義をコードにてDotからDashにしたい
- XXXDashのXXXが分からない
- ユーザガイドを探す時間を節約したい

### 案

1. デザイン画面でDashに変更し保存
    - .dfmが書換えられる
2. .dfmで「Dash」で検索

下記が見つかった。

```.dfm 
    LeftAxis.Grid.Style = psDash
```

psDashをコードで使って設定できることが分かった。

```cpp
void __fastcall TForm1::Button1Click(TObject *Sender)
{

	Chart1->Axes->Left->Grid->Style = psDash;

	// グリッド横方向の線
	Chart1->Axes->Left->Grid->Width = 5;
}
```


### 関連

- [C++ Builder XE4 > TeeChart > グリッド線の太さをコードで変える](https://qiita.com/7of9/items/afb6268564fa5aeeb01a)
CentOS7にRedisをインストールする

# CentOS7 に Redis をインストールする

CentOS7にRedisをインストールしてPHPから使えるようにする。

epelリポジトリをインストールする。

```
# yum install epel-release
```

yumコマンドを実行するたびにepelを参照するのでepelを無効にして、必要なときだけ使用するように設定を変更する。

```file:/etc/yum.repos.d/epel.repo
[epel]
enabled=0
```

epelリポジトリを使用するときは`yum <コマンド> <パッケージ名> --enablerepo=epel`でコマンドを実行する。
Redisをインストールしたいので、epelリポジトリを指定して`redis`をインストールする。

```
# yum install redis --enablerepo=epel
```

Redisの設定を変更する
メモリがいっぱいになったときに、有効期限が設定されたキーの中でより短い有効期間（TTL）のキーを削除する`maxmemory-policy volatile-ttl`を指定する。

```file:/etc/redis.conf
maxmemory 256m
maxmemory-policy volatile-ttl
```

Redisのサービスを有効にして起動する。

```
# systemctl enable redis.service
# systemctl start redis.service
```

PHPのRedisクライアントモジュールをインストールする。

```
# yum install php-pecl-redis --enablerepo=epel
```

すべてのインストールが完了したらApacheを再起動して、`redis`が読み込まれているかを確認する。

```
# systemctl restart httpd.service
# php -m | grep redis
```
C++ Builder XE4 > TeeChart > グリッド線の太さをコードで変える

```txt:動作環境
C++ Builder XE4
```

### 処理概要

- TeeChartのグリッド線の太さをコードで変更する

### 実装

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <DateUtils.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	// ダミーデータ作成

    Chart1->Series[0]->XValues->DateTime = true;
    Chart1->BottomAxis->DateTimeFormat = L"nn:ss";

    TDateTime dt;

    dt = Now();

    double yval;
    for (int idx=0; idx < 10; idx++) {
        yval = (1+ idx) % 2;
        Series1->AddXY(dt, yval, "", clRed);
        dt = IncSecond(dt, 1);
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	// グリッド横方向の線
	Chart1->Axes->Left->Grid->Width = 5;
}
//---------------------------------------------------------------------------
```

### 動作例

ソフト起動直後
![2018-12-26_14h08_19.png](https://qiita-image-store.s3.amazonaws.com/0/32870/a2c3dfff-be99-0c1b-0eca-2774853e4864.png)

Button1押下後
![2018-12-26_14h08_32.png](https://qiita-image-store.s3.amazonaws.com/0/32870/fabf181f-1d3b-14e5-5432-5f8a97fc097b.png)

グリッド横方向の線の個々が丸くなった。
なぜか?

グリッド線のデフォルト定義が「Dot」であるため。
![2018-12-26_14h08_57.png](https://qiita-image-store.s3.amazonaws.com/0/32870/b09ace19-dd8b-1077-70a5-7c306bfafa3c.png)

丸くなるのを避けるには「Dash」を使う、など。
Railsでお手軽ランキング機能

今回はいいね順に記事を３つ表示する方法を書いていきたいと思います。

#前提
・記事のテーブル名はnotesとする
・いいね機能のテーブル名はlikesとする
・いいね機能は実装しているものとする
・htmlではなくhamlで説明する

#コントローラをいじる

@all_ranksを追加してあげてます。

```ruby:app/controller/notes_controller.rb
  def index
    @all_ranks = Note.find(Like.group(:note_id).order('count(note_id) desc').limit(3).pluck(:note_id))
  end
```

これだけで、いいね順に記事をランキング形式で取ってくる事ができます。

今回はindexでやってますが、別に他のアクションでも構いません。あくまで例です！

＠all_ranksの説明をします。

```ruby:@all_ranksの説明

Like.group(:note_id)#まず、記事の番号(note_id)が同じものにグループを分ける
order('count(note_id) desc')#それを、番号の多い順に並び替える
limit(3)#表示する最大数を3個に指定する
pluck(:note_id)#そして最後に:note_idカラムのみを数字で取り出すように指定。


Note.find()#最終的に、pluckで取り出される数字をノートのIDとすることでいいね順にnoteを取得する事ができる

@all_ranks = Note.find()#最後に＠all_ranksに代入
```

という感じです！楽勝ですね！

#ビューで表示させる

```ruby:app/view/notes/index.html.haml

- @all_ranks.each do |note|
#後はご自身で表示させたいカラム名を打ち込むだけ！
```

たったこれだけです！eachでいいね順に<b>５つ</b>の記事がランキングで表示できます！

#####もし、第１位、２位とか数字を表示させたい時は、with_index(1)を使ってあげてください！
```ruby:rank.html.erb
- @all_ranks.each.with_index(1) do |note, i| %>
    第
    = i
    位
  = note.title
```

とりあえず、これで終了です！

#番外編〜自分のノートをランキングにしたい時〜

もし、自分のノートのみをランキング表示させたい！となった時には

```ruby:app/controller/notes_controller.rb
  def index
    @all_ranks = Note.find(Like.group(:note_id).order('count(note_id) desc').limit(3).pluck(:note_id))
    @my_ranks = @all_ranks.select{ |note| note.user_id == current_user.id }
  end
```

＠my_ranksを追加してあげてください。

＠all_ranksは配列になっています。
なのでselectメソッドを使うことにより、user_idがcurrent_userのidじゃないやつは弾いています！
これで自分の記事のみをランキング表示できます！

# さらに補足〜コントローラを綺麗にしたい上級者向け〜
今のコントローラの@all_ranksの定義はめちゃくちゃ冗長ですし、本来コントローラは<b>データを用意</b>するためにあるものです。
もっと良いRailsの使い方があるので、@all_ranksの定義をモデルにクラスメソッドとして書いちゃいましょう！

##モデルにメソッドを書く
```ruby:note.rb
  def self.create_all_ranks #Noteクラスからデータを取ってくる処理なのでクラスメソッド！
    Note.find(Like.group(:note_id).order('count(note_id) desc').limit(3).pluck(:note_id))
  end
```

create_all_ranksというクラスメソッドを定義しました！
これをコントローラで使ってあげると、、

```ruby:app/controller/notes_controller.rb
def index
  @all_ranks = Note.create_all_ranks
end

```
これでしっかりと取得できているはずです！
コントローラが綺麗になりましたね。


#終了！ありがとうございました！
いいねを頂けたらめっちゃ嬉しいです！
Cloud Firestoreの柔軟性を利用して新しいパーミッションの仕組みを考えた

## はじめに
どうも、[@1amageek](https://twitter.com/1amageek)です。
これは僕が実践で利用しているテクニックの一つです。応用範囲が広いので、まとめることにしました。

## Cloud Firestoreの設計で困るところ
- ルールがめんどくさい
- ルールによって構造を変えなければならない

特に問題なのはReadですね。やっぱりセキュアに保ちたいドキュメントをルートコレクションに配置することはできないし、かと行ってサブコレクションにすると横断的にQueryかけないし

と言うことで、ブログの構造について考えてみましょう。

## 今までのブログの構造

RDBであれば、例えばデータベースの構造はこんな感じかな？

__article table__

| id | title | body | is_published | author |
|---|---|---|---|---|
| 0 | hoge | hoge | false | 1amageek |
| 1 | hoge1 | hoge | true | 1amageek |
| 2 | hoge3 | hoge | true | 1amageek |
| 3 | hoge4 | hoge | true | 1amageek |

公開・非公開は`is_published`で管理するような形。

Firestoreなら次の二つが考えられる。

```typescript

// /version/1/article/0
{
  title: "hoge",
  body: "hoge",
  isPublished: true,
  author: "1amageek"
}

// もしくは

// /version/1/user/1amageek/article/0
{
  title: "hoge",
  body: "hoge",
  isPublished: true,
  author: "1amageek"
}
```

どっちがいいでしょうか？
前者は、検索性に優れているけど、`isPublished === true`を入れ忘れただけの簡単なヒューマンエラーでサービス潰す可能性ありますよね？😇
僕ならやりたくない。と言うことで、後者にしましょう。

いや待てよ。。。🤔

公開した時に必ず全文検索を噛ませないといけない。。orz

このくらいはCloud Firestoreだけでやりたいじゃん。

## Cloud Firestoreの特性を使えばできますよ
ではどちらの構造を使えばいいでしょうか？

__正解はどちらも使う__

次の構造をみてください。

```typescript

// 未公開時の記事はuserのSubCollectionに
// /version/1/user/1amageek/article/0
{
  title: "hoge",
  body: "hoge",
  isPublished: true,
  author: "1amageek"
}

// 公開時の記事はRootCollectionに
// /version/1/article/0
{
  title: "hoge",
  body: "hoge",
  author: "1amageek"
}

```

Cloud Firestoreには__WriteBatch__と呼ばれる機能が入っています。二つのノードを同時に安全に更新できることで、一つのノードを更新・一つのノードへは追加を同時できます。

他の手段として、CloudFunctionsに任せるのもいいかもしれません。次のノードをトリガーにセットして

```
/version/1/user/1amageek/article/${article_id}
```

`isPublished == true`なら、次のノードへデータを渡す。

```
/version/1/article/${article_id}
```

これでセキュアかつ、横断的な検索が可能なブログを作ることが可能となります。

---

Cloud Firestoreについて気になり始めたら次もどうぞ

- [Cloud Firestoreを実践投入するにあたって考えたこと](https://qiita.com/1amageek/items/d606dcee9fbcf21eeec6)
Djangoのadmin管理画面にデータベースの項目を追加

サーバーを起動してadmin画面を確認
初期設定は「グループ」と「ユーザー」のみ。
新規に作成した、テーブル名を表示させる。

http://xxxxx.com/admin/

![サイト管理   Django サイト管理 (2).png](https://qiita-image-store.s3.amazonaws.com/0/187963/42c3f961-2cd6-85e2-10ff-a40c2326be3f.png)
今回アプリケーション名はreportで、モデルはこんな感じです。

```models.py
from django.db import models

# Create your models here.
class Company(models.Model):
    name = models.CharField(verbose_name='アカウント名', max_length=255)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
```

migrateで追加したアプリケーションフォルダの配下のadmin.pyを編集します。

```
$ {project}/{application}
$ report_site/report

$ vim admin.py
```

```admin.py
from django.contrib import admin

# Register your models here.

#下の２行を追加
# from アプリケーション名.models import マイグレーションのクラス名
from report.models import Company
admin.site.register(Company)
```

![サイト管理   Django サイト管理 (3).png](https://qiita-image-store.s3.amazonaws.com/0/187963/2d2ff46d-b7fa-5ae6-6382-a535ec4a51ed.png)

![変更する company を選択   Django サイト管理.png](https://qiita-image-store.s3.amazonaws.com/0/187963/47b74168-31fd-b94e-c54b-7d313edfd35e.png)


### 参考記事
https://qiita.com/taijijiji/items/343fb56ab94eee28c401
Seven Puzzle

# [Seven Puzzle](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0121)
- 蟻本に乗ってる例題
- 今年の3月くらいに挑戦してわからなかったやつがようやくわかった（今12月だぞおい）


## 考察

- 盤面を１つのノードとしてみれば、最初の盤面からBFSできそう

<img width="1090" alt="seven_puzzle_1.png" src="https://qiita-image-store.s3.amazonaws.com/0/218584/fee29be7-134a-f93f-187b-dc834bf0afdc.png">



- ２行だからわかりづらいけど、盤面は$8!=40320$通りとなる
- 入力として与えられる盤面は最大で$1000$個なので、入力されるたびに計算する方法では間に合わない
- なので、最初に全盤面について計算すると良い





## 解法

1. 初期盤面(01234567)から全盤面に遷移するまでの手数を求める
2. 入力で盤面を受け取る。受け取った盤面に対応する手数を出力する



## [コード](http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=3312251#1)

```cpp
#include <bits/stdc++.h>
using namespace std;

const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, -1, 1};

using vi = vector<int>;

map<vi, int> mp; // mp[ある盤面]: その盤面に到るまでの手数

void bfs(vi origin) {
  // キューの初期化
  queue<vi> que;
  que.push(origin);
  // データの初期化
  mp[origin] = 0;

  while (que.size()) {
    // 軸を取り出す
    vi axis = que.front(); que.pop();

    // 0の場所を求める
    int zeroPos = 0;
    for (int i = 0; i< axis.size(); i++) {
      if (axis[i] == 0) zeroPos = i;
    }
    int y = zeroPos / 4, x = zeroPos % 4;
    int pos = y * 4 + x;

    // 軸から行ける場所を列挙
    for (int i = 0; i < 4; i++) {
      int ny = y + dy[i], nx = x + dx[i];
      if (ny < 0 || ny >= 2 || nx < 0 || nx >= 4) continue;
      int npos = ny * 4 + nx;
      vi next = axis;
      swap(next[npos], next[pos]);
      if (mp.count(next)) continue;
      // 行けるならキューとデータを更新する
      mp[next] = mp[axis] + 1;
      que.push(next);
    }
  }
}


signed main() {
  // 前処理
  vector<int> origin(8);
  iota(origin.begin(), origin.end(), 0);
  bfs(origin);

  string s;
  while (getline(cin, s)) {
    vi v;
    for (int i = 0; i < s.size(); i+=2) {
      v.push_back(s[i] - '0');
    }
    // 前処理の結果を出力するだけ
    cout << mp[v] << endl;
  }

  return 0;
}
```



## 当初疑問だったこと

### 疑問

- BFSとは違うアルゴリズムを使えば、より最善の手数がわかるのでは...?と思った。
- BFSでなぜ最善手を求めることができるのかがわからなかった

<img width="511" alt="seven_puzzle_2.png" src="https://qiita-image-store.s3.amazonaws.com/0/218584/f8e0d9b5-179e-e263-5ed3-672ca6fb8960.png">


### 答え

- 初期盤面から１手目、２手目、３手目、…のように列挙していく。なので、「５手目に出てきた盤面が実は３手で行けた」みたいなことは起こらない。それに「５手目に出てきた盤面が実は３手で行けた」としたら、２手目の近傍ですでに出てきているはずである
- １手目は初期盤面の近傍、２手目は１手目の盤面からの近傍、３手目は２手目の盤面からの近傍、みたいになる。なので、n手目であげる盤面は、必ず最善手となる



![seven_puzzle_3.png](https://qiita-image-store.s3.amazonaws.com/0/218584/95eca5c2-c151-3ec5-db84-dada60c835e1.png)



## 要点

- 盤面を１つの状態として考える
  - これが慣れてなくてなかなか馴染まなかった
  - この考え方ができれば、BFSが思いつきやすくなると思う。たぶん



## 参考記事

- [つ、つたじぇー☆](http://tsutaj.hatenablog.com/entry/2017/12/23/000000)



## 感想

- 今年(2018)の3月くらいにつたさんに質問した問題。当時は7割程度しか理解できなかった。ふと思い立って、つたさんとのDM振り返ったら理解できた。嬉しみが深い
Elm 0.19に移行する

# Elm 0.19に移行する
Elm 0.19リリース直後に、既存の0.18なプロジェクトで一度試してパッケージが足りなくて断念したのですが、改めて試したところなんとか移行ができたので、振り返りもかねてまとめておきます。

## 主な手順
1. [elm-upgrade](https://github.com/avh4/elm-upgrade)をかける
2. 0.19がサポートされてないパッケージの依存を解決する
3. 型エラーを直す
4. CI設定やRailsの設定を直す

## [elm-upgrade](https://github.com/avh4/elm-upgrade)
以下のコマンドを実行して何かしら失敗したらGitでコードを戻してやり直します。

```bash
npm install elm@elm0.19.0
npm install elm-format@elm0.19.0
npx elm-upgrade@latest
```

`elm-upgrade` のいうとおりにしていれば単純なめんどくさい作業は大体終わっています。
`elm-format` という最近流行りの標準的なコードフォーマッターがかかるので行数が増えるのは注意点かもしれません、

## パッケージ依存を解決する
`elm make` を走らせても、パッケージの問題でそもそもコンパイルがはじまらないので、それをいい感じに直してきます。
公式パッケージは大体移行できるので、対応してなさそうなサードパーティを削除していくのが早いです。

0.19対応してないパッケージがあるので、そういったのは代わりを探したり、標準的なパッケージの機能を組み合わせたりで代替できないか模索します。
今回は、幸いすべての代替を見つけることができたんですが、互換性をわかりやすく壊していくというスタイルとはいえどうしてもアップグレードし続けるというのはマンパワーが必要だなと感じます。

特に、[Elm Bootstrap](http://elm-bootstrap.info/)には助けられました。
0.18では[elm-dialog](https://github.com/krisajenkins/elm-dialog)を使っていたんですが、機能的にもよりよくなっていて移行してよかったです。

## 型エラーやバグを直す
Elmの方針として、互換性というのはわかる形でどんどん壊していくので、それに追従します。
今まで使えてた方法は、設計のまずさなどの理由で変わってしまうことが多いので、リファクタリングを兼ねて粛々と修正します。

[公式で移行ガイド](https://github.com/elm/compiler/blob/a936e95a4d915a41f501ce70878675e20df03d60/upgrade-docs/0.19.md)があるので、それがヒントになることもあります。

今回、困ったのは [`fmod`](https://package.elm-lang.org/packages/elm-community/basics-extra/3.0.1/Basics-Extra#fmod) 関連の変更でした。
名前が [`fractionalModBy`](https://package.elm-lang.org/packages/elm-community/basics-extra/latest/Basics-Extra#fractionalModBy)に変わり引数の順序が変わっています。
名前が変わった時点で気づけばよかったのですが、引数の順番が変わっているのに気づくまで手間取ってしまいました。

## CI設定やフレームワークの設定
関連コマンドが全部 `elm` に集約されたのでそれらをいい感じに直します。
`elm-package` がなくなって `elm make` に統合されたので、コマンド数が減ったのでかなりすっきりするかと思います。

未だに[sprockets](https://github.com/rails/sprockets)でこうゆうことをしているので、はやく[webpack](https://webpack.js.org/)に移行したいです...。

## 事後評価
アップグレード作業というのはどうしてもしんどかったり検証が大変なんですが、Elmの場合は検証がツールに全部任せられるので安心してできました。
また、しんどいところは技術的な負債が原因の一端なので、それらを同時に返すことができると考えると相応の価値があるのでよかったです。
超絶技巧演習問題 - Coq

一発ネタかつフランツ・リストの超絶技巧練習曲のパロディです。

```coq
(** * 超絶技巧演習問題 - Coq *)

Require Import Coq.Init.Prelude Coq.Init.Nat.

Open Scope nat_scope.


Definition felmat
  : forall n : nat, 2 < n -> ~ exists x y z, 0 < x /\ 0 < y /\ 0 < z /\ x ^ n + y ^ n = z ^ n.
Proof.
  (* [Admitted] を [Qed] に取り換えて、この空欄を埋めよ *)
Admitted.


Definition catalanic a b x y := 1 < a /\ 1 < b /\ 1 < x /\ 1 < y /\ x ^ a = 1 + y ^ b.

Definition catalan
  : forall a b x y, catalanic a b x y -> x = 3 /\ a = 2 /\ y = 2 /\ b = 3.
Proof.
  (* [Admitted] を [Qed] に取り換えて、この空欄を埋めよ *)
Admitted.


Definition baudetic (P : nat -> bool) a b c n := forall p, p < n -> P (a + b * p) = c.

Definition baudet
  : forall P, exists c, forall n, exists a b, baudetic P a b c n.
Proof.
  (* [Admitted] を [Qed] に取り換えて、この空欄を埋めよ *)
Admitted.


Definition collatzic n := if even n then div2 n else n * 3 + 1.

Definition collatz
  : forall n, n <> 0 -> exists p, iter p collatzic n = 1.
Proof.
  (* [Admitted] を [Qed] に取り換えて、この空欄を埋めよ *)
Admitted.
```

## 解説

* `felmat`, `catalan` - フェルマーの最終定理、カタラン予想と呼ばれる問題です。どちらもディオファントス方程式の形になっていて、こういう問題は簡単に書けるくせに難問だったりします。Coq でも `Coq.Init.Prelude` に足し算などがそろっているので簡単に記述することが出来ますが、冪はデフォルトで利用できず `Coq.Init.Nat` をインポートしないといけないのでちょっと嵌りました。どちらも肯定的に解決していますが、その証明は非常に高度です。
* `baudet` - 「自然数全体の集合を二つの集合に分けたとき、少なくとも一つの集合は任意の長さの等差数列を含む」。ちょっとマイナーですが、この予想に関する歴史はとても面白いです。詳細は参考文献を見てください。未解決です。
* `collatz` - 「それが偶数だったら二で割り、それが基数だったら三を掛けて一を足す」という操作を考えます。このとき、ゼロではない全ての自然数に対して、その操作を繰り返していったとき、いつかは必ず一になるという問題です。計算してみると成り立ちそうなのですが、たまにたくさん繰り返さないと一にならない数があったりして言い切れません。未解決です。

## 参考文献

* [フェルマーの最終定理 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A7%E3%83%AB%E3%83%9E%E3%83%BC%E3%81%AE%E6%9C%80%E7%B5%82%E5%AE%9A%E7%90%86)
* [カタラン予想 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%AB%E3%82%BF%E3%83%A9%E3%83%B3%E4%BA%88%E6%83%B3)
* [コラッツの問題 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%A9%E3%83%83%E3%83%84%E3%81%AE%E5%95%8F%E9%A1%8C)
* [謎の数学者バウデットが死の直前に遺した真珠 - INTEGERS](http://integers.hatenablog.com/entry/2017/09/06/221401)
Mac で Terminal の k8s 操作環境を改善する

[Kubernetes完全ガイド impress top gearシリーズ](https://www.amazon.co.jp/dp/B07HFS7TDT/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)を読みながら設定した時のメモ。

# kubectl コマンドを補完する

kubectl コマンドの補完、Pod/Node 名などの補完が出来る

[Enabling shell autocompletion](https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion)

自分の場合 `zsh` を使っており、`~/.zshrc`に以下を追加して対応

```~/.zshrc
# kubectl completion
source <(kubectl completion zsh)
```

これで補完されるようになった

# alias を作成する

以下を追加

```~/.zshrc
# kuebctlc alias
alias k='kubectl'
```

これで以下のように打てる。

```bash
$k get nodes
NAME                                              STATUS    ROLES     AGE       VERSION
ip-172-31-0-56.ap-northeast-1.compute.internal    Ready     <none>    6d        v1.11.5
ip-172-31-19-51.ap-northeast-1.compute.internal   Ready     <none>    6d        v1.11.5
ip-172-31-23-75.ap-northeast-1.compute.internal   Ready     <none>    6d        v1.11.5
```


# プロンプトに context/namespace 情報を表示する

[kube-ps1](https://github.com/jonmosco/kube-ps1)を利用します。

```bash
$ brew update
$ brew install kube-ps1

・・・(略)

You may wish to add the GOROOT-based install location to your PATH:
  export PATH=$PATH:/usr/local/opt/go/libexec/bin
==> kubernetes-cli
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

zsh completions have been installed to:
  /usr/local/share/zsh/site-functions
==> kube-ps1
Make sure kube-ps1 is loaded from your ~/.zshrc and/or ~/.bashrc:
  source "/usr/local/opt/kube-ps1/share/kube-ps1.sh"
  PS1='$(kube_ps1)'$PS1

```

自分は `zsh`なので `~/.zshrc`に追記

```~/.zshrc
# kubec-ps1
source "/usr/local/opt/kube-ps1/share/kube-ps1.sh"
PS1='$(kube_ps1)'$PS1
```

```bash
$source ~/.zshrc
```

無事表示できた。

```bash
(⎈ |arn:aws:eks:ap-northeast-1:xxxx:cluster/eks-second-cluster:default)  ~
```

ただ、クラスター名が長すぎて画面が狭くなってしまうという問題が。。

[ Trim cluster name & namespace name #53 ](https://github.com/jonmosco/kube-ps1/issues/53)

変えればいい。

>For the cluster, you can do a rename (alias) with kubectl:
kubectl config rename-context old_name new_name

やってみる。


```bash
$kubectl config rename-context arn:aws:eks:ap-northeast-1:xxxx:cluster/eks-second-cluster eks-second-cluster
Context "arn:aws:eks:ap-northeast-1:xxx:cluster/eks-second-cluster" renamed to "eks-second-cluster".
(⎈ |eks-second-cluster:default) ~
```

context を変えて長すぎないようにした。
この状態でも `kubectl`コマンドも正しく実行可能。

# cluster/namespace の切り替えを補完する

`kubectx`　を使う。

[ ahmetb /kubectx ](https://github.com/ahmetb/kubectx)


Mac の場合、`brew install kubectx` で終わり。
これで補完も効いてくれる。
tkinterでthread その3

#概要

tkinterでthreadやってみた。
threading.Eventで、thread止めてみた。

#サンプルコード

```
from tkinter import *
import time
import threading

def _delete_window():
    try:
        flg.clear()
        time.sleep(2)
        root.destroy()
    except:
        pass

def draw():
    while flg.is_set():
        str.set(time.strftime('%I:%M:%S'))
        time.sleep(1)

def func0():
	flg.set()
	t = threading.Thread(target = draw)
	t.start()
	print ('start')

def func1():
	flg.clear()
	print ('stop')

flg = threading.Event()
flg.set()
root = Tk()
root.protocol("WM_DELETE_WINDOW", _delete_window)
frame = Frame(root)
frame.grid(row = 3, column = 3)
startbutton = Button(frame, text = "Start", command = func0)
startbutton.grid(row = 0, column = 0, sticky = NSEW)
stopButton = Button(frame, text = "Stop", command = func1)
stopButton.grid(row = 0, column = 1, sticky = NSEW)
str = StringVar()
str.set('')
label = Label(frame, textvariable = str)
label.grid(row = 0, column = 2, sticky = NSEW)
t = threading.Thread(target = draw)
t.start()
root.mainloop()


```

以上。
Microsoft Azureのcomputer visionでカンタンな分析をしてみよう

お仕事でちょっと下調べしたのがあったので、折角なのでqiitaで共有

# 0. 環境
- python 3.7 (Anacondaをpre-install)にて動作確認

# 1. 必要なlibrary設定

```py
import requests
import matplotlib.pyplot as plt
import json
from PIL import Image
from io import BytesIO
```

# 2. Subscriptionなどの設定

```py
## Setting for cloud side
SUBSCRIPTION_KEY = ## Subscription keyの指定
vision_base_url = "https://japaneast.api.cognitive.microsoft.com/vision/v2.0/" ## 利用regionにより適宜変更して下さい

## Setting for local images
WKDIR = ## 画像のディレクトリを指定
IMG_FILE = ## 画像ファイル名(jpg, png)
```

## 3. API用の設定

```py
image_path = WKDIR + IMG_FILE
analyze_url = vision_base_url + "analyze"

image_data = open(image_path, "rb").read()
headers = {'Ocp-Apim-Subscription-Key': SUBSCRIPTION_KEY,
          'Content-Type': 'application/octet-stream'}
params  = {'visualFeatures': 'Categories,Description,Color'
          ,'language': 'ja'} ## 日本語なら'ja'
data = {'byte': image_data}
```

# 4. APIをcallしてみよう

```python
response = requests.post(analyze_url, 
                         headers=headers, 
                         params=params, 
                         data=image_data)
```

# 5. 結果を確認しよう

```py
img = Image.open(image_path)
plt.imshow(img)
caption = response.json()['description']['captions'][0]['text']
print(caption)
```

皿の上の料理とワイン
![image.png](https://qiita-image-store.s3.amazonaws.com/0/80539/514fa1db-20a8-d8e4-e2cf-58d556d918d3.png)

実は、ワインじゃなくビールなんですが、ワイングラスに入ったビールなので「ワイン」、、いや違う(笑)

## Reference
- [Azure Computer Vision](https://azure.microsoft.com/ja-jp/services/cognitive-services/computer-vision/)
- [API仕様](https://westus.dev.cognitive.microsoft.com/docs/services/5adf991815e1060e6355ad44/operations/56f91f2e778daf14a499e1fa)
Ubuntu 18.04にKnowledge 1.13.1をインストールする

(関連記事)
dockerコンテナを使用せずに1台のマシンで複数のKnowledgeを立ち上げる
https://qiita.com/panda1100/items/e3dfa34b84d961e01b87

# クリーンインストールの場合

``` bash
apt update
apt install -y openjdk-8-jdk #必ずこれが完了してからtomcat8を入れる

apt install -y tomcat8

systemctl stop tomcat8

cd /var/lib/tomcat8/webapps
wget https://github.com/support-project/knowledge/releases/download/v1.13.1/knowledge.war
chown tomcat8:tomcat8 knowledge.war

mkdir -p /var/lib/tomcat8/.knowledge
chown tomcat8:tomcat8 /var/lib/tomcat8/.knowledge

systemctl start tomcat8
```

# トラブルシューティング

## openjdk-8-jdkとtomcat8を同時に入れてしまった場合

openjdk-8-jdkとtomcat8を同時に入れると、
defualt-javaがopenjdk8でないものにリンクされていて正常に動作しない。

update-alternativesやupdate-java-alternativesでopenjdk8を
default-javaに設定しようとしても
`/usr/lib/jvm/default-java`のリンク先を正常に書き換えられなかった。

そこで、あまりお勧めできませんが以下で解決

``` bash
cd /usr/lib/jvm
ln -sf java-8-openjdk-amd64 default-java
```
Azure Pipelines の Android アプリビルドでビルドタイプを指定する

[Azure Pipelines](https://azure.microsoft.com/ja-jp/services/devops/pipelines/) で Android アプリ(Not Xamarin)をビルドする時、普通にテンプレから作った gradle タスクは、 ``gradlew build`` を実行しますが、これはアプリのプロジェクトに含まれる全てのビルドタイプをビルドするため、多くの場合ムダです。[^1]

[^1]: Debug ビルドで単体テストを行い、同時に配布用 Release ビルドを生成したい、というケースでもあるのでしょうか？わからん。

例えば私のプロジェクトの場合、ビルドタイプは標準の「Debug」,「Release」に加え実験用の「Experiment」を用意していたので、タスクの実行に 12分 もかかっていました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/8227/346f0a15-a0c9-f671-9046-d90d3e39ce5a.png)

完了後、Debug, Release, Experiment それぞれの ``.apk`` が生成されていました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/8227/5390eac9-9deb-42b1-8155-a3e0659f25cf.png)

## Release のみをビルドする

特定のビルドタイプのみ（ここでは Release とします）をビルドする場合、``gradlew build`` の代わりに ``gradlew assembleRelease`` を実行すればよいのですが、既定で追加されている gradle タスクではなぜか変更できません。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/8227/91a0b402-1cdc-2628-dfde-67c25b693a65.png)

仕方がないので、既存の gradle タスクは削除して、「＋」 で gradle タスクを検索して追加します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/8227/70053a12-60e8-d632-03af-6bac2faf4d66.png)

こちらの Tasks は変更できるので ``assembleRelease`` を設定します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/8227/13f771df-de9e-f480-21ec-1f8926722de3.png)

これで保存してパイプラインを実行すると、ビルドタスクの時間が 12分 から **8分** に短縮されました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/8227/c59dc0e7-8e5f-6cb6-387a-6872f4de6610.png)

Artifacts にも Release 版の apk しか生成されていないのが確認できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/8227/cbc5cf63-50cf-6eea-88a2-0d0c3f22ecac.png)


[@penguin_sharp さん](https://twitter.com/penguin_sharp/status/1077762715853107201)、ありがとうございました。

## おまけ

上記はビルドAgent 「Hosted VS2017」 で作業してたんですが、これを 「Hosted macOS」 に替えたところ、 8分かかっていたビルド時間が **「2分50秒」** に短縮されました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/8227/05a69245-4fe5-ab16-53de-24fdca7cca13.png)

VS2017 が遅いのか Hosted macOS が早いのか分かりませんが、とりあえず Android アプリのビルドは Hosted macOS を使うとよさそうです。[^2]

[^2]: Xamarin.Android も Hosted macOS でビルドしたいなー、確か Xamarin.iOS しかビルドできないんだよなー
C++ と Haskell と Rustの似てるとこ、違うとこ

関数型言語とオブジェクト指向が相反するものではないことを
感じ始めました。

C++ と Haskell と Rust で似てるところを挙げて
どこが異なっているかを示します。

間違っていたらご指摘お願いします。

# 列挙型
| C++ |Haskell |Rust  |
|---|---|---|
| enum | data | enum |

C++ は値と結び付くけど Haskell, Rustは型と結びつく

Rust    では Derive   を使い規定した振る舞いを付加できる。
振る舞いはトレイトで規定される。

Haskell では Deriving を使い規定した振る舞いを付加できる。
振る舞いは型クラスで規定される。

# 構造体
| C++ |Haskell |Rust  |
|---|---|---|
| struct | data | struct |

Rust    では Derive   を使い規定した振る舞いを付加できる。
振る舞いはトレイトで規定される。

Haskell では Deriving を使い規定した振る舞いを付加できる。
振る舞いは型クラスで規定される。

# クラス
|C++ |Haskell |Rust  |
|---|---|---|
| classes |  |  |

Rust, Haskellではモジュールによりメソッドをモジュール化し、再利用することが可能です。
Rustではenum、構造体によりデータを、implによりメソッドを梱包します。

どちらもカプセル化 (情報隠蔽)が可能です。

継承については以下に詳しく記します。

# 継承
Rust, Haskellにおいて継承はC++通常のオブジェクト指向言語とは
異なるアプローチをします。

Haskell では型クラスを使い型の振る舞いに制約をかけますが、

```Haskell
data Eq a => Ord a where -- こんな感じに
```

Rust もこの考え方に基づき、トレイト境界を使い型の振る舞いに制約をかけます。

```Rust
pub struct Eq<T: Ord> {

}

impl<T> Eq<T>
  where T: Ord {

}

// こんな感じに
```

しかしこのままでは部分片付けを実現することができないので、トレイトオブジェクトを
継承先で宣言します。
パラメータ境界多相性と呼びます。

継承においてRust が従来のオブジェクト指向と異なるアプローチをとったのは
あなたも感じての通りオブジェクト指向の継承は必要以上にクラスを共有してしまい、クラスの
柔軟性をそぐ危険性を孕んでいるなどの理由から現在オブジェクト指向においてあまり
重要視されていないためです。

Haskellにおいては部分型付け実現のためにExistentialQuantification 拡張が必要[^1]
と述べましたがこれによりRustは部分型付けの機能を実現します。

この時コンパイラはダイナミックディスパッチにより単相化を行うため
このコードにおいてインライン化が行えなくなり、最適化ができなくなる
部分が生じます。


また
スーパートレイトを使用してトレイト内で、他のトレイトのメソッドを使用することができます。

また
Haskell では newtype, Rust ではニュータイプパターンを用いることにより、
外部の型クラスに他の外部の型クラスの振る舞いを付加した新しい型をつくること
ができます。ニュータイプもカプセル化を実現できます。

# インターフェース
メソッドに対するデフォルト実装を提供

Haskell, Rust においては
型の振る舞いを規定する
型クラス、トレイト境界と呼ばれる。それらは型に制約をかける。

|C++ |Haskell |Rust  |
|---|---|---|
|純粋仮想関数| classとinstance | traitとimpl |


# おまけ
 オブジェクト指向が
 カプセル化　ポリモーフィズム　ダイナミックバインディング　インヘリタンス
であるというなら
　Haskell, Rustには
全部あります[^1]

だから

関数型プログラミングはオブジェクト指向と相反するものではないのでしょうか、



# 余談
[デザインパターン: 再利用可能なオブジェクト指向ソフトウェアの要素](https://www.amazon.co.jp/dp/4797311126)にはオブジェクト指向は

 > オブジェクト指向プログラムは、オブジェクトで構成される。オブジェクトは、データとその データを処理するプロシージャを梱包している。このプロシージャは、典型的にメソッドまた はオペレーションと呼ばれる。

と定義されるようです(読んでいない)。オブジェクト指向といっても色々な定義があるようです。

# 感想
 関数型言語を学び初めてまだ日が浅くenumをどういう時に使うかいまいちわからないので(具体的な例で言えば[自動微分](https://qiita.com/lotz/items/39c52f08cc9b5d8439ca)とか[パーサ](https://qiita.com/7shi/items/b8c741e78a96ea2c10fe)くらいしか知らない。でもすごく感動した。)

気合いでなんとかしたいです。

# 参考
- [関数型プログラマのためのRust](https://postd.cc/rust-for-functional-programmers/)

- [プログラミング言語 Rust, 2nd Edition](https://doc.rust-jp.rs/)

-  Miran Lipovača(著) 田中 英行, 村主 崇行(翻訳) 
　すごいHaskellたのしく学ぼう (オーム社)

- Graham Hutton (著), 山本 和彦 (翻訳)
  プログラミングHaskell (オーム社)
- エドガー・W・ダイクストラ　
　謙虚なるプログラマ

- [山本和彦 あどけない話　Haskell vs OOP](https://kazu-yamamoto.hatenablog.jp/entry/20080828/1219888005)
 (コメントより追記させていただきました)


[^1]: [コメントより追記] Haskellにおいては部分型付け実現のためにExistentialQuantification 拡張が必要[^2]

[^2]: [山本和彦 あどけない話　Haskell vs OOP ](https://kazu-yamamoto.hatenablog.jp/entry/20080828/1219888005)
100年時代を生き抜く会社に

クラウドインテグレーション事業本部の星名信太郎です。

この記事は「[ネクストスケープ クラウド事業本部のAdvent Calender 2018](https://qiita.com/advent-calendar/2018/ns-cloud)」の25日目（最終日）です。

ネクストスケープ社は元々は動画配信（DRM）を強みとして主にエンターテインメント系のサービスを中心にSI事業を展開していましたが、近年ではAzureを中心としたクラウドサービスをベースとしたシステムインテグレーションを様々な企業様、官公庁等にも提供できるような会社に育ってきています。
　[官公庁案件：農業データ連係基盤WAGRI](https://wagri.net/)
また、SIだけでなく自社プロダクトの開発にも力を入れ始めています。
　[12月13日にサービスを開始したAlterLock](https://alterlock.net/)

このAdvent Calenderは昨年もそうですが、上から強制的にやらせたモノではなく、社員が自発的に世の中に発信したいという意識を持って進めている施策です。
この姿勢こそが非常に大切な事だと思っています。

これからの世の中は、新しいテクノロジーが労働市場を激変させていくことが明らかだと言われています。
その世の中においては常に「自分は何になりたいのか」を思い描き、「そのために自分は何をやるべきなのか」を考えそれを実践していくことが重要です。
これまで重宝されてきたと思われる「言われた事を正確にやる」という仕事はどんどんAIなどの新しいテクノロジーで代替されてしまいます。
指示を待っている姿勢ではダメなんです。

[大学生の息子たちに勧めた本](https://www.amazon.co.jp/LIFE-SHIFT-%E3%83%A9%E3%82%A4%E3%83%95%E3%83%BB%E3%82%B7%E3%83%95%E3%83%88-%E3%83%AA%E3%83%B3%E3%83%80-%E3%82%B0%E3%83%A9%E3%83%83%E3%83%88%E3%83%B3/dp/4492533877)
![LIFESHIFT.jpg](https://qiita-image-store.s3.amazonaws.com/0/323395/1b427216-e62d-e349-f132-b2b56a4dd0bf.jpeg)
ネクストスケープのメンバーはこの100年を生きる世の中になっても、自分がやりたいテクノロジーを常にキャッチアップし続け、弊社の理念にも掲げている「お客様のビジョンに共感し感動を実現する」事をいつまでもやり続けていけると信じていますし、ネクストスケープという会社は100歳まで働くことも出来るような形にこれからしていきたいと思っています。

また、この考えに共感して一緒に働いてくれるメンバーの募集もしています。
[ネクストスケープ採用情報](https://www.nextscape.net/recruit/)

最後になりますが、この企画を推進してくれたメンバーに感謝しつつ、締めたいと思います。
今年も1年間ありがとうございました。
来年もよろしくお願いいたします。
matlab ベクトル化入門

matlab高速化の常套手段「ベクトル化」をまとめてみました。
あくまで入門レベルです。

#ベクトル化とは？
https://jp.mathworks.com/help/matlab/matlab_prog/vectorization.html

簡単に言うと、スカラ値を行列に置き換えることです。
これにより、計算速度を劇的に上げることができます。

# やってみる
簡単なベクトル化。まずは配列で。

```matlab
A = [1:100] ; % 1~100の配列
f = @(x) 2*x + 1 ; % テストのための計算式（関数ハンドルで生成。）
B = f(A') ; % ベクトル化計算（なんとなく列ベクトルのほうがイメージしやすいと思うので、「'」でAを転置。）
```

式で書くと、結果の行列Bはこんな感じで生成されます。

```math
B = 2*
\begin{pmatrix}
1 \\
2 \\
... \\
100
\end{pmatrix}
+1=
\begin{pmatrix}
3 \\
4 \\
... \\
201
\end{pmatrix}
```
要素ごとに計算してくれます。ループで一要素ずつ計算するよりずっと早いです。
（いわゆるGPUの並列処理のような感じなのかな？）
結果も要素ごと、つまりAと同じサイズの配列でBが生成されます。

ちなみに、これをループで書くと、こんな感じ。

```matlab
B = size(size(A)) ;
for i = 1:numel(A)
    B(i) = f(A(i)) ;
end
```

もちろん、配列だけでなく行列もできます。

```matlab
C = randi(10, 5, 5) ; % 1~10の整数のランダムな5x5行列を生成
D = f(C) ;
D ;
```

DはCと同じサイズの行列として生成されます。
なんて素敵なんだ・・・！

# 行列と行列で
行列サイズが同じなら、複数の変数をベクトル化できます。
例えば、ランダムな値の積をとろうとしたとき、

```matlab
E=randi(10,5,5);
F=randi(10,5,5);
G=E.*F;
```
これで、行列EとFの対応する要素の積を一気に計算できます。
この「.\*」とは、要素ごとの積を意味します。「*」だけなら、行列の積です。
（「.\*」を使う際は、EとFの行列サイズが同じであることが前提です）
で、これをループで書くと、

```matlab
G = size(5, 5) ;
for i = 1:5
    for j = 1:5
        G(i, j) = E(i, j)*F(i, j) ;
    end
end
```
長い！
計算時間以前に、コードが長くなりますね。

# ちょっとステップアップ
meshgridを組み合わせてみます。
X, Yの全ての組み合わせを一気に計算したいとき、

```matlab
X = [1:50];
Y = [20:30] ;
[MX, MY] = meshgrid(X, Y) ;
g = @(x, y) x + y ;
M = g(MX, MY) ;
```
これはつまり、
MX: 10x50, MY: 10x50

```math
MX = 
\begin{pmatrix}
1 & 2 & .. & 50\\
1 & 2 & .. & 50\\
... \\
1 & 2 & .. & 50\\
\end{pmatrix}
, MY=
\begin{pmatrix}
20 & 20 & ... & 20\\
21 & 21 & ... & 20\\
... \\
30 & 30 & ... & 30\\
\end{pmatrix}\\
M=
\begin{pmatrix}
1+20 & 2+20 & ... & 50+20\\
1+21 & 1+21 & ... & 50+20\\
... \\
1+30 & 1+30 & ... & 50+30\\
\end{pmatrix}

```

repmatを使ってMXとMYをそれぞれ生成することもできますが、meshgridなら一発で組み合わせ用の行列を用意できます。

# さいごに
ベクトル化の利点は、高速化もさることながら、スカラ値向けの計算式をほぼそのまま使えることです。
式がそのままなので、ロジックを理解する手助けになるのではと感じています。
もちろん、前述の通り、積は「.\*」か「\*」かをはっきりさせる必要はありますが。

では！