wsl2でzshなどのコマンド補間がやたら遅い対策

概要

wsl2を立ち上げると、PATHにホストであるwindowsのPATHが追加されてしまう。
windowsのファイルはすべて実行権限がついているとみなされてしまうため、PATH上のファイルがすべてコマンド補間対象に出てしまう。
なので遅い。

対策

  • PATHをいじる

PATHを無理やりうわがいてしまう。ただ意図しない上書きまでしちゃいそうでいや。 最初はこうしてた。

  • wsl.confを設定する

https://roy-n-roy.github.io/Windows/WSL%EF%BC%86%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A/wslconfig/

こう。

/etc/wsl.conf
[interop]
appendWindowsPath = false

これで追加されない。 この設定後、Powershellを管理者権限で起動して、

PS C:\WINDOWS\system32> Restart-Service LxssManager

を実行してあげる必要がある。実行しないと反映されないので注意。

https://github.com/Microsoft/WSL/issues/1493#issuecomment-580643734

windows側のコマンドを叩きたい場合

reactなんかで npm start を打つとwslからでもchromeをいい感じに立ち上げてくれるんだけど、ここらへんはcmd.exeから呼び出している。
なので、c:\\Windows\System32 にパスが通ってないとnpm startでエラーがでる。
こんなふうに極稀にwindowsのコマンドを実行したいときは、シンボリックリンクを貼っておくと良さそう。

$ sudo ln -s /mnt/c/Windows/System32/cmd.exe /usr/local/bin/cmd.exe

これで無事に動いた。おわり

Redshift Spectrumでparquetを扱う、timestampに苦労した話

概要

  • 元データがtsv, csvなものをpythonを利用してparquetに変換して、spectrumで利用するためにやったこと
    • timestampなカラム周りでかなり苦労したのでせっかくなので書く
    • 結果的にかなり単純にできるんだけど、あまりやり方とかなかったのでせっかくだし書いた

一行でまとめると

  • fastparquetのwrite関数でtimesオプションにint96をつけろ!

いろいろ

tsvをparquetに変換すること自体はかなり容易で、fastparquetやpyarrowを利用することで数行で実現できます。

blog.amedama.jp

などのように単純にできます。このとき、parquetのschemaはpandasのdataframeをもとに設定されていきます。 文字列や数字のカラムだったら基本的にそのまま変換して、そのまま外部テーブルとして読み込ませることが可能なのですが、問題はtimestampなカラムです。
pandasで、 read_csv などで読み込む場合、例えば 2019-03-30 12:30:12 のようなdb上ではtimestampとして扱われるカラムは何もしないと当然文字列として扱われてしまいます。
Redshift spectrumの外部テーブルもschemaを設定し、parquet側もschemaを持ちます。テーブル上ではtimestampで、parquetでは文字列な場合どうなるでしょうか?
答えは、クエリ時にエラーが出ます。

では、timestampのカラムをそのように変換すればよいのではないか?と思ったりします。こんな風に

import pandas as pd
from fastparquet import write

df = pd.read_csv("path/to/csv")
df["created_at"] = pd.to_datetime(df["created_at"])
write("output.parquet", df)

はい、これでparquet上でもtimestampとして出力できます。 実際に、parquet-toolsと呼ばれるparquetファイルのschemaだったりレコードを見れるツールで確認することで、timestampとして認識されていることがわかります。

parquet-mr/parquet-tools at master · apache/parquet-mr · GitHub

しかし、これで変換したとしてもダメなのです。 下記のissueのように、クエリの結果が全く異なったり、そもそもtimestampなデータとして認識してくれなかったりします。

Add ability to output Hive/Impala compatible timestamps · Issue #82 · dask/fastparquet · GitHub

これは推測なのですが、Redshift spectrumはint96なtimestampしか対応しておらず、int64なtimestampは受け付けてないのかなと。(正確には、Redshift spectrumの内部エンジン(prestoなのかimpalaなのかhiveわからない)が)

実際に今回模索していくなかで、hiveより出力したparquetファイルをそのままRedshift spectrumに読ませるとtimestampは正しく解釈され、parquetファイルのtimestampの型はint96となっておりました。

じゃあint96なformatとして出力すればよいわけで、じゃあどうすればいいかというとoptionを指定すればいいだけです。

import pandas as pd
from fastparquet import write

df = pd.read_csv("path/to/csv")
df["created_at"] = pd.to_datetime(df["created_at"])
write("output.parquet", df, times="int96") # timesにint96指定するだけ!

これだけでRedshift spectrumでもちゃんとtimestampを解釈することができます。なんと簡単。 実は上記のissueに答えは最初から書いてあったのですねー、悲しい。

まとめにならないまとめ

わかればとても単純な話ですが、これだけに半日くらい使ったのでその記録として残しておきます。
判明する過程として、hiveを立てたり様々なことをしました、今思うと遠回りしましたがそういうことってよくありますよね。。。辛い。
もっとデータとかコマンド履歴とかちゃんと丁寧に書いたほうがいいと思うのですが、やろうとするとこの記事を上げられないと思うので、もう雑記事なままえいやっです。

怠惰な人が行うダイエット

この記事は VOYAGE GROUP Advent Calendar 2017 - Qiita の17日目の記事です。

頑張って書こう、とAdvent Calendarをやると考えたときは思っていたのも今は昔、あっという間に当日です。

朝だらだらとゴールデンカムイ を読み、Advent Calendar用に仕込もうと思っていた 強化学習の本 を読んでいたら、いつの間にかまさかの担当日。

なにも書かないのはアカンと思ったので、ダイエットについて書こうかなと思い重い腰をあげました。

はじめに

自分の昔と入社2年目あたりの姿を覚えている人は、なんとなくわかると思いますが、とても太りました。 具体的にすると、この3年で35kgくらい太りました。

太ったきっかけは色々あり

  • 大学3年のころにやった肝臓手術
    • ここから体重が増えだした
  • 大学院1年で参加した某インターン
    • 講義中の差し入れがとても美味しい
    • とても良いインターンでした
  • ビールとツマミを毎日買っても経済的に困らない状況
    • つまり就職
  • etc

上記のどれが真の理由かは定かではないものの、数字は嘘をつきません。

2017年5月ごろぼくの目の前にあったのは、大台を突破していた確かな数字でした(まあ実際にはもっと前に突破していましたが。。)。

具体的には言いません。

取り組んだダイエット(失敗)

体重が増え続ける日々、怠惰な私もさすがに対策を行いました。

これまで以下のようなダイエットに取り組んでいました。

  • エアロバイク
    • 毎朝, 10km相当やっていた。
    • だいたい2ヶ月くらい続いた
      • なんか飽きてやめた
  • 夜だけ糖質制限オフ
    • 夜だけサラダ生活
    • 2日でやめた
      • つらすぎた
  • ロードバイク
    • 雑にサイクリング
    • 購入当初は全然乗らなかった
      • いまは隔週くらいで乗っている
  • 昇降ダイエット
    • 2週間くらい続いた
      • 膝を痛めてやめた

他にもいろいろやった記憶がありますが、継続せずにどれも失敗に終わっていました。

ようは摂取カロリー量が消費カロリー量を下回らない限り痩せないですよね(まあわかっててもやれないんですが)。

最後にやったダイエット(成功)

これで痩せられなかったらもうダイエットはやらないと決めていたダイエットを2017年5月ごろからはじめました。 それは糖質制限を行いダイエットするというものでした。

周囲で痩せた人も多くわりと可能性を感じていましたが、生活習慣をガラッと変えるのでちょっとモチベが上がらずやっていませんでした。 が、これが最後と思いやろうと雑に決断、有名なダイエットジム(某ザップ)にも通うことを決め今回は本気度が違いました(結局いろいろな事情でザップには行かなかったが)。

さらにこれまでの継続しなかったという反省を踏まえ、

  • なるべく楽に
  • 一人ではやらない

ことを今回は新しいチャレンジとして取り組みました。 具体的には

  • Withingを利用して、自動で体重を記録
  • 社内slackに自分用のダイエットチャンネルを開設し、そこにwithingで記録した体重を自動でpost
    • ここらへんはいろんな記事がググればでてきます。

です。

1つ目はわかりやすいですね。本当に楽に体重記録できます。めっちゃ楽。

2つ目は、ダイエットチャンネルがあることでいろいろな人が私のダイエットに興味を持ち、現状を知ってくれて叱咤激励をしてくれるようになります。 社内slackに投稿することで痩せた時にドヤりやすくなります。めっちゃドヤってます。ドヤれるから痩せる、痩せたらドヤれる、みたいな最高のループが回ります。

自分みたいな意志力が弱い人は一人でやってもなかなか長続きしないので、いろいろな人を巻き込んで継続しやすくなるので良いと思います(雑)。 どんなダイエットでも継続さえすれば何らかの効果はあると思うので。

まとめ

というわけでようやく成功できたダイエットをドヤる記事でした。

私はこのダイエットで現在22kgのダイエットに成功しました。 目標まではまだ先なので、もうしばらく社内slackには私の体重が投稿され続けると思います。

雑な記事で恐縮でございますが、VOYAGE GROUP Advent Calendarの17日目の記事でした。

怠惰な人のカロリー管理~~~

この記事は VOYAGE GROUP Advent Calenderの22日目の記事となっております。

前置き~~~~~

こんにちは、今年新卒で入社した @takeru0911です。早いもので入社して8カ月も経過しました。

皆様のご指導のたまもので技術力が少しずつ成長しているという実感がありますが、技術力よりも圧倒的に成長したことがあります。

はい、 体重 です。

大学入学時からすると驚きの30kg増、大学院入学時からだとなんと25kg程度太りました。 この圧倒的な成長の傾きは衰えることなく入社してさらに勢いを増しております。

その圧倒的(体重)成長曲線のイメージは下のような感じです。

f:id:tkr911:20161221214444g:plain

(こちら縦軸が体重で、横軸が時間tと思っていただければ)

どちらも圧倒的ですが、入社後の成長具合がよくわかるかと思います。

成長するのはとても良いことですがこのままいくとちょっと良くないことが起きかねないとダイエットを決意したのが入社して一カ月も経たないときでした。

そのあと、ダイエットするためにいろいろなことを行いました。

このうちの 摂取カロリーを記録 、というのが地味なようで自分の体質を把握する意味でもいい感じに効いてくるらしいです(ネット調べ)

でもめんどくさくないですか?

毎回の食事のカロリーをいちいち調べて、なんかに記録して、というのを毎食行うなんてちょっと信じられないですよね。

できる人心の底から尊敬します、僕には無理です(無理でした、一週間くらいでやめました)

でも最近は補助するアプリもあって、これなら私でもいけるのでは・・・!?と使ってみたりしました。

ダメでした

例えば、おにぎり って検索すると、梅にぎり、鮭にぎり、そのほかいっぱいのおにぎり。

あれですよね、選択するのめんどくさいですよね。 これがおにぎり2個とかになると、いくつ食べたかを入力してとかなるわけですよ。

なんにしてもこれを食事のたびに食品ごとに行うのはちょっと辛いですよね。

とは言え最近いろいろな方面の方々に会うたびに

「太った?」 「痩せた方がいい」

と言われるので、痩せるためにカロリー管理をするにはどうしたら良いのか?と本気出して考えてみました。

結果、自分みたいな怠惰マンでもカロリーを管理できるようなものは自分でしか生み出せないと考えて、もう作るしか無いか・・・という結論に至りました。

前置き終わり。

カロリ~~~~~

ここまでの前置きでどんな感じなら、とても怠惰な自分でもカロリーを管理できるか分かってきた気がします。

  • 入力するだけ
  • あいまいでも選択しないでいい
  • 選択肢が複数あってもいい感じにサマる
  • 一つのページで完結する

上の条件をGoogle Spreadsheetで実現することにしました、google application script(gas)便利ですね(ぼくはExcelVBAのほうが書き慣れてて好きです)

あと食品のカロリーはapiで取得します

カロリーapi~~~~~

食品のカロリーの取得には カロリー api でぐぐって上のほうで出てきた↓のものを使用させていただきました。

blog.24th.jp

このapi結構気に入っていて、例えばおにぎりって叩くと、↓みたいにおにぎりで部分一致するものをすべて返してくれます(calがカロリーですね)。

<Result>
  <food>
    <id>77</id>
    <name>おにぎり紀州梅</name>
    <cal>148</cal>
  </food>
  <food>
    <id>102</id>
    <name>おにぎり</name>
    <cal>180</cal>
  </food>
</Result>

怠惰な私は、シーチキンおにぎりを食べようが、鮭おにぎりを食べようが(面倒なので) おにぎり で登録したがります。 なのでこの部分一致で返ってきたものをいい感じにサマれば、どんなおにぎりを食べようがなんとなくそれっぽいカロリーになるはずです(?)

ではapi叩いて、xmlをparseしていい感じにサマるのをgasで書きましょう。

xmlのparseあたりはここらへんを参考にしました。

unguis.cre8or.jp

//apiたたいてカロリーxmlを取得
function fetchCalorieXml(foodName){
  var feedURL = "http://24th.jp/test/api_cal.php?submit=on&name=" + foodName;
  var response = UrlFetchApp.fetch(feedURL);
  return response.getContentText();
}

//取得したxmlをparseしてカロリー取得
//該当する食品があったら良い感じにカロリーをさまる
function parseCalorieXml(contentText){
  var xml = XmlService.parse(contentText);
  var items = xml.getRootElement().getChildren('food'); 
  var sumCal = 0;

  if(items.length == 0){
    return 0;
  }

  for(var i = 0; i < items.length; i++) {
    var cal = Number(items[i].getChild("cal").getText());
    sumCal = cal + sumCal
  }
  //いい感じにサマる
  return sumCal / items.length;
}

fetchClorieXmlapiを叩いて取得されたxmlparseCalorieXml に渡すだけです。

サマる箇所はもし複数ヒットしたら平均をとって返すとかいうなんの捻りもない内容になってます。

User Defined Calorie(UDC)

このapiのおかげで基本的な食事はカバーできます。

しかしよく食べるけど一般的ではないなにか(会社で売られる弁当とか)とか、大量の飲み物や食べ物を食べる会(飲み会)の場合はちょっとapiだけだと辛いですね。

なのでユーザーが独自のカロリーを登録できるようにしました。

はい、いわゆる User Defined Calorie(UDC)機能の実装です。

本当に何の捻りもない実装です。 下の画像みたいにUDC sheetに食べ物の名前と、カロリー数を書いてその値を取得するだけです。

f:id:tkr911:20161221223314p:plain

将軍ってのは会社に来る弁当屋さんの名前で、カロリー数は適当です。 飲み会は飲み会ですね、夜飲み会があるとこれを入力すれば面倒なことなしです、素晴らしい!!(このくらい割り切らないと絶対続かないので)

これを普通にgasで実装ですね。

なんも捻りもないのでコードは載せないです。

食べた数をわけるのめんどい!!

朝ごはんに私はおにぎりを2つ食べてカフェラテを飲むのですが、それぞれの食べた個数を↓みたいに複数のセルに書いていくのは無理ですね。

食べたもの 個数
おにぎり 2
カフェラテ 1

一つのセルにこんな感じで入力したいですよね

おにぎり*2,カフェラテ

この入力でいい感じにカロリー計算してくれたら、毎朝全く同じメニューの私は補完が効いて朝ごはんの登録は を入力するだけでとても楽になります。

というわけでこれもgasでできるように実装しましょう。 普通に , でsplitして、splitされた文字列を * でsplitするだけです。

//複数食品があったら、なんか分解する
//カレー*2とかあったら個数もなんかやる
function parseInputFood(inputText){
  var splitText = inputText.split(",")
  var foods = [];
  for(var i = 0; i < Number(splitText.length); i++){
    var cnt = 1;

    var text = splitText[i];
    //なんこか食べたら
    var splitAsta = text.split("*");
    if(splitAsta.length > 1){
      cnt = splitAsta[1];
    }
   
    var foodName = splitAsta[0];

    foods.push(
      {
        name: foodName,
        cnt: cnt
      }
    );
  }
  return foods;
}

普通ですー。

なんやかんやで↓みたいな感じにわりと楽な感じにカロリーを計算できるようになりました。

f:id:tkr911:20161222092332g:plain

ちなみにapiにもUDCにもない食品は、UDCに登録してね☆って言われます。

まとめ

いろいろバグというか、実装が足りない部分もありますがこれくらいで十分かなと思います。 ほとんど書いたことないので読みにくかったり、もっときれいに書けるやんってところが多々あると思いますがご容赦を。

でもなんだか自分でこういうのを作ると、長続きするような気がします。 ダイエットでカロリー管理が続かなかった方がもしいれば自分で作ってみるのも良いかもしれないですね

ちなみに書いたコードはgistにあげておきました。 スクリプトエディタでこれをぺって貼り付けて、プロジェクトトリガーでシートの編集時に動くように登録すれば動くかと思います。

カロリー計算するマン · GitHub

それでは来年ではダイエット成功の報告ができると信じてさようなら~!

次の VOYAGE GROUP Advent Calendar の記事をお楽しみに~~~~~

KotlinでVue.jsを動かしてみた

この記事はVOYAGE GROUP Advent Calendar 2015の12日目となります。

こんにちは,VOYAGE GROUPの16卒内定者の@takeru0911です.内定者でだれかAdventなCalendar書かないか?と聞かれたのでチャレンジしてみました.

最近私が結構触っているKotlinについて少し書いてみようかなと思って書いてみます. 当初は巡回サンタさん問題を蟻コロニー最適化で解こうかな,と思ってました(解いてみて記事も書き終わってました)が当日になってこっちの方が良いのでは(?)と謎の発想により書いてみました.

今回のコードなんかはこちらです.

github.com

Kotlinについて

JetBrain社が開発しているJVM言語です. 静的型付け言語とか型安全とかNull安全とかAndroid開発が捗るとか特徴あります. 他にもいろいろ語るべきことはあるかと思いますがKotlin Advent Calendarがあるのでそちらをぜひお読み下さい.

ちなみにちょっと試したい,触ってみたいといった場合はWeb上で動かすことも可能(Try Online)となっております.

KotlinでJS

KotlinはJavaScriptコンパイルするコンパイラーを搭載しております. Androidに関して,Kotlin今すごく盛り上がっていますが,AltJSとしてのKotlinの記事はあまり見かけないし,せっかくなので遊びがてら少し触れてみようと思います. 仕組みとかは公式のドキュメント見るか日本語だと少し古いですが

yyyank.blogspot.jp

上記の記事が参考になります.

Hello World

はじめにHello Worldをさせてみます. 下のコードがconsole.log('hello world')を実行するコードです.

fun main(args: Array<String>){
    console.log("hello world")
}

このコードをコンパイルするとこんなjsのコードに生まれ変わります.

(function (Kotlin) {
  'use strict';
  var _ = Kotlin.defineRootPackage(null, /** @lends _ */ {
    main_kand9s$: function (args) {
      console.log('hello world');
    }
  });
  Kotlin.defineModule('hello', _);
  _.main_kand9s$([]);
}(Kotlin));

mainmain_kand9s$という名前の関数に変換されていることがわかりますね.Kotlinというオブジェクトに対して関数をつけていくような感じで動いていきます(多分).

Vue.jsを動かす

ここからが本題です. hello worldできたんでじゃあなんかのライブラリを動かしてみるかと思い,インターン*1で使ったVue.jsを動かしてみようと思いました.(Vue.jsについてもはしょります)

目標としては単純ですが,テキストボックスに入力した文字列がリアルタイムにどこかしらの要素に反映されるような単純なアプリを目指します.

KotlinでJSのライブラリを使う際は一部を除いて*2,そのライブラリのインターフェースの定義が必要となります. ここら辺はこの記事を参考にさせていただきました.

arata.hatenadiary.com

scala-js-ts-importerという便利なツールがあるらしい,ならkotlin-js-ts-importerもあるやろ!と思ってぐぐったところ

_人人人人人人_

>ないです!!<

 ̄^Y^Y^Y^Y^Y ̄

自分が探した限りありませんでした.悲しい(もしご存知の方がおられましたら教えていただけると,とてもとても嬉しいです). ないものは仕方ないので上の記事や下のリポジトリを参考にTypeScript → Scala → Kotlinとなるようにインターフェースを手作業で変換することにしました.

github.com

github.com

正直わりと似ていたりしたのでそんなに苦労はしませんでした.

Scala Kotlin
js.native noImpl
@JSName("") @native("")

上の表に対応するような形でそれぞれ書き換えたくらいだった気がします.(細かいところは他にもちょいちょいありましたが・・・)

実際に作ったkotlinコードです.

import vue.Vue

@native("window")
val w: dynamic = noImpl

fun main(args: Array<String>) {
  Vue.config.delimiters = arrayOf("{!", "!}")

  val option = json(
          Pair("el", "#app"),
          Pair("data",
                  json(
                          Pair("text", "")
                  )
          ),
          Pair("methods",
                  json(
                          Pair("clickedResetBtn", {
                            w.app.`$data`.text = ""
                          })

                  ))
  )
  w.app = Vue(option)
}

Pairはキーバリュなオブジェクトで,これを用いてjsのオブジェクトを作ります. 変数wにjsのnativeなオブジェクトwindowを割り当てたりしています.

実行結果は以下の様な感じです. f:id:tkr911:20151212102622g:plain

ちゃんとテキストに入力したのがリアルタイムに反映されているかと思います.

まとめ

あまり情報が多くなく(数というより種類),なかなか苦労しましたがなんとか動かせました. 自分もいつもはKotlinでAndroidを書いていますが,たまにはこうしてaltJSとして書くのも面白いので時々は書いて,情報をしっかり追っていければなと思います.

明日は@TachibanaKaoruさんです!お楽しみに!

*1:VOUYAGE GROUPインターンTreasure

*2:jQueryは使用可能

Javaの常識を変えるらしいPlay Framework~チュートリアルの4~

! この記事はJavaの常識を変えるらしいPlay Framework~チュートリアルの3~のつづきです。

公式ページのチュートリアル的には次は別なんだけど、せっかくだからGETとかのリクエストパラメータの取得をやる。

リクエストパラメータの取得

Play FrameworkのController側で、テキストボックスからGETリクエストされたパラメータの値を取得して表示してみる。 - 感謝のプログラミング 10000時間 を参考にしてやってみよう。

routesファイルの修正は必要なくてcontrollerを変えればいいみたいなので前の記事で作った/show/:idを/show?pageみたいな感じにしてみます

    public static Result show() {
        String page = Form.form().bindFromRequest().get("page");

        return ok(index.render(page));
    }

Form.form().bindFromRequest().get("page");これですねー、このメソッドで"page"を取得するみたい。 じゃあpostのときはと言いますと同じようにしていいみたい。個人的には区別していて欲しかった。