Pippi Life

主に仕事に関連するITのことや、プライベートもちょいちょい書きます。

座標上の四角形の中に、点が入っているかを調べたい

はじめに

点(a,b,c,d)をもつ四角形の中に点eが入っているか、を出すためにベクトルの外積を使用します。 numpyって本当に便利ですね。

考え方

  1. まず、原点から点(a,b,e)へのベクトルA,B,Eを作成。
  2. 点aからbへのベクトルAB、点aからeへのベクトルAEを計算。
  3. ベクトルAB、ベクトルAEの外積を計算
  4. b->c,c->d,d->aに対しても2,3を実施する。
  5. a->b, b->c, c->d, d->a のすべてで外積がマイナスであれば、 点は確変の左側にあるといえる ->四角形の中にある

image.png

実装

以下が実装。

def in_rect(rect,target):
    a = (rect[0][0], rect[0][1])
    b = (rect[1][0], rect[1][1])
    c = (rect[2][0], rect[2][1])
    d = (rect[3][0], rect[3][1])
    e = (target[0], target[1])

    # 原点から点へのベクトルを求める
    vector_a = numpy.array(a)
    vector_b = numpy.array(b)
    vector_c = numpy.array(c)
    vector_d = numpy.array(d)
    vector_e = numpy.array(e)

    # 点から点へのベクトルを求める
    vector_ab = vector_b - vector_a
    vector_ae = vector_e - vector_a
    vector_bc = vector_c - vector_b
    vector_be = vector_e - vector_b
    vector_cd = vector_d - vector_c
    vector_ce = vector_e - vector_c
    vector_da = vector_a - vector_d
    vector_de = vector_e - vector_d

    # 外積を求める
    vector_cross_ab_ae = numpy.cross(vector_ab, vector_ae)
    vector_cross_bc_be = numpy.cross(vector_bc, vector_be)
    vector_cross_cd_ce = numpy.cross(vector_cd, vector_ce)
    vector_cross_da_de = numpy.cross(vector_da, vector_de)

    return vector_cross_ab_ae < 0 and vector_cross_bc_be < 0 and vector_cross_cd_ce < 0 and vector_cross_da_de < 0

if __name__ == '__main__':
    rect = [[48, 43],[45, 42],[43, 38],[45, 39]]
    print(in_rect(rect, [44,45]))
    # -> False
    print(in_rect(rect, [46,41]))
    # -> True

参考

http://www.endo-yuta.com/2011/09/blog-post_06.html

Qiitaにも投稿しています。

古いMacでもAirDropを使えるようにする方法

私のiMacは2010年モデルなので、AirDropに対応していません。 2012年以降に発売されたものから対応しているらしい。

ですが、AirDropってふとしたときに便利ですよね 使いたかったので調べたところ、コマンドがあったので、メモしておきます。

$ defaults write com.apple.NetworkBrowser BrowseAllInterfaces -bool TRUE; killall Finder
 ```

もとに戻すには以下のコマンドです。

$ defaults write com.apple.NetworkBrowser BrowseAllInterfaces -bool False; killall Finder ```

参考 https://lifehacker.com/enable-airdrop-on-older-unsupported-macs-1556180698

Qiitaはこちら。

golangで配列を、分散してマージしたい

タイトルのとおり、なのですが、 コードを書いていて、以下みたいなマージをしたかったので、メモしておきます。

func main() {
    s1 := []int{1, 2, 3, 4, 5}
    s2 := []int{7, 8,9,10}
    s3 := MergeSlice.Mix(s1, s2)
    fmt.Println(s3)
}

// ->  [1 7 2 8 3 9 4 10 5]

みたいな感じです。 なんでこれをやりたかったかというと、 2つの配列に入った処理を一定時間に按分して処理させたくて、 かつ、同じタイミングでそれぞれの処理が実行されたくなかったからです。

例えばgoroutineでそれぞれを並列実行すると 配列の数が同じだった場合は、実行タイミングが近くなりすぎてしまいました。

ライブラリがなかったので、作成しました。

func Mix(slice1 []int, slice2 []int) []int {
    var resp []int
    // ゼロチェック、どちらかが0なら、もう一つが返却される
    if len(slice1) == 0 {
        return slice2
    } else if len(slice2) == 0 {
        return slice1
    }

    long, short, step := checkSlice(slice1, slice2)
    
    // 返却されるスライスは2つの合計値の値を持つ
    goal := len(long)+len(short)
    for i := 1; i <= goal; i++ {
        if i%(step+1) == 0 {
            if len(short) != 0 {
                resp = append(resp, short[0])
                short = short[1:]
            } else {
                resp = append(resp, long[0])
                long = long[1:]
            }
        } else {
            resp = append(resp, long[0])
            long = long[1:]
        }
    }
    return resp
}
func checkSlice(s1 []int, s2 []int) ([]int, []int, int) {
    // 大きい方の配列を判定し、大きい配列、小さい配列、小さい配列の間隔を返します。
    if len(s1) > len(s2) {
        return s1, s2, int(len(s1) / len(s2))
    } else {
        return s2, s1, int(len(s2) / len(s1))
    }
}

GitHubにもアップしています。 Qiitaはこちら

APIのテスト書いたので覚書

はじめに

最近サーバーレスを良くやっているので、 APIのテストを書きたくて、いいフレームワークを探していました。 とりあえず動くところまで行けたので、覚書しておきます。

環境

やりたいこと

  • 学習コストが少なくAPIテストをテストを書きたい
  • メンテナンスしやすいこと
  • レスポンスの値を、後続のテストケースで使いたい。

Frisby + Jest

さがしていて出会ったのが、Frisby + Jestという構成 frisbyはAPIテストのフレームワーク、Jestが実行環境みたいです。

https://github.com/vlucas/frisby

シンプルに書ける

const frisby = require('frisby');

it('should be a teapot', function (done) {
  frisby.get('http://httpbin.org/status/418')
    .expect('status', 418)
    .done(done);
});

ネストした処理も記述できる

const frisby = require('frisby');
const Joi = frisby.Joi; // Joiは便利らしい

describe('Posts', function () {
  it('should return all posts and first post should have comments', function (done) {
    frisby.get('http://jsonplaceholder.typicode.com/posts')
      .expect('status', 200)
      .expect('jsonTypes', '*', {
        userId: Joi.number(),
        id: Joi.number(),
        title: Joi.string(),
        body: Joi.string()
      })
      .then(function (res) { // res = FrisbyResponse object
        let postId = res.json[0].id;

        // これでやりたかったこともできる
        return frisby.get('http://jsonplaceholder.typicode.com/posts/' + postId + '/comments')
          .expect('status', 200)
          .expect('json', '*', {
            postId: postId
          })
          .expect('jsonTypes', '*', {
            postId: Joi.number(),
            id: Joi.number(),
            name: Joi.string(),
            email: Joi.string().email(),
            body: Joi.string()
          });
      })
      .done(done);
  });
});

ビルトインのアサーションも豊富

  • status
  • header
  • json
  • jsonStrict
  • jsonTypes
  • jsonTypesStrict
  • bodyContains

他にも拡張ハンドラが作成できる、とかJasmine Matcherを直接アサーションに記述できるとか。 使ってませんが。

環境構築

インストール

環境構築や使い方はこちらを参考にさせてもらいました。

$ npm install frisby --save-dev
$ npm install jest --save-dev

package.json

npm run apitestで実行できるように、package.jsonも修正しておきましょう。

:
:
  },
  "devDependencies": {
    "frisby": "^2.0.14",
    "jest": "^22.4.3",
  },
  "scripts": {
    "apitest": "jest"
  }
:

テスト書いてみる

Jestは、__test__フォルダ配下か、 .spec.js もしくは .test.js のファイル名をフィルタして、 テスト実行してくれるみたいです。

const frisby = require('frisby');
const Joi = frisby.Joi;

var target_host = 'https://hostname';
var arg1 = 'sample';
var arg2 = '1234567890';

var arg3 = "";
var arg4 = "";

it('__正常系__JSONアサーション', function (done) {
    frisby.post(target_host + '/api1',
        {
            "req_body1": arg1,
            "req_body2": arg2
        }
    )
        // ステータスコードのアサーション
        .expect('status', 200)
        // jsonのアサーションはこう書く
        .expect('jsonTypes', '', {
            'res_body1': Joi.string().required(),
            'res_body2': Joi.string().required()
        })
        .then(function (res) {
            // arg3,4は後続のテストでも使用できる。
            arg3 = res.json.res_body1;
            arg4 = res.json.res_body2;
            // コンソールにログを出力もできる
            console.log(arg3);
            console.log(arg4);
        })
        .done(done);
});


it('__正常系__JSONのリストアサーション', function (done) {
    frisby.setup({
        request: {
            //例えばレスポンスの値を、ヘッダーに追加してリクエストしたいとき
            headers: {
                'Authorization': arg3
            }
        }
    })
        .get(target_host + '/api2?req_body1=' + arg4)
        .expect('status', 200)
        // listのアサーション
        .expect('jsonTypes', '', {
            'res_body3': Joi.array()
        })
        .then(function (res) {
            // リストの中身のアサーション
            expect(res.json.res_body3[0].aaa).toBe("bbb");
        })
        .done(done);
});

expectの中身はまだまだ勉強が必要です。 ネット上の情報を見る限り、決め打ちのjsonアサーションもできる気がします。 これでPythonで書いたサーバーレスAPIPythonでut,it、NodeでAPItestとある程度テストをかけて大変うれしい次第です。 サーバーレスアーキテクチャって微妙にデバッグしにくいのは自分だけでしょうか? APIのテスト、みんなどう書いてるんでしょ?

qiitaにもあります。

react-native環境の構築

やらないといけなさそうなので、 勉強はじめました。 まずは環境セットアップから。

前提

node,npmのインストール

以下のコマンドでインストールします

$ brew install node
$ brew install npm

watchmanのインストール

Facebookが作ったファイルシステムの監視ツールらしく React-nativeでは必須なんだそうです。 以下のコマンドでインストールします

$ brew install watchman

react-nativeのインストール

npmでインストールします。

$ npm isntall -g react-native-cli

Hello worldの実行

さっそくreact-nativeでhello worldしてみます。 特定のディレクトリに移動して、初期化してみます。

$ react-native init hello_world

いろいろと関連モジュールのダウンロードのため、 ちょっと時間がかかるかもしれません。 自分の環境では、npmがsudoじゃないと動かなかったのですが、きっと昔にsudoでインストールしていたのかもしれません。。。切ない。

:
:
:
To run your app on iOS:
   cd /Users/user_name/hello_world
   react-native run-ios
   - or -
   Open ios/hello_world.xcodeproj in Xcode
   Hit the Run button
To run your app on Android:
   cd /Users/user_name/hello_world
   Have an Android emulator running (quickest way to get started), or a device connected
   react-native run-android

iOS上で実行したかったら、 react-native run-iosを実行しろと言っているので実行してみましょう。

$ cd hello_world
$ react-native run-ios

動きました!! image.png

こちらでも同じ記事を置いています。

Magic Keyboard USから、FILCO Majestouch2 Tenkeyless Sに乗り換えました

件名の通りなのですが、乗り換えました。 かんたんな開封の義と、 配列ちょっと気になったりしたので、そのエントリーになります。

そもそもなぜUSなのか。

Apple 信者の後輩がいるのですが、 「USがマジでいいっす。JIS配列とかくそっす」 と言っていたので、転職を機に乗り換えてやったわけです。 ※転職エントリーは1ヶ月くらいたったら、新旧比較もかねて書いてみようと思います。

US配列で2ヶ月経って

ということで、後輩のいらなくなった、Magic Keyboard USを焼肉を担保に譲り受けたわけですが、 早くもJIS配列に戻りたくなってきています 。 でも修行だと思って頑張ります。 キーボードってある程度からは、慣れですよね、慣れ。 最近の悩みは、 エンターを押すときに間違って、「¥」を推しがちなんですよね。 JIS配列のキーボードって、エンターキーが大きくなっています。 日本語をPCで入力する場合、ローマ字入力だと、

一文を書くのに、子音を入力→母音を入力→スペースで変換→エンターキーで確定

というのをひたすら繰り返してきていきます。 半角言語よりも多くエンターキーを使用するんですよね。よく考えられています。 で、小さくなったエンターキーの場所には「¥/|」が鎮座しているのです。 自分はもともと、「エンターの上より」を打鍵しがちだったみたいです。

なぜMajestouchに乗り換えるのか

Magic Keyboardって、めっちゃ薄いんですよね。薄い。ひたすらに薄い。 けど、長時間タイピングしていると結構しんどくなってくるのです。 ちょっと前に売ってた、電池式のはもうちょっと厚みがあって、打ちやすかった気がします。

ということで、Majestouch2を購入しました。

f:id:yutako0217:20180317230815j:plain
なんか「開封の儀」みたい

あけるとこんな感じです。 f:id:yutako0217:20180317230805j:plain

ここで、Magic Keyboardとの比較の写真です。 大きい。 Macで市販のキーボードを使う場合、 US配列であっても、キー配列が異なります。 ALt(Option)キーのところにWindows CommandキーのAlt 左にあるFnキーがなく、それに相当するのが右のアプリケーションキーになります。 f:id:yutako0217:20180317230754j:plain

分厚い f:id:yutako0217:20180317230826j:plain

キー配列の変更

キー配列の変更は有名なKarabinerを使用します。

こちらからDL^インストールしてください。 Karabiner - Software for macOS

そして、以下のように変更します。 f:id:yutako0217:20180318075756p:plain これで ALt(Option)キーのところにWindows CommandキーのAlt 左にあるFnキーのかわりに右のアプリケーションキーを使用することができます。

メカニカルはキートップが取り外せるので、 WindowsとAltの位置を入れ替えて終了です。 Majestouch2には、キートップ取り外し用の工具はついていないので、注意してください。

自分のキーボードのキーがどうPCに認識されるかは、 Karabiner-EventViewerを使ってください。 押下したボタンが表示されるようになります。 f:id:yutako0217:20180318080337p:plain

ちなみに Majestouch2のPrintScreenキーはF13に該当するみたいなのですが、 EventViewerでは認識してくれませんでした。 自分はBTTを使っていて、こちらが反応してくれたので F13なんだと知ることができました。

「分報」を3つの職場で適用してみた結果

分報というものがあります。 最近だと結構適用しているところも多いのかもしれません。 分報についての詳細は、「分報」でググればたくさん出てきますので、そちらを参照してください。

SIer企業なのでプロジェクトもちょいちょい変わります。 その都度適用してみたのですが、メリットデメリットが見えてきたので、 共有したいと思います。

適用した現場とツール。勤務形態

はこんな感じです。

・1.部内(小チーム)  人数:人数5人
 ツール:googleハングアウト
 勤務形態:全員が比較的近い机にすわり勤務している
      新しい案件開拓や自社持ち帰りインフラ案件などを行っている

・2.部内
 人数:人数15人くらい
 ツール:googleハングアウト
 勤務形態:ライン長以外は現場に出ており、勉強会以外では基本顔を合わさない     

・3.プロジェクト
 人数:人数5~8人くらい
 ツール:slack
 勤務形態:アジャイルでのJava開発を行っている。
      全員が近い机に座っている

それぞれ、順番に起きたこと、良かったこと、メリット・デメリットを紹介していきます。 また2,3は同時並行で利用していました。

1.部内(小チーム)

導入のキッカケ:

分報を取り入れるまではメールや、1:1のチャットしか利用していませんでした。
業務にあたっていて、自分とAさんがやりとしていた情報や、参考リンクが共有できてなくて Bさんが同じところでハマる。みたいなことが結構起きていたんですね。
最初は共通のグループチャットだったんですが、 そのうちマネージャが分報というものを見つけて来たので、そのまま導入となりました。

導入の結果

チームも小さかったし、管理職との距離も近かったので
結構上手く回りました。情報の共有もスムーズになり、技術に対しての議論も行われるようになりました。

なので

メリット

 情報共有のリアルタイム化  個人の興味が共有され、コミュニケーションが活発になった

デメリット

 gmailの検索に引っかかるから、検索時に「 -in:chats」入れる必要があるくらい?

だったかなと思います。

・2.部内

導入のキッカケ:

1のチームが他部署に吸収された感じでした。 「まぁ前回上手く回ったので、今回もやってみましょう。こんなメリットがありました。」と、 部会で発表し一部のメンバーに導入。
全員が全員現場でインターネット使えると限らないのが残念ですね。

導入の結果

最初は結構スムーズにまわっていたような気がします。 1で得られた効果も出てたし、月1でしか顔を合わさない人たちが 何をしているのか、は見えるようになったと思います。 だから嵌りそうなときのヘルプとかは本当に順調に回っていました。

が 途中から雲行きが怪しくなってきてしまいました。 分報をとりいれた一部のメンバーが、分報で毒を吐くんですね。 まぁ会社、上司に対する不満とか。負の感情って伝染するもので、それに同調するメンバーがいたり、 結構取扱にこまる発言が増えてきてしまいました。 結果、「意識高い系の愚痴り部屋」というか、「文句は言うけど何もアクションしない人の吹き溜まり」みたいなことに。 あとは「弄り」ですね。顔が見えないから、結構弄るけど、限度がわからない人もいて、 いじられてた人が「俺もう分報やめるわ」みたいな結果に。 チャットだけで怒らない、叱らない、とか負の感情はクローズドなメンバーでやりましょうっていう周知がもっと必要だったのかもしれない。

なので

メリット

 情報共有のリアルタイム化  個人の興味が共有され、コミュニケーションが活発になった

デメリット

 負の感情のコントロールが難しい。

・3.プロジェクト

導入のキッカケ:

私のプロジェクトでも提案して導入してみました。 今回はSlack。ああ素敵、Slack。

導入の結果

コーディングが多いプロジェクトだったのもあり、 すごくフィットしました。 コミュニケーションの活発化だけでなく、疑問解決も早くなりました。
一部、頻度が少ない人がいるものの、それが分報のいいところでもある、くらいのレベルです。

メリット

 情報共有のリアルタイム化  個人の興味が共有され、コミュニケーションが活発になった  同じところでハマる、を回避

デメリット

 とくに感じなかった。

環境が良かったのもあるかもしれません。 多少の愚痴も、許容範囲内だった気がします。

職場の士気が低いところで実践すると、逆効果もあるかもしれません! 改善案はいいけど、不満・愚痴はクローズドなところでしましょう、くらいのルールはあってもいいかもしれませんね。