How to keep panning only if id exists? - ruby

I'm trying to pan through a list of elements to confirm that the set minimum number of elements is there on the screen. The problem I'm running into is that 'pan' will keep going and the test will pass even if I set the minimum to a high number (greater than what's actually there on the page).
When /^I swipe through my list of chat suggestion cards I should see the minimum$/ do
i = 0
while i < 12
i += 1
wait_for_element_exists("* id:'itemContainer'")
pan("* id:'itemContainer'", :left)
end
end
Is there anyway to check if the number of id: 'itemContainer' is actually there, to make it fail if the minimum number doesn't exist?

Query will only return the elements that are currently on the screen, so you will have to swipe across to make all of the cards visible to calabash and check for them. Assuming that query("* id:'itemContainer'") would only find one at a time, i.e. the cards are a whole screen in size,
12.times do
card_before_panning = query("* id:'itemContainer'")
pan("* id:'itemContainer'", :left)
card_after_panning = query("* id:'itemContainer'")
assert_not_equal card_before_panning, card_after_panning
end
If more than one of the cards can be visible on the screen at a time then you will have to do an additional check. Assuming that there could be two visible at the time
11.times do
card_before_panning = query("* id:'itemContainer' index:0")
pan("* id:'itemContainer'", :left)
card_after_panning = query("* id:'itemContainer' index:0")
assert_not_equal card_before_panning, card_after_panning
end
# Then check that there are two visible on the final screen.
assert_equal 2, query("* id:'itemContainer'").size
Note that this will only work if the cards appear differently in your app, i.e. they have different content. If query("* id:'itemContainer'") has identical results for each of the cards then calabash will not be able to tell them apart to see if anything has changed.

Related

Create Buttons and it's signals dynamically in Ruby GTK

i'm trying to make a Nurikabe puzzle with Ruby GTK and i'm having trouble creating button signals dynamically.
Basically, i have a matrix, some boxes have a number ( clicking them won't do anything), others can have one of 3 states (white, black or unplayed). The matrix can have different sizes so i did this :
def construction
# we get the width and height of the matrix
taille_hauteur = ##partie.grilleEnCours.hauteur
taille_largeur = ##partie.grilleEnCours.largeur
#boutons = {}
#We create a table which will include all of our buttons (one for each box of our matrix)
table = Table.new(taille_hauteur,taille_largeur,false)
# we go through our matrix
for i in 0..taille_largeur-1
for j in 0..taille_hauteur-1
# if the box has a number, we create a button with that number as a label
if ##partie.grilleEnCours.matriceCases[i][j].is_a?(CaseNombre)
# we add this button to a hash
#boutons[[i,j]] = Button.new(:label=> ##partie.grilleEnCours.matriceCases[i][j].to_s)
table.attach(#boutons[[i,j]], i, i+1, j, j+1)
else
# otherwise,we create and add a button to the hash without a label
#boutons[[i,j]] = Button.new()
# we create a signal, changing the state of the box of the matrix at the same coordinates as the button
#boutons[[i,j]].signal_connect('clicked'){
puts "#{i} #{j}"
# we change the box's state of the matrix
##partie.clicSurCase(i,j)
puts ##partie.grilleEnCours
# here we are just changing the label corresponding to the box's state
if(##partie.grilleEnCours.matriceCases[i][j].etat==0)
lab = ""
elsif (##partie.grilleEnCours.matriceCases[i][j].etat==1)
lab = "Noir"
else
lab = "Point"
end
#boutons[[i,j]].set_label(lab)
}
table.attach(#boutons[[i,j]], i, i+1, j, j+1)
end
end
end
#object.add(table)
end
The problem is, doing this, when we click any button, it will change the last box of the matrix and the last button's label (bottom right). I believe this is because Integers are objects in Ruby so clicking a button will change the box's state and button's state at the coordinates (i,j) (which are matrix height-1, matrix width-1) and not the values i and j had when we created the signal.
I have no idea how to link a button to a specific box of the matrix (knowing matrixes can have multiple sizes), could you help me on this one ?
It is quite hard to read such a large block of code - maybe start by chopping it into logic-based functions?
It will clear the code up.
you don't need to set "lab =" in each branch of if - just:
lab = if (i==1)
1
else
2
end
in additions - use "case" in this case. Once you split the code up - you will(probably) find the issue you have.
it will be easier to debbug.

Create PySimpleGUI list with a key

I wish to have a list of text items in a PySimpleGUI that I can update later. That is, I want to have a key for the list. This might be vertical or horizontal, and I do not know how many items there will be.
I end up with different use cases, but the current one is to make a single line of text items with different colors. Other times, I need to write and update a customized table, just different enough that the table widget does not work.
Conceptually, I want to do something like this:
layout = [ [sg.T('Titles and Things')], sg.ListThing(key='-data-', [[]]) ]
so that I can:
window['-data-'].update(values=[ [sg.T(v, color=c)] for (v,c) in my_data ])
Another, invalid syntax, way of saying what I want is to use [key="-data-", sg.T('Item1'), sg.T('Item2')].
Is this possible?
You can update individual layout elements but you cannot dynamically change the layout itself.
It is possible to create 2 or more elements, whereby only one of them is visible, and switch them later as needed. Or you can close and re-create the window with another layout. Or combine both approaches.
An example of switching layouts:
def change_layout():
left_col_1 = sg.Column([[sg.Text(f'Text {i}') for i in range(4)]], visible=True, key='col_1')
left_col_2 = sg.Column([[sg.Text(f'Text {i}')] for i in range(6)], visible=False, key='col_2')
visible_1 = True
layout = [[sg.Column([[left_col_1, left_col_2]]), sg.Button('Change layout', key='change')]]
window = sg.Window('window', layout=layout, finalize=True)
while True:
event, values = window.read()
print(event)
print(values)
print(visible_1)
if event in ('Exit', sg.WIN_CLOSED):
break
if event == 'change':
window['col_1'].update(visible=not visible_1)
window['col_2'].update(visible=visible_1)
visible_1 = not visible_1
Please notice that the alternative layouts for the left part (left_col_1, left_col_2) need to be enclosed in a container (column, frame) to keep their position in the window in the moment they are invisible.

Trouble building tree for possible chess piece movements

I'm building a chess game that takes a start coordinate and end coordinate and builds a tree using BFS. I have two methods to find possible moves.
The #find_possible_positions_from_origin method logs every single possible square that chess piece can end up (for example a rook can end up either, north up to 7 spaces, south up to 7 spaces, left up to 7 spaces, and right up to 7 spaces. If the end coordinate ends up BEING one of these coordinates from #find_possible_positions_from_origin, it then runs another method directly under it #find_possible_incremental_moves that traverses every single one of these spaces by only 1 space at a time - the reason being so that it can check if each space is empty, and not just hop over another piece. It creates a "cell" on each of these spaces so that it can log the path to destination. Each cell remembers the path to it from the starting coordinate.
I'm having trouble getting the second variable #find_possible_incremental_moves run smoothly under the #find_possible_positions_from_origin method. A "cell" is supposed to be created at the destination coordinate of the board, so that I can have the path to it, and check if the path is occupied by any other pieces. But when I call the destination coordinate, I get nil.
Someone corrected me on a previous question that I shouldn't post my entire production code which makes sense, so I included the single #build_tree that I'm having trouble with I hope that's enough.
Here is my code that have for this section.
def build_tree
#start_coor = convert_input_to_coor(#start)
#destination_coor = convert_input_to_coor(#destination)
#selected_piece = #gameboard[#start_coor[0]][#start_coor[1]]
starting_cell = Cell.new(#start_coor[0], #start_coor[1])
queue = []
queue.unshift(starting_cell)
until queue.empty?
current = queue.shift
possible_positions = find_possible_positions_from_origin([current.x, current.y])
next if possible_positions.nil?
if possible_positions.include?(#destination_coor)
#selected_piece.possible_positions = find_possible_incremental_moves(([current.x, current.y]))
#selected_piece.possible_positions.each do |move|
next unless !#dummyboard.board[move[0]][move[1]].instance_of? Cell
linked_cell = Cell.new(move[0], move[1])
current.edges << linked_cell
linked_cell.path = current.path + linked_cell.path
#dummyboard.board[move[0]][move[1]] = linked_cell
queue.push(linked_cell)
end
end
end
starting_cell
end

Dividing by half in ruby to create an effective calculator

For the past while I've been working on a calculator, but have run into problems when needing to divide by a half. I'll add the offending bit of code along with a loop to keep it open below.
on = true
while on == true do
half = 1.0 / 2.0
puts ("FUNCTION IN TESTING MODE, DO NOT EXPECT IT TO FUNCTION PROPERLY")
puts ("Area of a triangle")
print("What is the legnth of the base? ").to_i
base = gets.chomp("base")
print("\nWhat is the height? ")
height = gets.chomp("height").to_i
PreAreaT = base * height
AreaT = PreAreaT * half
puts("The area of the triangle is #{AreaT}")
end
So essentially, how on Earth do I get the program to display an answer, rather than outputting nothing for the answer?
EDIT:As it would turn out the code above is improperly done. I've spent nearly two weeks asking myself why it wouldn't work only to find I had .to_i after a print statement rather than the input.
Your to_i call is switched around here.
print("What is the legnth of the base? ").to_i
base = gets.chomp("base")
Should be the other way 'round.
print("What is the length of the base? ")
base = gets.chomp("base").to_i
Further, chomp will attempt to remove any occurrences of base or height from the string. Be sure that you're intention is to remove those occurrences; if you want to remove whitespace, you'll have to take a different approach.

Dynamic refresh in a view - xcode 4 / interface builder

I'm new to xcode so please bear with me.
I have a label that I have set to blank, and after a user clicks 'go' I generate a random word or number and use:
self.label.stringValue = "some_word"
to update the view. (I am using MacRuby btw)
However, I would like to show 20 or so random words in quick succession before the last one is shown - just because it's too boring at the moment. (Alternatively, I'd be happy with showing an animated graphic in its place - which is replaced by the final random word.)
I've tried things like:
100.times do
num = rand(40)
self.label.stringValue = num
end
But it doesn't work. I've also tried .reloadData but to no avail as well.
Any ideas on how to achieve this?
So as not to leave the question haning, from the Macruby mailing list:
def drawWord(sender)
if !next_word
self.timer.invalidate
return
end
self.label.stringValue = next_word
self.setNeedsDisplay true
end
def next_word
...
end
self.timer = NSTimer.scheduledTimerWithTimeInterval( 1/20.0,
target:self, selector:"drawWord:", userInfo:nil, repeats:true)

Resources