5ee610e858812d3ce19941a85c5b99ef

I am a total newbie when it come to ruby (coming from a C# background).

Basically, I need to generate a series (500 of them) of random numbers, that have a fixed (16 chars) length.

What I've come up with works, but I'm wondering how it could be optimized.

1
2
3
4
5
6
7
8
9
10
11
12
13
chars="1234567890"  #only numbers
random_code=""

srand

500.times do
  16.times do
    pos = rand(chars.length)
    random_code += chars[pos..pos]
  end
  puts random_code
  random_code=""
end

Refactorings

No refactoring yet !

Avatar

Shawn Presser

October 2, 2007, October 02, 2007 19:07, permalink

2 ratings. Login to rate!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def random_word(*args)
  options = args.last.is_a?(Hash) ? args.pop : {}
  options[:length] = 16 unless options[:length] # Default to a word length o
  options[:letters] = (0 .. 9).to_a unless options[:letters] # Default to nu
  chars = options[:letters].to_a

  val = ""
  options[:length].times do
    pos = rand(chars.size)
    val << chars[pos].to_s
  end
  val
end

# 500 random 16-letter words containing only numbers
500.times do
  puts random_word
end

# 500 random 20-letter words containing a-z
500.times do
  puts random_word(:length => 20, :letters => 'a' .. 'z')
end
D5e83fd66c4a432c79bfe1e0c0fee462

Shawn Presser

October 2, 2007, October 02, 2007 19:08, permalink

No rating. Login to rate!

Hum.. Cut off some commments. Oh well. The first comment was "Default to a word length of 16 unless specified" and the second one was "Default to numbers unless specified". If you have any questions let me know.

5ee610e858812d3ce19941a85c5b99ef

khillabolt.myopenid.com/

October 2, 2007, October 02, 2007 19:19, permalink

No rating. Login to rate!

Wow Shawn, you really went all out. Your method really expands on what I was trying to do and offers a lot of flexibility.

Thank you so much for your input.

D5e83fd66c4a432c79bfe1e0c0fee462

Shawn Presser

October 2, 2007, October 02, 2007 20:59, permalink

No rating. Login to rate!

No problem, good luck with Ruby. If you have any other questions let me know!

Bfec5f7d1a4aaafc5a2451be8c42d26a

macournoyer

October 2, 2007, October 02, 2007 21:55, permalink

1 rating. Login to rate!

Could not resist to turn it into a oneliner.
Shorter but less flexible then Shawn's solution. Nice one Shawn!

1
500.times { puts((1..16).collect { '1234567890'.split('')[rand(10)] }.join) }
Ada486a7a6724ac155c537674f6942ae

hungryblank

October 3, 2007, October 03, 2007 03:25, permalink

No rating. Login to rate!

stressing a bit the [] method...

1
2
3
4
5
500.times { puts((1..16).inject('') { |a,n| a << '1234567890'[rand(10),1] }) }

# or

500.times { puts((1..16).map { '1234567890'[rand(10),1] }.join) }
Ada486a7a6724ac155c537674f6942ae

hungryblank

October 3, 2007, October 03, 2007 03:34, permalink

2 ratings. Login to rate!

and in case you really want just numbers...

1
500.times { puts((1..16).map { rand(10) }.to_s) }
5ee610e858812d3ce19941a85c5b99ef

khillabolt.myopenid.com/

October 3, 2007, October 03, 2007 04:20, permalink

No rating. Login to rate!

Wow, I have a lot to learn about ruby. :)

Avatar

Panya

October 3, 2007, October 03, 2007 10:43, permalink

1 rating. Login to rate!

2 Shawn Presser
Some modifications for your code.

1
2
3
4
5
6
7
8
9
10
11
def rand_word(*args)
  options = args.last.is_a?(Hash)? args.pop : {}
  options[:size] = 8 unless options[:size]
  options[:chars] = ("a".."z").to_a + ("A".."Z").to_a + (0..9).to_a unless options[:chars]
  chars = options[:chars].to_a
  size = options[:size].to_i
  (0...size).map{|n| chars[rand(chars.size)]}.join
end

500.times{puts rand_word(:size => 6, :chars => "a".."z")}
  
B4a4d3e4fae5ecdc906cc767abbf2ac3

Taku Nakajima

October 3, 2007, October 03, 2007 18:16, permalink

No rating. Login to rate!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Array
  def rand_select_1
    self[rand*size]
  end

  def rand_select(size)
    Array.new(size) { rand_select_1 }
  end
end

def random_pronouncable_password(size = 4)
  c = %w(b c d f g h j k l m n p qu r s t v w x z ch cr fr nd ng nk nt ph pr rd sh sl sp st th tr)
  v = %w(a e i o u y)

  c.rand_select(size).zip(v.rand_select(size)).to_s
end
7c45f63f61e478233f0c2ad3006b178c

michiel

October 5, 2007, October 05, 2007 13:43, permalink

2 ratings. Login to rate!

You know, rand(x) doesn't return anything but numbers either - why bother doing it one character at the time?

1
(1..500).map {rand(10 ** 16).to_s.rjust(16,'0')}
E635ccff7389d9070f5e7e9fe8b36beb

Ryan

October 8, 2007, October 08, 2007 04:16, permalink

No rating. Login to rate!

Panya - some (minor) modifications to your code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# when setting optional parameters, it's often a bit cleaner to use
# ||= instead of "unless options[:whatever]"

def rand_word(options = {})
  options[:size]  ||= 8
  options[:chars] ||= (0..9).to_a
  size              = options[:size]
  chars             = options[:chars]
  (0...size).map{|n| chars[rand(chars.size)]}.join
end

# even better (but untested)

def rand_word(options = {})
  size  = (options[:size]  ||= 8)
  chars = (options[:chars] ||= (0..9).to_a)
  (0...size).map{|n| chars[rand(chars.size)]}.join
end
87aa551019ab6b008f6bf03d71042d52

dsphunxion

November 19, 2007, November 19, 2007 13:57, permalink

No rating. Login to rate!

macournoyer: how exactly do you call that oneliner out on a terminal? I'm also new to ruby, just curious to try it in a terminal

Bfec5f7d1a4aaafc5a2451be8c42d26a

macournoyer

November 19, 2007, November 19, 2007 15:14, permalink

No rating. Login to rate!

You can open an interactive shell using the irb command
or run a oneliner from the terminal:

1
ruby -e "puts (1..500).map {rand(10 ** 16).to_s.rjust(16,'0')}"
E065268b4e2a95b2bbf09cf8350074b2

dsphunxion

November 19, 2007, November 19, 2007 17:17, permalink

No rating. Login to rate!

I tried from a normal bash prompt and it did nothing:

# ruby -e "(1..500).map {rand(10 ** 16).to_s.rjust(16,'0')}"
# ruby -v
ruby 1.8.5 (2006-08-25) [i386-linux]

From an interactive terminal:
#ruby
ruby -e "(1..500).map {rand(10 ** 16).to_s.rjust(16,'0')}"
-:1: syntax error
ruby -e "(1..500).map {rand(10 ** 16).to_s.rjust(16,'0')}"
^
-:1: Interrupt
# ruby
(1..500).map {rand(10 ** 16).to_s.rjust(16,'0')}
-:1: Interrupt

I guess I should hit the ruby books, any you'd care to recommend, I've got tons of awk/sed experience

Bfec5f7d1a4aaafc5a2451be8c42d26a

macournoyer

November 19, 2007, November 19, 2007 18:09, permalink

No rating. Login to rate!

sorry I forgot to put the puts in the previous command ^ that's why it wasn't printing anything (fixed now)

also to start the interactive terminal, type: irb not ruby

7f745cb20d1822c5efd76dbcf42c1223

dsphunxion

November 19, 2007, November 19, 2007 18:59, permalink

No rating. Login to rate!

Care to share any tutorials ;) If you would be so kind

Bfec5f7d1a4aaafc5a2451be8c42d26a

macournoyer

November 19, 2007, November 19, 2007 19:57, permalink

No rating. Login to rate!

Here's a fun intro to Ruby : http://poignantguide.net/ruby/chapter-3.html

Your refactoring





Format Copy from initial code

or Cancel