連続する数列をハイフンでまとめるPythonスクリプト

連続する数列をハイフンでまとめるシェルスクリプト – ザリガニが見ていた…。を見て、面白いことをやっているので Python でやってみた。

 cf. Rubyでどう書く?:連続した数列を範囲形式にまとめたい – builder by ZDNet Japan (元記事)

def diff(a):
    return map(lambda x, y: x - y, a[1:], a[:-1])

def hyphenate_num(s):
    a = map(lambda x: int(x), s.split())
    d = diff(a)
    b = map(lambda x, y: (x, y), a, d)
    r = []
    flg = False
    for x in b:
        if x[1] > 1:
            r.append(str(x[0]))
            r.append(', ')
            flg = False
        elif x[1] == 1:
            if not flg:
                r.append(str(x[0]))
                r.append('-')
                flg = True
        else:
            r.append(str(x[0]))
    return ''.join(r)

if __name__ == '__main__':
    print hyphenate_num("1 2 3")
    print hyphenate_num("1 2 3 5 7 8")
    print hyphenate_num("1 3 4 5 7")

実行結果:

^o^ > python hyphenate_num.py
1-3
1-3, 5, 7-8
1, 3-5, 7

あんまりきれいなコードじゃないけどできた。やっぱりreduceを使うのほうがいいのかなあ。

URLのリストからリンク集を作る

理由はどうでもいいんだけど、URLが大量に書かれたファイルがあって、そのひとつひとつをブラウザでチェックすることになった。で、ひとつずつコピペするのなんてかったるくってやってられないわけで、Pythonでスクリプトを書いてみた。
URLのリストはたとえばこんな感じ(実際はもっといっぱいある)。

^o^ > type url.txt
https://www.ruby-lang.org/ja/
http://www.python.jp/
http://www.perl.org/
http://www.haskell.org/
http://ocaml.jp/

スクリプトはこんなの。htmlを作るテンプレートエンジンには、Jinja2を使った。

import sys
from jinja2 import Environment, DictLoader

templates = {'index.html': """
<ul>
  <li style="list-style-type: none;">
    <ul>{% for url in urls %}</ul>
  </li>
</ul>
<ul>
  <li style="list-style-type: none;">
    <ul>
      <li><a href="{{ url }}">{{ url }}</a></li>
    </ul>
  </li>
</ul>
{% endfor %}

"""
}

filename = sys.argv[1]
f = open(filename, 'r')
urls = []
for line in f:
    urls.append(line.rstrip('\n'))
f.close

env = Environment(loader=DictLoader(templates))
tmpl = env.get_template('index.html')
html = tmpl.render(urls=urls)

print html

Jinja2の使い方はここらへんを参考にした。
 cf. Jinja2 利用ノート
 cf. http://jinja.pocoo.org/docs/api/#loaders
上のサイトでは、テンプレートローダーにFileSystemLoaderを使って説明されているけど、今回はいくつものテンプレートを使うわけではないし、テンプレート自体も簡単なものなので、DictLoaderを使っている。

スクリプトはこんな風に使う。

^o^ > python genlinks.py url.txt > index.html

できた index.html がこれ。

<html>
  <body>
    <ul>
      
        <li><a href="https://www.ruby-lang.org/ja/">https://www.ruby-lang.org/ja/</a></li>
      
        <li><a href="http://www.python.jp/">http://www.python.jp/</a></li>
      
        <li><a href="http://www.perl.org/">http://www.perl.org/</a></li>
      
        <li><a href="http://www.haskell.org/">http://www.haskell.org/</a></li>
      
        <li><a href="http://ocaml.jp/">http://ocaml.jp/</a></li>
      
    </ul>
  </body>
</html>

なんか余計な改行が入ってるけど、まあいいか。

Haskellでランダムな文字列を得る

先日のお題を、今度は Haskell でやってみた。Haskell はだいぶ忘れてるな。
乱数の使い方は↓ここを参考にした。

cf. haskell で乱数 – はわわーっ

module Main where

import System.Environment ( getArgs )
import System.Random
import Control.Monad

strPool :: String
strPool = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

lenPool :: Int
lenPool = length strPool - 1

randomStr :: Int -> IO String
randomStr n = do
  lis <- replicateM n $ (getStdRandom $ randomR (0, lenPool) :: IO Int)
  return $ map (\ x -> strPool !! x) lis

main :: IO ()
main = do
  argv <- getArgs
  let n = read $ head argv
  randStr <- randomStr n
  putStrLn randStr

実行結果:

^o^ > runhaskell randomString.hs 20
GhDADFMuNNxrUBbpMXw3

Ruby でランダムな文字列を得る

昨日のやつを Ruby でもやってみた。

# coding: utf-8

def randstr(length)
  pool = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a
  r = Random.new
  l = pool.size
  rand_str = ''
  length.times do |i|
    rand_str += pool[r.rand(l)]
  end
  rand_str
end

length = ARGV.shift.to_i
print randstr(length)

実行結果:

^o^ > random_string.rb 20
y397x9Bx1z7fAvJTr9RK

Random クラスの使い方はここ:

cf. http://docs.ruby-lang.org/ja/1.9.3/class/Random.html

Pythonでランダムな文字列を得る

さっきのエントリのPython版。

import random
import sys

def randstr(length):
    s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
    pool = list(s)
    l = len(pool) - 1
    rand_str = ""
    for i in xrange(length):
        rand_str += pool[random.randint(0, l)]
    return rand_str

length = int(sys.argv[1])
print randstr(length)

random モジュールの使い方についてはこちら:
cf. randomモジュール – blog.PanicBlanket.com

実行結果:

^o^ > python random_string.py 20
cw1xeVn49yXZgexCWuDl

Perlでランダムな文字列を得る

ググってみると String::Random モジュールを使うといいらしいんだけど、うまくインストールできなかったので(原因不明)、もっとベタな方法でやることにした。

use strict;
use warnings;

sub randstr {
    my $length = shift(@_);

    my @chars;
    push(@chars, ('A'..'Z'));
    push(@chars, ('a'..'z'));
    push(@chars, ('0'..'9'));

    my $rand_str = '';

    for (my $i = 1; $i <= $length; $i++) {
        $rand_str .= $chars[int(rand($#chars+1))];
    }

    return $rand_str;
}

my $length = shift(@ARGV);
print randstr($length);

$#chars という表現は、配列 @chars の最後のインデックスを取得している。こんな書き方があるとは初めて知った。

実行結果:

^o^ > random_string.pl 20
LxN8r4RSM8rdZ4iQdp3r

ボルダリングをやってきた(2)

気がつけば一月以上も更新してなかった。当初のせめて週一更新の目標はどこへいったやら。

ブログはあんまり続いていないけど、ボルダリングは週一で続いている。
今日は、先週散々苦労した緑の5番を一撃でクリア。その勢いで緑の6、7番も一撃。だけど調子よくいったのもそこまでで、水色の4番がどうしてもクリアできなかった。来週こそ!