Support

If you have a problem or need to report a bug please email : support@dsprobotics.com

There are 3 sections to this support area:

DOWNLOADS: access to product manuals, support files and drivers

HELP & INFORMATION: tutorials and example files for learning or finding pre-made modules for your projects

USER FORUMS: meet with other users and exchange ideas, you can also get help and assistance here

NEW REGISTRATIONS - please contact us if you wish to register on the forum

Ruby Exercise

For general discussion related FlowStone

Ruby Exercise

Postby DaveyBoy » Tue Apr 11, 2017 12:22 pm

So.... I needed a Hash where note numbers are the keys and note names are the values, so instead of typing it all out I thought it would be a good exercise to try and auto-generate it.

Image

Code: Select all
#  1 - Generate note names, we need to start with C so doing it in 2 steps:
a = ((Array("C".."G") + Array("A".."B")).zip Array("C#".."G#") + Array("A#".."B#")).flatten

#  2 - Remove the B# and E#:
a.delete_if{|e|e == "B#"||e =="E#"} # gives: ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]

#  3 - Repeat a 11 times:
b = Array.new(11,a).flatten

#  4 - Generate 0 to 10 (the octave nos) 12 times and sort:
c =((Array (0..10)) * 12).sort # Gives: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,...  10, 10]

#  5 - Zip b and c together and remove the last 4 elements:
d = b.zip(c).take(128) # Gives: [["C", 0], ["C#", 0], ["D", 0], ["D#", 0], ["E", 0].....  ["F#", 10], ["G", 10]]

#  6 - Join the note names and octave nos together:
e = d.map{|e|e[0] + e[1].to_s} # Gives: ["C0", "C#0", "D0", "D#0",......  "F#10", "G10"]

#  7 - Generate the Hash
notes = Hash[e.map.with_index{ |x, i| [i, x ] }] # Gives: {0=>"C0", 1=>"C#0",.....  126=>"F#10", 127=>"G10"}

watch notes


Note No Creation.fsm
(1.29 KiB) Downloaded 848 times


So whilst what I've come up with does actually work, I can't help thinking that there must be a more elegant, Ruby way of doing this.

Would any of the Ruby experts on here care to take a look and show me how it should be done? :)

Thanks in advance
Dave
User avatar
DaveyBoy
 
Posts: 131
Joined: Wed May 11, 2016 9:18 pm
Location: Leeds UK

Re: Ruby Exercise

Postby tulamide » Tue Apr 11, 2017 2:27 pm

Well, I don't see much sense in not using a string of key names, so this would be my turn.

Code: Select all
a = "C C# D D# E F F# G G# A A# B".split
h = Hash.new
h.default_proc = proc do |hash, key|
   hash[key] = a[key % 12] + (key / 12).to_s
end


You can then directly call a hash via h[desired_key], but be aware that the key.value pairs are only generated when they are requested for the first time ( for example, h[2] calls the proc if not yet defined )
"There lies the dog buried" (German saying translated literally)
tulamide
 
Posts: 2688
Joined: Sat Jun 21, 2014 2:48 pm
Location: Germany

Re: Ruby Exercise

Postby DaveyBoy » Tue Apr 11, 2017 2:57 pm

Wow... that's brilliant, and so short too.
I knew there had to be better ways of doing this but I never expected it to be so concise!

I've never programmed before and only been doing Flowstone for about a year or so (guess it shows :lol: ), so I think it may have been another year or two before I'd have done it like this.

Got some studying to do now to see how it works.

Thanks Tulamide :D
User avatar
DaveyBoy
 
Posts: 131
Joined: Wed May 11, 2016 9:18 pm
Location: Leeds UK


Return to General

Who is online

Users browsing this forum: Google [Bot] and 57 guests