Force to end n if in haml - ruby

I have an if:
-12.times do |control|
-dia += 1
-if control == 1
%a#hoy{:href=>'/dias/algo'}<
-else
%a{:href=>'/dias/algo'}<
=dia
%span=dias[rand(7)]
The problem is I need =dia and span elements inside the anchor tag in both cases (true/false), and when I quit one identation it fails, because haml will end the if (which is also normal).
Is there any way to force end an if? I have tried it in many ways, but couldn't find the right way if it exist.
Thanks.

-12.times do |control|
-dia += 1
%a{:id => control == 1 ? "hoy" : "", :href=>'/dias/algo'}<
=dia
%span=dias[rand(7)]
Didn't test it but it should work ...

Related

Better way to write this code

I am designing a user interface for a menu project. I tried using a for-loop such as:
for i in 0..8
i=i
end
for k in 0..7
k=k
end
if #selection==i && #unlock==k && $switches[(what do I do here?)]==?????
do thing
Whenever the user presses the Y key, it will turn off a function; if #selection==1 is highlighted and the user presses the "Y" key, the corresponding switch at that specific location should be turned off. #unlock is just used as a way of saying that, unless this global boolean is set to true, the user can press "Y" and turn this switch on or off.
First thing, you could change each if else to something like this:
BITMAP_PATH = "Graphics/Pictures/Input Map/switch"
if #selection==1 && #unlock1
pbSEPlay("BW2MenuChoose",65)
bitmap_switch = $switches[310] ? 'off' : 'on' # sets path to off/on
#graphics["switch"].setBitmap(BITMAP_PATH + bitmap_switch)
!$switches[310] # it changes value of boolean to opposite value
end
And the selections that only have one condition could be written like this:
if #selection==0 && #unlock0
pbSEPlay("buzzer",65)
end
You could also try writing a case expression for #selection. Probably you could dry it even more, but I do not really understand what each #unlock is used for.
Edit:
BITMAP_PATH = "Graphics/Pictures/Input/switch"
SELECTION_SWITCHES = [nil, 310, 300, 339, 338, 330, 318]
def pbChangeSwitch
case
when 0
case #selection
when 0,7
pbSEPlay("buzzer",65) if instance_variable_get("#unlock#{#selection}")
when 1..6
if instance_variable_get("#unlock#{#selection}")
pbSEPlay("BW2MenuChoose",65)
bitmap_switch = $switches[SELECTION_SWITCHES[#selection]] ? 'off' : 'on'
#sprites["switch"].setBitmap(BITMAP_PATH + bitmap_switch)
index = SELECTION_SWITCHES[#selection]
$switches[index] = !$switches[index]
end
end
Graphics.update
Please add $ to the last line. bitmap_switch can not be true or false, because you add it to BITMAP_PATH, so it has to be 'off' or 'on'.

For-loop in lua with löve2D, deleting variable

i'm a bit beginner about coding, and my english isn't great, i hope i'll be able to make my question clear:
So I have a for-loop in my code, and 2 if in it, in each if, I see if something is true or false, if it's true, I delete a portion of the loop. like that:
for n=#Test,1, -1 do
if Test[n].delete == true then
table.remove(Test, n )
end
if Test[n].y > 0 then
table.remove(Test, n )
end
end
kind of like that, and my problem is, if the first if make Test[n] being deleted, then the game crash at the next if because Test[n] Doesn't exist anymore. I solved the problem by making 2 for-loop, one for each if.
But I saw someone who did it without 2 for-loop, and it's not crashing, I tried to figure what was wrong but I can't find it.
If someone could find what is wrong with what I wrote, I would be thankful!
So here is the moment that makes problem in my code, on line 9, if the condition are met, i table.remove(ListeTirs, n ), then on line 17, when code try to find it again for test it, it bug :
for n=#ListeTirs,1, -1 do
if ListeTirs[n].Type == "Gentils"
then local nAliens
for nAliens=#ListeAliens,1,-1 do
if
Collide(ListeTirs[n], ListeAliens[nAliens]) == true
then
ListeTirs[n].Supprime = true
table.remove(ListeTirs, n )
ListeAliens[nAliens].Supprime = true
table.remove(ListeAliens, nAliens)
end
end
end
if
ListeTirs[n].y < 0 - ListeTirs[n].HauteurMoitie or ListeTirs[n].y > Hauteur + ListeTirs[n].HauteurMoitie or ListeTirs[n].x > Largeur + ListeTirs[n].LargeurMoitie or ListeTirs[n].x < 0 - ListeTirs[n].LargeurMoitie
then
ListeTirs[n].Supprime = true
table.remove(ListeTirs, n)
end
end
I hope it's clear, I could post the whole code but I don't feel it's necessary, if it is, I will add it.
Thank you :)
for n=#Test,1, -1 do
local should_be_removed
-- just mark for deletion
if Test[n].delete = true then
should_be_removed = true
end
-- just mark for deletion
if Test[n].y > 0 then
should_be_removed = true
end
-- actually delete (at the very end of the loop body)
if should_be_removed then
table.remove(Test, n )
end
end

Why does that loop sometimes click randomly on screen?

I have made that loop my self and Iam trying to make it faster, better... but sometimes after it repeat searching for existing... it press random ( i think cuz its not similar to any img iam using in sikuli ) place on the screen. Maybe you will know why.
Part of this loop below
while surowiec_1:
if exists("1451060448708.png", 1) or exists("1451061746632.png", 1):
foo = [w_lewo, w_prawo, w_dol, w_gore]
randomListElement = foo[random.randint(0,len(foo)-1)]
click(randomListElement)
wait(3)
else:
if exists("1450930340868.png", 1 ):
click(hemp)
wait(1)
hemp = exists("1450930340868.png", 1)
elif exists("1451086210167.png", 1):
click(tree)
wait(1)
tree = exists("1451086210167.png", 1)
elif exists("1451022614047.png", 1 ):
hover("1451022614047.png")
click(flower)
flower = exists("1451022614047.png", 1)
elif exists("1451021823366.png", 1 ):
click(fish)
fish = exists("1451021823366.png")
elif exists("1451022083851.png", 1 ):
click(bigfish)
bigfish = exists("1451022083851.png", 1)
else:
foo = [w_lewo, w_prawo, w_dol, w_gore]
randomListElement = foo[random.randint(0,len(foo)-1)]
click(randomListElement)
wait(3)
I wonder if this is just program problem with img recognitions or I have made a mistake.
You call twice the exist method indending to get the same match (the first one in your if statement, the second time to assign it to the value. You ask sikuli to evaluate the image twice, and it can have different results.
From the method's documentation
the best match can be accessed using Region.getLastMatch() afterwards.

Cucumber and variables internal to methods called indirectly

Please note: I am new to TDD & cucumber, so the answer may be very easy.
I am creating a basic image editor for a test (the image is just a sequence of letters).
I have written a Cucumber story:
Scenario Outline: edit commands
Given I start the editor
And a 3 x 3 image is created
When I type the command <command>
Then the image should look like <image>
The step
Scenarios: colour single pixel
| command | image |
| L 1 2 C | OOOCOOOOO |
always fails, returning
expected: "OOOCOOOOO"
got: " OOOOOOOO" (using ==) (RSpec::Expectations::ExpectationNotMetError)
This is the step code:
When /^I type the command (.*)$/ do |command|
#editor.exec_cmd(command).should be
end
The function exec_cmd in the program recognizes the command and launches the appropriate action. In this case it will launch the following
def colorize_pixel(x, y, color)
if !#image.nil?
x = x.to_i
y = y.to_i
pos = (y - 1) * #image[:columns] + x
#image[:content].insert(pos, color).slice!(pos - 1)
else
#messenger.puts "There's no image. Create one first!"
end
end
However, this always fails unless I hardcode the values of the two local variables (pos and color) in the function in the program itself.
Why? It doesn's seem I'm doing anything wrong in the program itself: the function does what it's supposed to do and those two variables are only useful locally. So I'd think this is a problem with my use of cucumber. How do I properly test this?
---edit---
def exec_cmd(cmd = nil)
if !cmd.nil?
case cmd.split.first
when "I" then create_image(cmd[1], cmd[2])
when "S" then show_image
when "C" then clear_table
when "L" then colorize_pixel(cmd[1], cmd[2], cmd[3])
else
#messenger.puts "Incorrect command. " + "Commands available: I C L V H F S X."
end
else
#messenger.puts "Please enter a command."
end
end
When /^I type the command (.*)$/ do |command|
#output = #editor.exec_cmd(command)
end
Then /^the image should look like (.)*$/ do |expected_image|
#output.should == expected_image
end
Hope this may help you.
It's not a cucumber issue.
The problem was that, in exec_cmd, split was called only in the "case" clause, not in the "when"s. This meant that, since the command's format was "a 1 2 b", cmd[1] in the "when" would call the second character of the string, a space, not the second value of the array, and the other functions would convert that to_i, returning 0.
I changed exec_cmd like this:
def exec_cmd(cmd = nil)
if !cmd.nil?
cmd = cmd.split
case cmd.first
when "I" then create_image(cmd[1], cmd[2])
[...]
end
which fixed the issue.

Could I do this blind relative to absolute path conversion (for perforce depot paths) better?

I need to "blindly" (i.e. without access to the filesystem, in this case the source control server) convert some relative paths to absolute paths. So I'm playing with dotdots and indices. For those that are curious I have a log file produced by someone else's tool that sometimes outputs relative paths, and for performance reasons I don't want to access the source control server where the paths are located to check if they're valid and more easily convert them to their absolute path equivalents.
I've gone through a number of (probably foolish) iterations trying to get it to work - mostly a few variations of iterating over the array of folders and trying delete_at(index) and delete_at(index-1) but my index kept incrementing while I was deleting elements of the array out from under myself, which didn't work for cases with multiple dotdots. Any tips on improving it in general or specifically the lack of non-consecutive dotdot support would be welcome.
Currently this is working with my limited examples, but I think it could be improved. It can't handle non-consecutive '..' directories, and I am probably doing a lot of wasteful (and error-prone) things that I probably don't need to do because I'm a bit of a hack.
I've found a lot of examples of converting other types of relative paths using other languages, but none of them seemed to fit my situation.
These are my example paths that I need to convert, from:
//depot/foo/../bar/single.c
//depot/foo/docs/../../other/double.c
//depot/foo/usr/bin/../../../else/more/triple.c
to:
//depot/bar/single.c
//depot/other/double.c
//depot/else/more/triple.c
And my script:
begin
paths = File.open(ARGV[0]).readlines
puts(paths)
new_paths = Array.new
paths.each { |path|
folders = path.split('/')
if ( folders.include?('..') )
num_dotdots = 0
first_dotdot = folders.index('..')
last_dotdot = folders.rindex('..')
folders.each { |item|
if ( item == '..' )
num_dotdots += 1
end
}
if ( first_dotdot and ( num_dotdots > 0 ) ) # this might be redundant?
folders.slice!(first_dotdot - num_dotdots..last_dotdot) # dependent on consecutive dotdots only
end
end
folders.map! { |elem|
if ( elem !~ /\n/ )
elem = elem + '/'
else
elem = elem
end
}
new_paths << folders.to_s
}
puts(new_paths)
end
Let's not reinvent the wheel... File.expand_path does that for you:
[
'//depot/foo/../bar/single.c',
'//depot/foo/docs/../../other/double.c',
'//depot/foo/usr/bin/../../../else/more/triple.c'
].map {|p| File.expand_path(p) }
# ==> ["//depot/bar/single.c", "//depot/other/double.c", "//depot/else/more/triple.c"]
Why not just use File.expand_path:
irb(main):001:0> File.expand_path("//depot/foo/../bar/single.c")
=> "//depot/bar/single.c"
irb(main):002:0> File.expand_path("//depot/foo/docs/../../other/double.c")
=> "//depot/other/double.c"
irb(main):003:0> File.expand_path("//depot/foo/usr/bin/../../../else/more/triple.c")
=> "//depot/else/more/triple.c"
For a DIY solution using Arrays, this comes to mind (also works for your examples):
absolute = []
relative = "//depot/foo/usr/bin/../../../else/more/triple.c".split('/')
relative.each { |d| if d == '..' then absolute.pop else absolute.push(d) end }
puts absolute.join('/')
Python code:
paths = ['//depot/foo/../bar/single.c',
'//depot/foo/docs/../../other/double.c',
'//depot/foo/usr/bin/../../../else/more/triple.c']
def convert_path(path):
result = []
for item in path.split('/'):
if item == '..':
result.pop()
else:
result.append(item)
return '/'.join(result)
for path in paths:
print convert_path(path)
prints:
//depot/bar/single.c
//depot/other/double.c
//depot/else/more/triple.c
You can use the same algorithm in Ruby.

Resources