Very nice Halloween icon...
Tuesday, October 31, 2006
Wednesday, October 25, 2006
Niceboxes (latex)
You can define things like
\usepackage{niceboxes}
\newenvironment{definition}[1][Definition]{
\par
\SpecialEnv{#1}{LightSlateGrey}{Lavender}{LightSlateGrey}{}%
}{%
\endSpecialEnv
}
Of course you need to have imported xcolors if you want to call colors by name (like LightSlateGrey)
Latex Companion
And eventually from Amazon arrived the Latex Companion...
I leafed through it and have to say it seems a wonderful book. There's plenty of information (in my opinion more than other book on Latex like the "Guide to latex" or Lamport's book -- that seems more suited to a beginner latex user).
In fact I was spending too much time on the web to look for information on intermediate or advanced tasks, and I was also thinking to abandon latex in favor of something else (by the way, I didn't find a true candidate, a part from docbook). Thanks to Andrea Bergia (I didn't find his proper blog/website) for pointing me the listings package that solving one of my immediate problems made me understand that it wasn't latex not being suited for what I had to do: it was me who needed to learn more latex.
Monday, October 9, 2006
Monday, September 11, 2006
Rails: Loading fixtures to development with a specified order
My development style is heavily test driven. One of the very first things I do write are fixtures, in order to write tests on them. For this reason the very first database I use in a Rails projects is the test database, rather than the development one.
When I have to populate the development db, I already have plenty of fixtures: if they aren't enough to try the user interface (that is what is left to do), they weren't enough to test the models and the controllers.
Of course this should be no problem, there is the rake task db:load:fixtures that plays well with this kind of issues. However, I tend to use db constraints rules such as
ALTER TABLE bars ADD FOREIGN KEY(`foo_id`) REFERENCES foos (`id`) ON DELETE CASCADE;if you use MySQL or
ALTER TABLE bars ADD CONSTRAINT valid_foo FOREIGN KEY (foo_id) REFERENCES foos (id) MATCH FULL;if you use Postgres.
Solution
Of course, in this case you can't load fixtures in any order and you must supply correct fixtures loading order.
After some searching I found this solution.
However, it does not work. In fact it builds a Hash inserting fixture names in the specified order, than builds an array with other fixtures that had not been specified as needing some particular order.
Eventually, it sums the keys of the hash and the array, and loads fixtures in this order. I don't understand how the poster got this code working, since Ruby Hashes are not ordered in any way and the documentation explicitly says that iterators and methods return values in arbitrary order and do not rely on insertion order.
This meant I had to change the code. Now it uses arrays everywhere (which seems the most reasonable thing to do, since this rake task it's about order). I also added namespaces.
You still have to define something like
ENV["FIXTURE_ORDER"] =
%w( entities interaction_sources interaction_devices
payments interactions accounts employments
enrollments payables receivables tenures wards ).join(' ')
My code is:
require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
ENV["FIXTURE_ORDER"] ||= ""
def print_separator_line(n=80)
puts "\n" + '='*n
end
desc "Load fixtures into #{ENV['RAILS_ENV']} database"
namespace :db do
namespace :fixtures do
task :load_ordered => :environment do
require 'active_record/fixtures'
print_separator_line
puts "Collecting specified ordered fixtures\n"
ordered_fixtures = ENV["FIXTURE_ORDER"].split
fixture_files = Dir.glob(
File.join(RAILS_ROOT, 'test', 'fixtures', '*.{yml,csv}'))
other_fixtures = fixture_files.collect
{ |file| File.basename(file, '.*') }.reject
{|fx| ordered_fixtures.include? fx }
ActiveRecord::Base.establish_connection(ENV['RAILS_ENV'])
all_fixtures = ordered_fixtures + other_fixtures
print_separator_line
puts "Fixtures will be loaded in following order\n"
all_fixtures.each_with_index do |fx, i|
puts "#{i+1}. #{fx}"
end
print_separator_line
puts "Actually loading fixtures to #{ENV['RAILS_ENV']} db..."
all_fixtures.each do |fixture|
puts "Loading #{fixture}..."
Fixtures.create_fixtures('test/fixtures', fixture)
end unless :environment == 'production'
# You really don't want to load your *fixtures*
# into your production database, do you?
end
end
end
Thursday, August 24, 2006
RealBasic loops, arrays and MemoryBlocks
I wrote a test function that makes various speed-checks. The number Ireport are in Rosetta emulation, but it does not matter, since they are"good enough" and the point is not to bench RB against other "native"languages, but to test RB against itself.However, running in Windows gaves about a 2x improvement respect toRosetta code.
All loops involve 1000000(10e6) iterations (double loop make 1000 * 1000iterations). I also tried with 10000000 (10e7) iterations and it tookabout 10 times more than the 1000000(10e6) iteration. That is to saybechmarks are linear with number of elements (as expected). I didn't trybigger values as it involved paging, thus making quite useless the test.
The first one is a void loop. It takes 0.09 seconds on my MacIntel. Then I made a double void loop. It takes the same time. That is to sayusing two nested for does not take more time.
Then I made a simple loop that copies a variable into another variable.This runs in 0.17 seconds. Good.The third loop puts in the variable array elements. 0.17 seconds. Thesame. So arrays are well optimized: accessing an element of an arraytakes the very same time than accessing a single variable.
I then tried using two dimensional arrays: we get to 0.22 seconds. Sothis is slower, but not a *lot* slower (even if for large objects this+33% can make the difference).
And then memory blocks. I was surprised: 0.3 seconds. It seems thatusing memory blocks is slower than using arrays (and in fact there is arationale behind this: a lot of people use arrays to store large amountsof data, they *must* be ultra optimized. I think that MemoryBlocks areused more often in a different fashion).
#pragma DisableBackgroundTasks
#pragma DisableBoundsChecking
Const LoopSize = 1000000
Const SmallerLoop = 1000
Dim void_start, void_end, arr_start, arr_end As Double
Dim var_start, var_end, mat_start, mat_end As Double
Dim block_start, block_end, dvoid_start, dvoid_end As Double
Dim var As Double
Dim value As Double = 1.0
Dim arr(LoopSize) As Double
Dim mat(SmallerLoop, SmallerLoop) As Double
Dim block As MemoryBlock
for i As Integer = 0 to UBound(arr)
arr(i) = value
next
for i As Integer = 0 to SmallerLoop
for j As Integer = 0 to SmallerLoop
mat(i, j) = 1.0
next
next
block = NewMemoryBlock(LoopSize * 8)
for i As Integer = 0 To (LoopSize-1) * 8 Step 8
block.DoubleValue(i) = 1.0
next
void_start = Microseconds()
for i As Integer = 0 to LoopSize
next
void_end = Microseconds()
MsgBox "Void loop(" + Str(LoopSize) + "): " + Str((void_end - void_start)/1000000)
dvoid_start = Microseconds()
for i As Integer = 0 to SmallerLoop
for j As Integer = 0 to SmallerLoop
next
next
dvoid_end = Microseconds()
MsgBox "Double void loop(" + Str(LoopSize) + "): " + Str((dvoid_end - dvoid_start)/1000000)
var_start = Microseconds()
for i As Integer = 0 to LoopSize
var = value
next
var_end = Microseconds()
MsgBox "Var loop(" + Str(LoopSize) + "): " + Str((var_end - var_start)/1000000)
arr_start = Microseconds()
for i As Integer = 0 to LoopSize
var = value
next
arr_end = Microseconds()
MsgBox "Arr loop(" + Str(LoopSize) + "): " + Str((arr_end - arr_start)/1000000)
mat_start = Microseconds()
for i As Integer = 0 to SmallerLoop
for j As Integer = 0 to SmallerLoop
var = mat(i, j)
next
next
mat_end = Microseconds()
MsgBox "Mat loop(" + Str(LoopSize) + "): " + Str((mat_end - mat_start)/1000000)
block_start = Microseconds()
for i As Integer = 0 To (LoopSize-1) * 8 Step 8
var = block.DoubleValue(i)
next
block_end = Microseconds()
MsgBox "Block loop(" + Str(LoopSize) + "): " + Str((block_end - block_start)/1000000)
block_start = Microseconds()
for i As Integer = 0 To (LoopSize-1)
var = block.DoubleValue(i*8)
next
block_end = Microseconds()
MsgBox "Block loop(" + Str(LoopSize) + "): " + Str((block_end - block_start)/1000000)
Saturday, June 24, 2006
Ruby on Rails: make LoginEngine fixtures dynamic
admin: id: 1 login: admin salted_password: salt: email: admin@company.com verified: 1This way you always generate fixtures that behave correctly according to your salt and such. Otherwise I had problems when doing "rake load_fixture" in the development db (the login failed).
Thursday, June 22, 2006
Rendering a chosen RJS
respond_to do |wants|
wants.html {render :partial=>"post", :object=>@post, :layout=>'posts'}
wants.js {render :action=>"remote_show"}
end
Although this is pretty obvious if you reason about it, you may need some time to get it. And on the net there aren't easily accessible examples about it (or at least I found none).It's just a dirty trick.
Wednesday, June 21, 2006
Pattern Matching in Ruby
func :qsort, [] { [] }
func :qsort do | list |
qsort( list.select {|a| a < list[0]} ) +
list.select {|a| a == list[0]} +
qsort( list.select {|a| a > list[0]} )
end
and if I find time it could become even some kind of "declarative like" unification algorithm... who knows. The point is I don't even know if I have enough time for the "toy" pattern matching.
[from the future: I did not find time!]
Wednesday, June 14, 2006
RJS Rails If statement
page.replace_html 'non_existent', 'some text'
you get a Javascript error and sequent lines are not processed. The first idea to solve this problem would be:
if page['not_valid']
page.replace_html 'not_valid', 'some text'
end
However, you don't get what you meant. Not at all. This is translated to
$("not_valid")
Element.update("not_valid", "some text");
The best way I found do express that meaning is
page.select('not_valid').each do |unique|
page.replace_html unique, 'some text'
end
That works.