2012/03/30
2012/03/29
2012/03/28
2012/03/27
2012/03/26
2012/03/25
2012/03/24
2012/03/23
2012/03/22
2012/03/21
2012/03/20
2012/03/19
2012/03/15
2012/03/14
2012/03/13
2012/03/11
2012/03/10
リスト ("*" (2 3 4) (a b) "!" (8 9 0)) から文字列 "*2a!8", "*2a!9", "*2a!0", "*2b!8" ...を作る
2chのLisp Schemeスレに掲題の問題が出てた。
ちょっとズルい気もするけど、それっぽい結果になった。gaucheで書きました。
235 :デフォルトの名無しさん:2012/03/09(金) 15:21:07.33 Allegro Common Lisp (ACL) の試用版を使っています (list "*" '(2 3 4) '(a b) "!" '(8 9 0)) こういう文字列とリストからなるリストをもとに *2a!8 *2a!9 *2a!0 *2b!8 *2b!9 *2b!0 *3a!8 ... と続くものを出力したいです(文字列とリストは0回以上ランダムに表れます) リストについては命令型言語でいうところの for (...) for (...) のような処理をすることになりそうですが どこから手をつければよいかわかりません おそらくmapcarを使ってリストを作り直す必要があります? どうすればよいですかこの問題って、対象のリスト
(list "*" '(2 3 4) '(a b) "!" '(8 9 0))の文字列も要素一個の集合ってことにして
(list '("*") '(2 3 4) '(a b) '("!") '(8 9 0))であると見なして、集合の集合と考えちゃう。するとこれらの集合に対してSQLで言うところのcross joinの結果を出せばいいんじゃないかという気がする。調べてみたらcross joinってデカルト積って言うんですって。そこで、デカルト積を出すにはどうしたらいいのかなーと探してみたらgaucheのutil.combinationsにcartesian-productってのが組み込みであった。
ちょっとズルい気もするけど、それっぽい結果になった。gaucheで書きました。
(use util.combinations) (let* ((ls (list "*" '(2 3 4) '(a b) "!" '(8 9 0))) (ls (map (^x (if (list? x) x (list x))) ls))) (for-each (^s (write s)(newline)) (map (apply$ string-append) (map (map$ x->string) (cartesian-product ls))))) ;; "*2a!8" ;; "*2a!9" ;; "*2a!0" ;; "*2b!8" ;; "*2b!9" ;; "*2b!0" ;; "*3a!8" ;; "*3a!9" ;; "*3a!0" ;; "*3b!8" ;; "*3b!9" ;; "*3b!0" ;; "*4a!8" ;; "*4a!9" ;; "*4a!0" ;; "*4b!8" ;; "*4b!9" ;; "*4b!0"
追記
せっかくなのでちょっと見やすく(use util.combinations) (define (print-list ls) (for-each (^s (write s)(newline)) ls)) (define (list->set-of-set ls) (map (^x (if (list? x) x (list x))) ls)) (define (cartesian-product-string set-of-set) (map (apply$ string-append) (map (map$ x->string) (cartesian-product set-of-set)))) (define (main ls) (print-list (cartesian-product-string (list->set-of-set ls)))) (main (list "*" '(2 3 4) '(a b) "!" '(8 9 0))) ;; "*2a!8" ;; "*2a!9" ;; "*2a!0" ;; "*2b!8" ;; "*2b!9" ;; "*2b!0" ;; "*3a!8" ;; "*3a!9" ;; "*3a!0" ;; "*3b!8" ;; "*3b!9" ;; "*3b!0" ;; "*4a!8" ;; "*4a!9" ;; "*4a!0" ;; "*4b!8" ;; "*4b!9" ;; "*4b!0"
2012/03/09
csvをsqlにする(insert, update)
検索すればいくらでも出てくるようなものをあえて作りました。csvをinsert文、update文に変換するコマンド。
昨日のこれと合わせると結構使えるかも。
例えばこういうCSVを
昨日のこれと合わせると結構使えるかも。
例えばこういうCSVを
$ cat sample.csv aaa,bbb,ccc,ddd,eee 1,2,3,4,5 10,20,30,40,50 100,200,300,400,500csv2sqlに渡すと
$ csv2sql sample.csv INSERT INTO sample (aaa , bbb , ccc , ddd , eee) VALUES ('1' , '2' , '3' , '4' , '5') INSERT INTO sample (aaa , bbb , ccc , ddd , eee) VALUES ('10' , '20' , '30' , '40' , '50') INSERT INTO sample (aaa , bbb , ccc , ddd , eee) VALUES ('100' , '200' , '300' , '400' , '500') $ csv2sql -k aaa sample.csv UPDATE sample SET aaa='1', bbb='2', ccc='3', ddd='4', eee='5' WHERE aaa='1' UPDATE sample SET aaa='10', bbb='20', ccc='30', ddd='40', eee='50' WHERE aaa='10' UPDATE sample SET aaa='100', bbb='200', ccc='300', ddd='400', eee='500' WHERE aaa='100' $ csv2sql -k "aaa,ccc" sample.csv UPDATE sample SET aaa='1', bbb='2', ccc='3', ddd='4', eee='5' WHERE aaa='1' AND ccc='3' UPDATE sample SET aaa='10', bbb='20', ccc='30', ddd='40', eee='50' WHERE aaa='10' AND ccc='30' UPDATE sample SET aaa='100', bbb='200', ccc='300', ddd='400', eee='500' WHERE aaa='100' AND ccc='300'こんな感じ。CSVファイル名がTable名に、CSVのheader行がカラム名に。update文でキーまで更新してることに今ごろ気づいたけど気にしない。
ソース
Gaucheで書きました。ソースはこちら。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/gosh | |
(use srfi-1) | |
(use text.csv) | |
(use file.util) | |
(use util.list) | |
(use gauche.parseopt) | |
(define (usage) | |
(print "Usage: csv2sql [options ...] <csv-file>") | |
(print " h|help - print this usage") | |
(print " k|keys - primary key column names (delimiter=,)") | |
(print " d|delimitter - (default=,)") | |
(print " n|tablename") | |
(print " t|tsv") | |
(print) | |
(print "SQL query") | |
(print " default => insert") | |
(print " -k|keys => update") | |
(print "Table name and Column name") | |
(print " Table name: <csv-file> name without extentions") | |
(print " Column name: header row column names") | |
(exit 1)) | |
(define (csv->list file :optional (delim #\,)) | |
(port->list (make-csv-reader delim) | |
(if file | |
(open-input-file file) | |
(current-input-port)))) | |
(define (csv->sql csv table-name . key-col-names) | |
(if (null? csv) | |
'() | |
(let ((header (car csv)) | |
(csv (cdr csv))) | |
(if (null? key-col-names) | |
(csv->insert-str csv table-name header) | |
(apply csv->update-str csv table-name header key-col-names))))) | |
(define (path->filename-without-ext path) | |
(receive (dir filename ext) | |
(decompose-path path) | |
filename)) | |
(define (keys-str->list keys-str) | |
(string-split keys-str #\,)) | |
(define (csv->insert-str csv table-name column-names) | |
(define (make-values row) | |
(intersperse "," (map (pa$ format "'~a'") row))) | |
(map (^[row] | |
(format "INSERT INTO ~a ~a VALUES ~a;" | |
table-name | |
(intersperse "," column-names) | |
(make-values row))) | |
csv)) | |
(define (csv->update-str csv table-name column-names . key-col-names) | |
(define (make-set row) | |
(apply string-append | |
(intersperse | |
", " | |
(fold-right (^[colname val acc] | |
(if (member colname key-col-names) | |
acc | |
(cons (format "~a='~a'" colname val) acc))) | |
'() column-names row)))) | |
(define (make-where row) | |
(apply string-append | |
(intersperse | |
" AND " | |
(map (^[key-col-name] | |
(let1 idx (list-index (pa$ equal? key-col-name) | |
column-names) | |
(format "~a='~a'" key-col-name (~ row idx)))) | |
key-col-names)))) | |
(map (^[row] | |
(format "UPDATE ~a SET ~a WHERE ~a;" | |
table-name | |
(make-set row) | |
(make-where row))) | |
csv)) | |
(define (main args) | |
(let-args (cdr args) | |
((help "h|help" => usage) | |
(keys "k|keys=s") | |
(delim "d|delimitter=s" #\,) | |
(tsv? "t|tsv") | |
(tablename "n|tablename=s") | |
(else (opt . _) | |
(print "Unknown option : " opt) | |
(usage)) | |
. rest) | |
(let ((csv (csv->list (and (not (null? rest))(car rest)) | |
(if tsv? #\tab delim))) | |
(filename (cond ((and (null? rest) tablename) tablename) | |
((null? rest) "<TableName>") | |
(else (path->filename-without-ext (car rest))))) | |
(keys (if keys (keys-str->list keys) '()))) | |
(for-each print (apply csv->sql csv filename keys))))) |
追記
update文でキーまで更新してることに今ごろ気づいたけど気にしない。
対応した。
2012/03/08
shell scriptでオプション引数を除いた引数を得る
getoptsした後のOPTIND - 1分shiftすればよかったのかー。というかOPTINDなるものを知らなんだ。
#!/bin/sh while getopts abcdef:g:h: OPT do echo $OPT done echo $OPTIND shift `expr "$OPTIND" - 1` echo "$@"
$ ~/temp % ./cmdargs -a -b -c -d -e -f hoge -g fuga -h piyo a b c d a b c d e f g h 12 a b c d $ ~/temp % ./cmdargs -a -b -c -f hoge -g fuga -h piyo a b c d a b c f g h 10 a b c d
shellで相対パスを絶対パスに
もっと簡単な方法はないのかね。
$ abp ~/bin /home/valvallow/bin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# http://dokonoumanohone.blog47.fc2.com/blog-entry-2.html | |
for ARG in "$@" | |
do | |
echo $(cd $(dirname "$ARG") && pwd)/$(basename "$ARG") | |
done |
追記
@kikuchan98先生に教えてもらいました!1行目無視
1行目無視。sedで行指定で削除できんのか。
$ cat hoge.txt | sed '1d'
追記
これまた@kikuchan98先生に教えてもらいました!$ cat hoge.txt | tail -n +2
csvをmapping
こういうCSVがあるとき
sample.jsはこんな感じ
いやー、やっぱS式っていいですね。人にやさしい脳にやさしい。
$ cat sample.csv a,b,c 1,2,3 10,20,30 100,200,300 1,2,3 10,20,30 100,200,300 1,2,3 10,20,30 100,200,300 1,2,3 10,20,30 100,200,300https://gist.github.com 1,2,3 10,20,30 100,200,300このように
$ cat sample.csv | csvremap sample.js a,b,c 1,2,3 foo,hoge,30 bar,200,300 1,2,3 foo,hoge,30 bar,200,300 1,2,3 foo,hoge,30 bar,200,300 1,2,3 foo,hoge,30 bar,200,300 1,2,3 foo,hoge,30 bar,200,300となる、というだけのコマンド。jsonってのがなんともアレだけど、動けばいいんです動けば。わりと活躍するかもしれん。
sample.jsはこんな感じ
$ cat sample.js {"a":{ "10":"foo" , "100":"bar" } , "b":{ "20":"hoge" } }cut,sort,uniqなんかのコマンドと相性いいかも(そらそうだろうな)。
$ cat sample.csv | csvremap sample.js | tail -n +2 | sort -nr | uniq 1,2,3 foo,hoge,30 bar,200,300で、こうやってmap系のコマンド作ると絶対reduce系のコマンド欲しくなるな(笑)
ソース
こちら。gauche。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/gosh | |
(use srfi-1) | |
(use text.csv) | |
(use file.util) | |
(use rfc.json) | |
(use util.list) | |
(use gauche.parseopt) | |
(define (usage) | |
(print "Usage: csvremap [opt ...] <mapping-table-json> <csv-file>") | |
(print " h|help => print this usage") | |
(print " d|delimiter => delimiter (default ,)") | |
(print " t|tsv") | |
(print " json spec => '{csv-column-name:{csv-column-value:substitution, ...}, ...}'") | |
(exit 1)) | |
(define (write-csv csv port :optional (delim #\,)) | |
(let1 writer (make-csv-writer delim) | |
(for-each (pa$ writer port) csv))) | |
(define (csv->list file :optional (delim #\,)) | |
(port->list (make-csv-reader delim) | |
(if file | |
(open-input-file file) | |
(current-input-port)))) | |
(define (file->json file) | |
(parse-json-string | |
(if file | |
(file->string file) | |
(port->string (current-input-port))))) | |
(define (map-csv-columns csv table) | |
(if (or (null? csv) | |
(null? table)) | |
csv | |
(let ((header (car csv)) | |
(csv (cdr csv))) | |
(cons header | |
(map (^[csv-row] | |
(map (^[name val] | |
(let1 table-row (assoc-ref table name) | |
(let1 new-val (and table-row (assoc-ref table-row val)) | |
(or new-val val)))) | |
header csv-row)) | |
csv))))) | |
(define (main args) | |
(let-args (cdr args) | |
((help "h|help" => usage) | |
(delim "d|delimiter=s" ",") | |
(tsv "t|tsv") | |
(else (opt . _) | |
(print "Unknown option : " opt) | |
(usage)) | |
. rest) | |
(when (null? rest) | |
(print "wrong number of arguments. required 1, got 0.") | |
(usage)) | |
(let* ((delim (if tsv #\tab (~ delim 0))) | |
(table (file->json (and (not (null? rest))(car rest)))) | |
(csv (csv->list (and (not (null? (cdr rest))) | |
(cadr rest)) delim))) | |
(write-csv (map-csv-columns csv table) | |
(current-output-port) | |
delim)))) |
追記
jsonを標準入力から受け取るようにしてたけど、引数の順序を変えてCSVを標準入力から受け取るようにした。どう考えてもCSVの方が加工されてわたってくることが多いもんな。使ってて不便だった。2012/03/07
KPF(熊本プログラミングフリークス)の勉強会を開催します
ブログで告知するの久しぶり。
プログラミングが好きな人は参加すると楽しいと思います。これからプログラミングを始めたい人、LTしてみたい人、ヘンタイ(いい意味)、仕事のプログラミングで悩んでる人、面白いもの作ったので発表したい人、変な人(面白い人・すごい人)に会いたい人など、これまでいろんな人に参加して頂いてます。
2012/03/31(土)の13時からです。会場は東海大学熊本キャンパスにお世話になります。ひやかし、のぞき見、歓迎します。
LT応募多すぎて入り切らないかもしれません(笑)
2012/03/31(土)の13時からです。会場は東海大学熊本キャンパスにお世話になります。ひやかし、のぞき見、歓迎します。
LT応募多すぎて入り切らないかもしれません(笑)
C#でREPL(Windows)
string.Formatのフォーマット指定子全部覚えてます?Enumerable.Range(0, 10)の結果が0から10までなのか0から9までなのか覚えてます?僕は覚えてないのでググるか、試しに書いてみます。consoleプロジェクト作って試したり、今書いてるソースに応急的に書き足して試したりするのって面倒じゃないですか?みんなどうやってんの?ConsoleApplication58.csとか作ってやってんの?REPL欲しくないですか?
なのでvpsにmono入れてsshでcsharpを使って試してました。が、monoのwindows向けのバイナリ入れればいい話でした。アホ過ぎた。csharp.bat叩けばcmdでreplが立ち上がるのでお手軽。
2012/03/06
2012/03/05
2012/03/05
- Gauche用OpenCVラッパー、Gauche-CVお披露目 - aharisuのごみ箱
- DB操作ツール Emacs DBI を作ってみた - 技術日記@kiwanami
- セキュリティさくら 勉強会#3 - self.extract
- 【みんカラ】 第3回 熊本セキュリティ勉強会 #セキュリティさくら|まいふぇいばりっつ|ブログ|俺様ななみん - 車・自動車SNS(ブログ・パーツ・整備・燃費)
- neocomplcacheを利用したGauche用補完プラグインgosh_completeを作ってます(インストール篇) - aharisuのごみ箱
- Gauche-SDLでライフゲーム - aharisuのごみ箱
- Gauche-SDLをWindowsで動かす - aharisuのごみ箱
- ***でSTGを作りますが何か?:いで庵
labels :
bookmark,
feedburner,
Web
日記(業務アプリ開発)
久しぶりに既存業務アプリ保守のお仕事。C#。業務アプリ開発はほとんどSQLとリファクタリングがメインだなと。いい機会なので勉強しますか。幸いまーちんふぁうらー先生の本を積んでるので消化しましょう。あ、コードコンプリート上下巻を再読もいいかもしれん。しかし久しぶりを差し引いてもSQL難しい。C#も。S式はあんなに親切なのに・・・。というか脳スペックが悪いのでS式のシンプルさに慣れると戻れんのかもしれん。
日記(2012年)
最近、読書もプログラミングもご無沙汰。去年の秋頃から私的な面で忙しいのが理由の一つ。去年の9月から今年の5月末まで週末はほとんど予定で埋まってる。リア充。2月に転職したのも理由の一つ。いくら楽しい職場と言っても新しい環境は何かと疲れる。
ということで今年は6月くらいまで、空いた時間は積極的にだらだらごろごろする。もしくは筋トレと水泳でリフレッシュだな。筋トレは4ヶ月超えてから効果出てきて(というより腹筋のやり方変えてから?)腹筋割れてきた。けど、徐々に筋肉痛にならなくなるとともに効果が落ちてきた。もっと負荷のかかるトレーニングに変えた方がいいのかな。
labels :
diary
2012/03/04
2012/03/04
- 『Emacs実践入門』を書く際に心掛けた点について。 - 日々、とんは語る。
- 3連続でTwitterに書くぐらいならブログで書いたほうがいい - ARTIFACT@はてブロ
- プログラマのためのUXチートシート — ありえるえりあ
- 自分をすごい人間だと過信していたから、人のことを話す時は悪口しか言えなかったんです。 - tumbllow
- 司馬遼太郎先生がね、物事を始めるとき、すぐに意味や答えを見つけようするのはやめなさい、って言ってたよ。... - tumbllow
- よいと説明しないとわからないものはたいしてよくない - tumbllow
- 楽しさにはビジネス価値があります――結局、モチベーションこそがプログラマの生産性を左右するのです。 - tumbllow
- 駄目な人ほど人に忠告したがる - tumbllow
- 10人に 9人は凡人だが、10人に 9人は自分は凡人ではないと思っている - tumbllow
- フルタイムのプログラマとして働き出して間もない頃、 ある有名なハッカーと話していて、... - tumbllow
- 僕の見る限りでは、自称常識人はキチガイ。 - tumbllow
labels :
bookmark,
feedburner,
Web
2012/03/03
2012/03/02
登録:
投稿 (Atom)