Julia: Conditional on For Loop Macros - for-loop

Is there an easy way to change a "for loop header" depending on the packages a user has? For example, #progress for is good for adding a progress bar in Juno/Atom (just found out!), while we also have things like #simd, #acc, and #parallel. So what I want to have on this loop is to put a bunch of these macros conditionally given a boolean from the user or depending on availability. However, if I do a simple
if isdefined(#progress)
#progress for ...
elseif accelerate
#acc for ...
elseif
#parallel for ...
end
or something of that sort, I would have to keep pasting around the same for loop code. Is there some more elegant way of doing this? Also, I may want to combine some, and so once you start looking at the viable combinations that ends up being a lot of code!

The Pkg.installed method will error if the package isn't installed. It takes a string, and returning the decorated expression after that line with the other possibility in the catch block is effective for this sort of thing:
macro optional_something(pkg, expr)
try
Pkg.installed(string(pkg)) == nothing && return expr
esc(quote
#time $expr
end)
catch
expr
end
end
# this won't add the macro #time
#optional_something XXX rand(1000)
# this will
#optional_something Plots rand(1000)

Related

Filter an collection of tuples

I'm playing with iterables and comprehension in Julia and tried to code simple problem: find all pairs of numbers less then 10 whose product is less then 10. This was my first try:
solution = filter((a,b)->a*b<10, product(1:10, 1:10))
collect(solution)
but I got error "wrong number of arguments". This is kind of expected because anonymous function inside filter expects two arguments but it gets one tuple.
I know I can do
solution = filter(p->p[1]*p[2]<10, product(1:10, 1:10))
but it doesn't look nice as the one above. Is there a way I can tell that (a,b) is argument of type tuple and use something similar to syntax in first example?
I don't think there's a way to do exactly as you'd like, but here are some alternatives you could consider for the anonymous function:
x->let (a,b)=x; a*b<10 end
x->((a,b)=x; a*b<10)
These can of course be made into macros if you like:
macro tup(ex)
#assert ex.head == :(->)
#assert ex.args[1].head == :tuple
arg = gensym()
quote
$arg -> ( $(ex.args[1]) = $arg; $(ex.args[2]) )
end
end
Then #tup (a, b) -> a * b < 10 will do as you like.
Metaprogramming in Julia is pretty useful and common for situations where you are doing something over and over and would like specialized syntax for it. But I would avoid this kind of metaprogramming if this were a one-off thing, because adding new syntax means learning new syntax and makes code harder to read.

Ruby elegant alternative to ++ in nested loops?

Before anything, I have read all the answers of Why doesn't Ruby support i++ or i—? and understood why. Please note that this is not just another discussion topic about whether to have it or not.
What I'm really after is a more elegant solution for the situation that made me wonder and research about ++/-- in Ruby. I've looked up loops, each, each_with_index and things alike but I couldn't find a better solution for this specific situation.
Less talk, more code:
# Does the first request to Zendesk API, fetching *first page* of results
all_tickets = zd_client.tickets.incremental_export(1384974614)
# Initialises counter variable (please don't kill me for this, still learning! :D )
counter = 1
# Loops result pages
loop do
# Loops each ticket on the paged result
all_tickets.all do |ticket, page_number|
# For debug purposes only, I want to see an incremental by each ticket
p "#{counter} P#{page_number} #{ticket.id} - #{ticket.created_at} | #{ticket.subject}"
counter += 1
end
# Fetches next page, if any
all_tickets.next unless all_tickets.last_page?
# Breaks outer loop if last_page?
break if all_tickets.last_page?
end
For now, I need counter for debug purposes only - it's not a big deal at all - but my curiosity typed this question itself: is there a better (more beautiful, more elegant) solution for this? Having a whole line just for counter += 1 seems pretty dull. Just as an example, having "#{counter++}" when printing the string would be much simpler (for readability sake, at least).
I can't simply use .each's index because it's a nested loop, and it would reset at each page (outer loop).
Any thoughts?
BTW: This question has nothing to do with Zendesk API whatsoever. I've just used it to better illustrate my situation.
To me, counter += 1 is a fine way to express incrementing the counter.
You can start your counter at 0 and then get the effect you wanted by writing:
p "#{counter += 1} ..."
But I generally wouldn't recommend this because people do not expect side effects like changing a variable to happen inside string interpolation.
If you are looking for something more elegant, you should make an Enumerator that returns integers one at a time, each time you call next on the enumerator.
nums = Enumerator.new do |y|
c = 0
y << (c += 1) while true
end
nums.next # => 1
nums.next # => 2
nums.next # => 3
Instead of using Enumerator.new in the code above, you could just write:
nums = 1.upto(Float::INFINITY)
As mentioned by B Seven each_with_index will work, but you can keep the page_number, as long all_tickets is a container of tuples as it must be to be working right now.
all_tickets.each_with_index do |ticket, page_number, i|
#stuff
end
Where i is the index. If you have more than ticket and page_number inside each element of all_tickets you continue putting them, just remember that the index is the extra one and shall stay in the end.
Could be I oversimplified your example but you could calculate a counter from your inner and outer range like this.
all_tickets = *(1..10)
inner_limit = all_tickets.size
outer_limit = 5000
1.upto(outer_limit) do |outer_counter|
all_tickets.each_with_index do |ticket, inner_counter|
p [(outer_counter*inner_limit)+inner_counter, outer_counter, inner_counter, ticket]
end
# some conditional to break out, in your case the last_page? method
break if outer_counter > 3
end
all_tickets.each_with_index(1) do |ticket, i|
I'm not sure where page_number is coming from...
See Ruby Docs.

Loop with conditions in python

Consider the following code in C:
for(int i=0; i<10 && some_condition; ++i){
do_something();
}
I would like to write something similar in Python. The best version I can think of is:
i = 0
while some_condition and i<10:
do_something()
i+=1
Frankly, I don't like while loops that imitate for loops. This is due to the risk of forgetting to increment the counter variable. Another option, that addressess this risk is:
for i in range(10):
if not some_condition: break
do_something()
Important clarifications
some_condition is not meant to be calculated during the loop, but rather to specify whether to start the loop in the first place
I'm referring to Python2.6
Which style is preferred? Is there a better idiom to do this?
This might not be related, but there's what I'm used to do... If some_condition is simple enough, put it in a function and filter items you iterate over:
def some_condition(element):
return True#False
for i in filter(some_condition, xrange(10)):
pass
You can use this approach also when you iterate over some list of elements.
selected = filter(some_condition, to_process)
for i, item in enumerate(selected):
pass
Again, this might not be your case, you should choose method of filtering items depending on your problem.
In general, the "range + break" style is preferred - but in Python 2.x, use xrange instead of range for iteration (this creates the values on-demand instead of actually making a list of numbers).
But it always depends. What's special about the number 10 in this context? What exactly is some_condition? Etc.
Response to update:
It sounds as though some_condition is a "loop invariant", i.e. will not change during the loop. In that case, we should just test it first:
if some_condition:
for i in xrange(10):
do_something()
for loops with a constant upper bound are a bit rare in Python. If you are iterating over somearray, you might do:
for i in xrange(len(somearray)):
if not some_condition:
break
do_sth_with(i, somearray[i])
or, better:
for i, item in enumerate(somearray):
if not some_condition:
break
do_sth_with(i, item)

Summarize object area with a Hash in Ruby

require 'sketchup'
entities = Sketchup.active_model.entities
summa = Hash.new
for face in entities
next unless face.kind_of? Sketchup::Face
if (face.material)
summa[face.material.display_name] += face.area
end
end
I'm trying to get the structure in the array as such:
summa { "Bricks" => 500, "Planks" => 4000 }
By the way, I'm making a ruby script for Google Sketchup
But if I run this code I only get
Error: #<NoMethodError: undefined method `+' for nil:NilClass>
C:\Program Files (x86)\Google\Google SketchUp 7\Plugins\test.rb:17
C:\Program Files (x86)\Google\Google SketchUp 7\Plugins\test.rb:14:in `each'
C:\Program Files (x86)\Google\Google SketchUp 7\Plugins\test.rb:14
C:\Program Files (x86)\Google\Google SketchUp 7\Plugins\test.rb:8:in `call'
As I'm used to using PHP and just doing $array['myownassoc'] += bignumber;
But I guess this isn't the right approach when using Ruby?
So any help in how I need to go would be nice.
The problem is this:
summa[face.material.display_name] += face.area
This is (roughly) equivalent to
summa[face.material.display_name] = summa[face.material.display_name] + face.area
However, you start out with summa as an empty hash:
summa = Hash.new
Which means that whenever you encounter a specific material for the first time (and obviously, this is going to be already the case in the very first iteration of the loop), summa[face.material.display_name] simply doesn't exist. So, you are trying to add a number to something that doesn't exist, which obviously cannot work.
The quick fix would be to just initialize the hash with a default value, so that it returns something useful instead of nil for a non-existing key:
summa = Hash.new(0)
There are, however, a lot of other improvements that could be made to the code. Here's how I would do it:
require 'sketchup'
Sketchup.active_model.entities.grep(Sketchup::Face).select(&:material).
reduce(Hash.new(0)) {|h, face|
h.tap {|h| h[face.material.display_name] += face.area }
}
I find that much easier to read, instead of "loop over this, but skip one iteration if that thing happens, and also don't do this if that happens".
This is actually a common pattern, that pretty much every Rubyist has already written a dozen times, so I actually had a code snippet lying around that I only needed to slightly adapt. However, I am going to show you how I could have refactored your original code step-by-step if I hadn't already had the solution.
First, let's start with coding style. I know it's boring, but it is important. What the actual coding style is, is not important, the important thing is that the code is consistent, which means that one piece of code should look the same as any other piece of code. In this particular instance, you are asking the Ruby community to provide you with unpaid support, so it is polite to at least format the code in a style that members of that community are used to. This means standard Ruby coding style: 2 spaces for indentation, snake_case for method and variable names, CamelCase for constants which refer to modules or classes, ALL_CAPS for constants, and so on. Don't use parentheses unless they clear up the precedence.
In your code, for example, you use sometimes 3 spaces, sometimes 4 spaces, sometimes 5 spaces and sometimes 6 spaces for indentation, and all of that in just 9 non-empty lines of code! Your coding style is not only inconsistent with the rest of the community, it isn't even consistent with its own next line!
Let's fix that first:
require 'sketchup'
entities = Sketchup.active_model.entities
summa = {}
for face in entities
next unless face.kind_of? Sketchup::Face
if face.material
summa[face.material.display_name] += face.area
end
end
Ah, much better.
As I already mentioned, the first thing we need to do, is fix the obvious problem: replace summa = {} (which BTW would be the idiomatic way to write it) with summa = Hash.new(0). Now, the code at least works.
As a next step, I would switch the assignment of the two local variables: first you assign entities, then you assign summa, then you do something with entities and you have to look three lines up to figure out what entities was. If you switch the two, the usage and the assignment of entities are right next to each other.
As a result, we see that entities is assigned, then immediately used and then never used again. I don't think this improves readability much, so we can get rid of it altogether:
for face in Sketchup.active_model.entities
Next comes the for loop. Those are highly un-idiomatic in Ruby; Rubyists strongly prefer internal iterators. So, let's switch to one:
Sketchup.active_model.entities.each {|face|
next unless face.kind_of? Sketchup::Face
if face.material
summa[face.material.display_name] += face.area
end
}
One advantage this has, is that now face is local to the body of the loop, whereas before, it was leaking out into the surrounding scope. (In Ruby, only module bodies, class bodies, method bodies, block bodies and script bodies have their own scope; for and while loop bodies as well as if/unless/case expressions don't.)
Let's get on to the body of the loop.
The first line is a guard clause. That's good, I like guard clauses :-)
The second line is, well, if face.material is true-ish, it does something otherwise it does nothing, which means the loop is over. So, it's another guard clause! However, it is written in a totally different style than the first guard clause, directly one line above it! Again, consistency is important:
Sketchup.active_model.entities.each {|face|
next unless face.kind_of? Sketchup::Face
next unless face.material
summa[face.material.display_name] += face.area
}
Now we have two guard clauses right next to each other. Let's simplify the logic:
Sketchup.active_model.entities.each {|face|
next unless face.kind_of? Sketchup::Face && face.material
summa[face.material.display_name] += face.area
}
But now there is only one single guard clause guarding only one single expression. So, we can just make the whole expression itself conditional:
Sketchup.active_model.entities.each {|face|
summa[face.material.display_name] += face.area if
face.kind_of? Sketchup::Face && face.material
}
However, that's still kind of ugly: we are looping over some collection, and then inside the loop we skip over all the items we don't want to loop over. So, if we don't want to loop over them, we do we loop over them in the first place? We don't we just select the "interesting" items first and then loop over just them?
Sketchup.active_model.entities.select {|e|
e.kind_of? Sketchup::Face && e.material
}.each {|face|
summa[face.material.display_name] += face.area
}
We can do some simplification on this. If we realize that o.kind_of? C is the same as C === o, then we can use the grep filter which uses === to pattern match, instead of select:
Sketchup.active_model.entities.grep(Sketchup::Face).select {|e| e.material
}.each { … }
Our select filter can further be simplified by using Symbol#to_proc:
Sketchup.active_model.entities.grep(Sketchup::Face).select(&:material).each { … }
Now let's get back to the loop. Anybody who has some experience in a higher-order language such as Ruby, JavaScript, Python, C++ STL, C#, Visual Basic.NET, Smalltalk, Lisp, Scheme, Clojure, Haskell, Erlang, F#, Scala, … basically any modern language at all, will immediately recognize this pattern as a catamorphism, reduce, fold, inject:into:, inject or whatever your language of choice happens to call it.
What a reduce does, is basically it "reduces" several things into just one thing. The most obvious example is the sum of a list of numbers: it reduces several numbers into just one number:
[4, 8, 15, 16, 23, 42].reduce(0) {|accumulator, number| accumulator += number }
[Note: in idiomatic Ruby, this would be written just as [4, 8, 15, 16, 23, 42].reduce(:+).]
One way to spot a reduce lurking behind a loop is to look for the following pattern:
accumulator = something # create an accumulator before the loop
collection.each {|element|
# do something with the accumulator
}
# now, accumulator contains the result of what we were looking for
In this case, the accumulator is the summa hash.
Sketchup.active_model.entities.grep(Sketchup::Face).select(&:material).
reduce(Hash.new(0)) {|h, face|
h[face.material.display_name] += face.area
h
}
Last but not least, I don't like this explicit returning of h at the end of block. We could obviously write it on the same line:
h[face.material.display_name] += face.area; h
But I prefer the use of Object#tap (aka the K-combinator) instead:
Sketchup.active_model.entities.grep(Sketchup::Face).select(&:material).
reduce(Hash.new(0)) {|h, face|
h.tap {|h| h[face.material.display_name] += face.area }
}
And, that's it!
summa[face.material.display_name] returns nil by default when face.material.display_name isn't an existing key. When creating a hash, you can specify a different default value to return. Something like:
summa = Hash.new(0)
Just a note on your summary of face areas - you must also take into account of group/components might be scaled so you need make use of the transformations of the whole hierarchy of the groups/components containing the face you inspect. Remember that groups/components can also be skewed - so that has to be taken into account as well.

Code folding on consecutive collect/select/reject/each

I play around with arrays and hashes quite a lot in ruby and end up with some code that looks like this:
sum = two_dimensional_array.select{|i|
i.collect{|j|
j.to_i
}.sum > 5
}.collect{|i|
i.collect{|j|
j ** 2
}.average
}.sum
(Let's all pretend that the above code sample makes sense now...)
The problem is that even though TextMate (my editor of choice) picks up simple {...} or do...end blocks quite easily, it can't figure out (which is understandable since even I can't find a "correct" way to fold the above) where the above blocks start and end to fold them.
How would you fold the above code sample?
PS: considering that it could have 2 levels of folding, I only care about the outer consecutive ones (the blocks with the i)
To be honest, something that convoluted is probably confusing TextMate as much as anyone else who has to maintain it, and that includes you in the future.
Whenever you see something that rolls up into a single value, it's a good case for using Enumerable#inject.
sum = two_dimensional_array.inject(0) do |sum, row|
# Convert row to Fixnum equivalent
row_i = row.collect { |i| i.to_i }
if (row_i.sum > 5)
sum += row_i.collect { |i| i ** 2 }.average
end
sum # Carry through to next inject call
end
What's odd in your example is you're using select to return the full array, allegedly converted using to_i, but in fact Enumerable#select does no such thing, and instead rejects any for which the function returns nil. I'm presuming that's none of your values.
Also depending on how your .average method is implemented, you may want to seed the inject call with 0.0 instead of 0 to use a floating-point value.

Resources