tdrk's diary

とある情報系大学生。主には自分のための備忘録...になる予定

【ruby】Runtime Errorについて

プログラムを作成してると次のようなエラー発生。

`[]=': can't add a new key into hash during iteration (RuntimeError)

どうやら、ハッシュのイテレーション中に新たなキーを追加できないとのこと。
調べてみるとRubyのバージョンが1.9.3ではなく1.8.7だと問題なく動くとのこと。
バージョンアップして仕様が変わったんですかね。

Rubyのバージョンを変えるのは嫌なので必要なデータを格納し、イテレーションの外で処理することで回避。

また同じことでハマるのが嫌なのでφ(..)メモメモ

【ruby】ランダムな文字列を生成

指定した長さのランダムな文字列を作りたいと思ったときに、
「Array#sample」を使ってみたら思い通りのものが得られなかったので、
その時の( ..)φメモメモ

得たい文字列は"0"または"1"をランダムに並べた文字列。
次のようにArray#sampleを使うと、"0"を1回、"1"を1回ランダムな順序で並べた文字列しか得られない。

length = 4 # 汎用化のために、指定長さを変数に格納
[*0..1].sample(length).join
# => "10" # 出力例

つまり、Array#sample では、ある要素を1回ずつしかとってこない。
しかも、生成できる文字列は最長でArrayのサイズまでなので、Arrayのサイズを超えた長さを指定してもそのサイズの文字列しか生成できない。

Array#sampleでは、"0011"みたいな文字列は生成できない。。。(´・ω・`)

ということで、調べる(´・ω・`)
その結果、"0011"みたいな文字列をランダムで生成するには次のように書けばOK!

length = 4
Array.new(length){[*0..1].sample}.join
# => "0011" # 出力例


(´・ω・`)「なるほどなぁ。。。」


ちなみに、もっと一般的にアルファベットとかも使う場合は次で。

length = 4
Array.new(length){[*:a..:z, *:A..:Z, *0..1].sample}.join
# => "PdgH" # 出力例

【ruby】Pythonの__main__みたいなやつ

Rubyのプログラムを書いていて、直接スクリプトを実行したときだけ動いてほしいテスト関数みたいなものが欲しいと思った。
Pythonだと、

if __name__ == __main__:
    hogehoge

ってかけるやつ、rubyにないのかなー?って思って調査。

答えとしてはある。
以下のように__FILE__変数を使う。

if __FILE__ == $0 then
    hogehoge
end

このようにすれば、if関数内に書かれたものはそのスクリプトを直接実行したときにだけ実行される。

今後、何度も使う予定なので( ..)φメモメモ

【シェルスクリプト】シェル上で進捗状況を表示

繰り返しの処理をしていく中で、今の進捗状況が見れるといいなと思い、それについて調査。
主にこちらのサイトを参考にさせてもらった。
全ては時の中に… : 【Linux】シェルで進捗を表示する

echoにおける表示の時に改行をせずに、同じ行の先頭から再描画するように書けばよい。

  • "\c" : 改行を抑制
  • "\r" : 行の先頭にフォーカスを移す

これら2つを組み合わせることで、徐々に変化する進捗の表示ができる。

以下、スクリプト例。

#!/bin/sh

COUNT=1                             # 今の実行回数を表す変数
MAX=5                               # 実行回数の最大値を表す変数
while [ $COUNT -ne $MAX ]
do
    echo "進度: ($COUNT/$MAX)\c"    # 改行を抑制しながら進捗状況を表示
    sleep 2                         # 2秒間停止
    COUNT=`expr $COUNT + 1`
    echo "\r\c"                     # 行頭にフォーカスを移す
done
echo "進度: ($MAX/$MAX)"            # これがないと表示が消えてしまうので、最後に改行を含めて書き込む

プログレスバー形式のスクリプトもつくりたいがこれは後日に...

【ruby】Stringを1文字ずつ処理する

Rubyで文字列を1文字ずつ処理していく方法。
Pythonと同様にできるかと思ってたらちょっと違った。。。

str = "hoge"
str.split(//).each do |s|
  p s
end
# "h"
# "o"
# "g"
# "e"


インデックスも同時にとってきたい場合は次のようにすればOK

str = "hoge"
str.split(//).each_with_index do |s, i|
  p [s, i]
end
# ["h", 0]
# ["o", 1]
# ["g", 2]
# ["e", 3]

Python.hがない...

今回もライブラリを入れてる時にエラーで怒られた時の話。

fatal error: Python.h: そのようなファイルやディレクトリはありません

という感じでPython.hがないというエラーが起こった。
こんな時には、

apt-get install python2.7-dev

を実行してあげればOK。



...なんだか環境構築時間かかってるな