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

Users are reminded of the forum rules they sign up to which prohibits any activity that violates any laws including posting material covered by copyright

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 873 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: 2714
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 59 guests