Cygwin + Anaconda + conda env

Windows (not cygwin)にインストールしたAnaconda (4.1.1)をCygwinzshでやろうとすると、初めいい感じにconda envが使えなかったのでメモ。もしかしたらAnacondaのバージョン上げたり、Cygwin上にAnacondaインストールすると動くかもしれない。

コマンドプロンプトとかPowerShell使えよ

コマンドプロンプトは動作キモいし、PowerShellはlsが常に-lオプションと同じ結果がでるのが嫌。

めんどいことをしたくないとき

cmderをインストールして、activate 環境名するとそのまま使える。mintty上では挙動が怪しいインタプリタも普通に使える。

なんとかできた方法

Cygwinbash.exeでsource activate 環境名とすると、何も出力がないし、環境も切り替わらない。zsh.exeでやると以下のエラーがでる。

Traceback (most recent call last):
  File "D:\Anaconda\Scripts\conda-script.py", line 5, in <module>
    sys.exit(main())
  File "D:\Anaconda\lib\site-packages\conda\cli\main.py", line 48, in main
    activate.main()
  File "D:\Anaconda\lib\site-packages\conda\cli\activate.py", line 105, in main
    shelldict = shells[shell]
KeyError: 'zsh.exe'

とりあえず、D:\Anaconda\Lib\site-packages\conda\cli\activate.pyにあるactivate.pyのエラー箇所をみると、conda.utilsパッケージのshellsにzsh.exeがないからエラーがでてるらしい。

そもそもの話、D:\Anaconda\Scripts\activateのファイルで、conda ..activateが実行されてるだけなので、そこをゴニョゴニョしてもいいかも知れない。 私はutils.pyのif sys.platform == "win32":以下のshellsに直接、

"zsh.exe": dict(
    unix_shell_base,
    exe="zsh.exe",
    binpath="/Scripts",
    path_form=cygwin_path_to_win,
    path_to=win_path_to_cygwin
),

を追加した。zsh.exeのプロンプトに環境名がでないけど、一応Pythonの実行ファイルは切り替わった。

感想

普通にcmder + bashで良いと思う。

追記(公開2分後)

pip切り替わってなかった。

Electron + TypeScriptメモ

前回の記事にも書いたけど,最近TypeScriptを触ってる.ついでにElectronも触ってる. browserifyでbundleしたら動かなくて詰まったので,備忘録として再度メモ.

やりたかったこと

  1. browserifyを使ってts -> js -> bundle
  2. renderer process上でbundleしたものを読み込む
  3. renderer process上でfsなどnodeモジュールを使う

つまったとこ

3の部分でfsなどがundefinedになる.

原因

イマイチよくわかってない.

qiita.com

こちらの記事によると(CoffeeScriptをつかっているけど)

fs とかの node.js ビルトインモジュールを electron 側で require できます

らしい.

qiita.com

こちらの記事では,BrowserProcess側もbrowserifyしちゃうとだめとは書いてあるけど,今回はRenderer側しかbrowserifyしてないので,あまり関係なさそう?

実際にwebpackで生成されたコードをみると,

(function(module, exports) {
module.exports = require("fs");
}),
/* 中略 */
const fs = __webpack_require__(0);

のようになっていて,webpack_requireなるファイル先頭に定義された関数でモジュールを読み込んでるっぽい.

まだJavascriptのモジュール周りとかの挙動がわからないまま書いてるから,結局みてもよくわからんかった.Renderer側でも使えるようにElectronがexportsしてくれるけど,browserifyが全部必要なモジュールをまとめてて,名前空間(この呼び方が正しいかもわからない)が別になってるからかなーと思ってる.なので,@typesのnodeモジュールだけじゃなくて,Electron自体のコードを含んだパッケージも追加してあげると動くような気がする.

Webpack

Webpackだとwebpack.config.jsでtargetパラメータにelectronを指定できるのでよしなにやってくれる.

そもそもトレンド的にもwebpack使っといたほうが良さそう.

f:id:Inaab:20170311000543p:plain

Typescript,Gulp,browserify(それとRiot.js)あたりのメモ

最近ElectronアプリでTypescriptを使おうとして詰まったので備忘録. リニューアルしたありたそ画展のJavascriptは既に生まれたときから負債確定だったので,こちらもTypescriptにして書き直す予定.

それはお前の書き方が悪いからだ!とか,なんでTypescript?CoffeeScriptのほうよくない?とか言われそうだけど,なんとなくPythonの型アノテーションっぽくてTSのほうがすき.某やでなんとかには,ミーハー云々言われたけど気にしないでいきます.

tsconfig.json

基本的には,compilerOptionsを書いとくだけ.

{
    "compilerOptions": {
        "target": "es6",
        "module": "commonjs",
        "allowJs": true
    }
}

ES6のPromiseとかそこら辺を使いたいのでtargetはes6を指定する.Riot.jsを使うのでallowJsも指定する.

gulpfile.js

var gulp = require('gulp');
var ts = require('gulp-typescript');
var browserify = require('browserify');
var browserifyShim = require('browserify-shim');
var source = require('vinyl-source-stream');

var riot = require('gulp-riot');
var riotify = require('riotify')

gulp.task('compile:ts', function() {
    var tsconfig = require('./src/ts/tsconfig.json');
    return gulp.src(['./src/ts/*.ts'])
        .pipe(ts(tsconfig.compilerOptions))
        .pipe(gulp.dest('./src/js/'));
});

gulp.task('merge:js', function() {
    return browserify({
        entries: './src/js/app.js'
    })
    .external(['firebase'])
    .bundle()
    .pipe(source('app.js'))
    .pipe(gulp.dest('./js/'));
});

gulp.task('compile:tag', function() {
    gulp.src('./src/tag/*.tag')
        .pipe(riot({
            type: 'typescript',
        }))
        .pipe(gulp.dest('./src/js/'));
});

gulp.task('merge:tag', function() {
    return browserify({
        entries: [
            './src/tag/gallery.tag',
            './src/tag/topbar.tag'
        ]
    }).transform([riotify])
    .bundle()
    .pipe(source('tags.js'))
    .pipe(gulp.dest('./js/'));
});

gulp.task('default', ['compile:ts', 'merge:js']);

browserify-shimを併用して,HTML内で<script src="http://hoge.js">なんてやったものをインポートしようとした時に,tsifyで一気にやろうとしたらいい感じにやってくれなかったので,コンパイルとマージのタスクを分けた.(ここでつまってだいぶ時間がかかった.)

もしかしたらpipeとかつないでやるとできるかもしれないけど,これで別段不便を感じてないからいいかな.

package.json

brwoserify-shimを利用するための設定を記述する.

{
  "browserify": {
    "transform": [
      "browserify-shim"
    ]
  },
  "browserify-shim": {
    "riot": "global:riot",
    "lightgallery.js": "global:lightGallery",
  }
}

先述した,CDNからロードしてglobalに展開されたものをインポートできるようにする.そのため,globalで展開されている値を適切に指定しないとだめっぽい(?).左側に指定するほう("riot"とか"lightgallery.js")はdevDependenciesとしてインストールしたnodeモジュール名と同じにしないと,tsコンパイル時にモジュールが見つかんねー!って怒られる.

参考: mae.chab.in

tsファイル

import * as riot from 'riot';
import * as lightGallery from 'lightgerllery.js';

型定義というか,そもそもライブラリをインポートというか,そういうことしてるので,さっき言ったようにモジュール名に合わせる必要がある.

まとめ

端的に言って,しんどい.

npmの@typesモジュール使えよとか言われるかもしれないけど,ブラウザで使うのに結局browserify(とかWebpackとか)使わなきゃアレな感じがするのでbrowserify-shim使うことになって,さらにしんどくなる.

あとriot.jsのタグのマージタスクが遅い.そんな長くないファイル2つマージしただけで2秒とかかかる.なにかやり方が悪いのかも知らん.

ts書くときはVSCode使ってるけど,型定義ファイルから補完とか必要な値とか表示してくれるのは便利.最高.

ありたそ画展

リニューアルしました. ありたそ先生の今後のより一層の活躍をご期待下さい.

https://pps5.github.io/AlitasoFan/

Dentoo.LTに参加してきた話

DentooLTに参加してきました。

ちょっと説明抜けたか嘘言ったかもしれないので。

読み込みダイアログをキャンセルできるようにしろ、くらいしか言わなかった気がするけど、実際はダイアログ推奨されてなくて、アクションバーの下に読み込みバーを表示するなりなんなりしてくれってことです。

発表時の資料はこちら。


Gmailの添付ファイルをGoogleドライブに自動保存する

普段研究関連で利用している学内メールからGmailに転送するようにしており、添付ファイルをAndroid端末でもみたい。 だけど、大体送られてくるのがdocxだったりpptxだったりするので、手持ちの端末にそれらを開くアプリを入れてないため、見られない。 以前まではInboxアプリで開いたファイルを、そのままGoogleドライブのアプリで開けたような気がする(※気がする)けども、今では「表示するアプリが見つかりません」って出て終わるようになったため、とりあえず対応するためにGoogle Apps Scriptで作りました。

単純に受信トレイのメールを確認して、保存するフォルダに同名のファイルがなければ保存するだけです。ざっとリファレンスを眺めた感じ、特定フォルダ内の検索はできないっぽかったので、全フォルダ内の名前検索をして、得られたファイル一覧の親フォルダを判定しています。

保存したいフォルダのIDはドライブでそのフォルダを開いた時のURLの最後の部分です。Gmail受信をトリガーとして実行はできないので、5分毎に実行するようにしています。

function attachmentUploader() {
  var threads = GmailApp.getInboxThreads();
  var msgs = GmailApp.getMessagesForThreads(threads);
  for (var i = 0; i < msgs.length; i++) {
    for (var j = 0; j < msgs[i].length; j++) {
      var attachments = msgs[i][j].getAttachments();
      saveToGmailFolder(attachments);
    }
  }
}

function isInGmailFolder(name) {
  var files = DriveApp.getFilesByName(name);
  while (files.hasNext()) {
    var file = files.next();
    var folders = file.getParents();
    while (folders.hasNext()) {
      var folder = folders.next();
      if (folder.getId() === '保存したいフォルダのID') {
        return true;
      }
    }
  }
  return false;
}

function saveToGmailFolder(attachments) {
  var folder = DriveApp.getFolderById('保存したいフォルダのID');
  for (var i = 0; i < attachments.length; i++) {
    if (!isInGmailFolder(attachments[i].getName())) {
      var data = DriveApp.createFile(attachments[i]);
      folder.addFile(data);
    }
  }
}

卒業決まりました。とバッテリ残量通知スクリプト

卒業

一時期とんでもなく卒業が危ぶまれた時期がありましたが、無事に卒業できそうです。

f:id:Inaab:20160228015110p:plain

卒業も決まったので、とりあえず当面の目標としては、今作ってるAndroidアプリを3月中には完成させることですか。いちいち変なところにこだわったり、そもそも作るの面倒な箇所を飛ばしたり、他のもの作ったりしてるので全然進んでないです。完成したとしてもPlayストアに登録するお金がないので、ストア公開自体は5月くらいとかになりそうなんですけど。

研究はもうちょっと計画的に、というかちゃんと毎週コンスタントに進捗を出せるように頑張っていきたいです……。

バッテリ残量通知スクリプト

ThinkpadDebianいれて、Awesome使ってるんですが、バッテリー表示は調べながらできたんですが、バッテリ残量が少ない時にどうするかって悩んで書きました。単純にacpiでバッテリ情報を引っ張ってきて10%以下の時にバッテリ残量と残り時間を表示するだけの簡単なものです。

なんか調べてる時にそういうスクリプトgithubにあるよ!みたいなの見たんですが、これくらいだったら書けるかな、と。
初めてnotify-sendとawk使ったんですが、便利ですね。

#!/bin/sh
if [ $$ != `pgrep -fo $0` ]; then
    exit 1;
fi
lastnotify=100;
while true; do
    battery=`acpi | grep Dis`
    if [ "$?" -eq 0 ]; then
	start=`echo $battery | awk 'match($0, /charging, /) {print (RSTART + RLENGTH)}'`
	end=`echo $battery | awk 'match($0, /%/) {print (RSTART - 1)}'`
	parcent=`echo $battery | cut -c$start-$end`

	if [ $parcent -le 10 -a $parcent -ne $lastnotify ]; then

	    if [ $parcent -le 8 ]; then
		urgency=critical
	    else
		urgency=normal
	    fi
		
	    remain=`echo $battery | cut -c30-37`
	    message="バッテリ残量:${parcent}%, 残り稼働時間:${remain}"
	    notify-send "バッテリ残量低下" "${message}" -t 59000 -u $urgency

	    lastnotify=$parcent
	fi
    fi
    sleep 60;
done

2015年振り返り

大晦日ということで2015年を振り返って。 昨年めちゃくちゃ適当な振り返りを書いた気がするので、今度はちょっとだけまじめに。ちょっとだけね。

1、2月

1月、2月に何をしていたか全く思い出せないのですが、どうやら2月にExcelアドインを作っていたようです。

inaab.hatenablog.com

それまでVBAなんてほとんど触ったことがなかったので、大したことがないものなのに変に苦労しました。 使う人はいないとわかりつつも、あまりにクソなコードを突貫工事で書き上げたので、見られたくなくてパスワードをかけました。が、パスワードを紛失したので今後改良などを行うことはできなくなりました。改良する予定もありませんけど。

3月

覚えてない。俺は一体何をしていたんだ……。 きっと論文読んでねってメールが届いて震えてたんだ。あとバイト。

4~6月

輪講で苦しんでた。

英語論文読んできて、まとめて発表ということでどの研究室でもやってただろうけど、時間が長すぎてつらかった。みんな慣れてないから先生方から突っ込まれることが多く、1人あたり4-50分、長い人だと1時間半とかかかってたので7人発表すると5時間、6時間とか。正直、もっとなんとかなったんじゃないのアレ、って今でも思ってる。

まあ何より大変なのは先生方だし、本当にお世話になりました。今現在進行形で物凄くお世話になってます。来年もお世話になります。よろしくお願いします。精進します。

7、8月

7月とか8月とかはたぶん院試の勉強してました。もともと数学が苦手だったので、1年次の授業でやったことですら思い出すのに時間がかかりました。院試直前でも結構不安でした。

本番では、ISの数学で行基本変形とかで時間かかって全然解けなくて、前と右斜め前に座っていた中国人留学生(1人は知らない人、もう1人は知ってるけど話したことがなかった)に慰めてもらいました。 まあ蓋を開けてみたら専門科目で稼がせて頂いたので余裕だったんじゃないかな。(実際はギリギリかもしれない。)

9月、10月

中間発表に向けて準備をしてたら、その1週間前にやけどをしました。 教授や研究室のメンバーから手羽先だのファントムペインだの言われながら、痛々しい包帯を巻いた手で指し棒を持って発表しました。

ちなみに労災の手続きがまだ進んでなくて病院から催促を受けてます。俺に言われたって困る。マネージャーと本社仕事しろ。

11、12月

なぜかこのブログの月間PVが1000を超える。 Google検索で「j com 解約」的な検索をすると7,8番目くらいに現れることを確認。みんなj:comだいすきやな。

現在

進捗がない。

学会発表の原稿も書けてない。