I am attempting to print out tables using the Text widget. I have created a method for doing this by using labels and frames, but the problem is that I will need to present larger tables to the point where I will need to use a scroll bar.
I am using tabs to make a table for the text widget, and it works well, but I can't seem to figure out a way to set the width of the widget to fit the text. I'm attempting to do it with the get_width() method below, but it doesn't always work.
The width option is measured in average sized characters for the font, but the problem is that the size of a tab 'character' varies. The way the tab key works for the text widget is different than the print() functions for a terminal or text file.
Here is my code below:
from tkinter import *
import math
class App(Text):
def __init__(self, matrix, parent, **kwargs):
Text.__init__(self, parent, **kwargs)
self.parent = parent
self.matrix = matrix
temp = []
for row in matrix:
temp.append(len(row))
# Making sure all the rows are of equal length and string values...
for row in matrix:
for _ in range(max(temp) - len(row)):
row.append('')
matrix = [[str(matrix[r][c]) for c in range(len(matrix[0]))] for r in range(len(matrix))]
# I need to get the maximum length for each column in the matrix...
c_lengths = {}
for c in range(len(matrix[0])):
c_lengths.update({c: []})
for r in range(len(matrix)):
c_lengths[c].append(len(matrix[r][c]))
self.tab_list = []
for r in range(len(matrix)):
temp = []
for c in range(len(matrix[0])):
if c != len(matrix[0]) - 1:
tab_count = (math.floor(max(c_lengths[c])/8)+1)
'''if (tab_count + max(c_lengths[c])) % 8 == 0:
tab_count += 1'''
temp.append(tab_count)
tabs = ['\t'] * tab_count
string = matrix[r][c] + ''.join(tabs)
else:
string = matrix[r][c]
self.insert(END, string)
self.tab_list.append(sum(temp))
self.insert(END, '\n')
self.configure(state=DISABLED, wrap=NONE, width=self.get_width())
def get_width(self):
temp = []
for row in self.matrix:
temp.append(len(''.join(row)))
return max(temp) + max(self.tab_list)*4
if __name__ == '__main__':
import random
root = Tk()
root.state('zoomed')
m = [['0' for _ in range(5)] for _ in range(40)]
for i in range(40):
for j in range(5):
m[i][j] = '*' * random.randint(1, 25)
App(m, root, font=('Times', '12'), height=40).pack()
root.mainloop()
Here is the output:
This run worked out good, but sometimes it cuts off some of the table.
from tkinter import *
import math
class App(Text):
def __init__(self, matrix, parent, **kwargs):
Text.__init__(self, parent, **kwargs)
self.parent = parent
self.matrix = matrix
temp = []
for row in matrix:
temp.append(len(row))
# Making sure all the rows are of equal length and string values...
for row in matrix:
for _ in range(max(temp) - len(row)):
row.append('')
matrix = [[str(matrix[r][c]) for c in range(len(matrix[0]))] for r in range(len(matrix))]
# I need to get the maximum length for each column in the matrix...
c_lengths = {}
for c in range(len(matrix[0])):
c_lengths.update({c: []})
for r in range(len(matrix)):
c_lengths[c].append(len(matrix[r][c]))
self.tab_list = []
for r in range(len(matrix)):
temp = []
for c in range(len(matrix[0])):
if c != len(matrix[0]) - 1:
tab_count = (math.floor(max(c_lengths[c])/8)+1)
'''if (tab_count + max(c_lengths[c])) % 8 == 0:
tab_count += 1'''
temp.append(tab_count)
tabs = ['\t'] * tab_count
string = matrix[r][c] + ''.join(tabs)
else:
string = matrix[r][c]
self.insert(END, string)
self.tab_list.append(sum(temp))
self.insert(END, '\n')
self.configure(state=DISABLED, wrap=NONE, width=self.getWidth())
def getWidth(self):
lst = []
for x in range(int(self.index('end-1c').split('.')[0])):
lst.append(len(self.get(f'end-{x} lines linestart', f'end-{x} lines lineend')))
return max(lst)+52
if __name__ == '__main__':
import random
root = Tk()
root.state('zoomed')
m = [['0' for _ in range(5)] for _ in range(40)]
for i in range(40):
for j in range(5):
m[i][j] = '*' * random.randint(1, 25)
App(m, root, font=('Times', '12'), height=40).pack()
root.mainloop()
Explaination:
self.get(f'end-{x} lines linestart', f'end-{x} lines lineend') here get(index1, index2) method is used to get characters between index1 and index2.
You can read what linestart and lineend parameter does here
end-x x goes from 0 to the last line, so end-1 is the last before line and so on. So all end-{x} lines linestart gets the starting index of each line and end-{x} lines lineend get the last index of the same line.
update:
Op your get_width:
def get_width(self):
temp = []
for row in self.matrix:
temp.append(len(''.join(row)))
return max(temp) + max(self.tab_list)*4
is the same as
def getWidth(self):
lst = []
spaces = []
for x in range(int(self.index('end-1c').split('.')[0])+1):
spaces = len([x for x in self.get(f'end-{x} lines linestart', f'end-{x} lines lineend') if x=='\t'])
lst.append(len(self.get(f'end-{x} lines linestart', f'end-{x} lines lineend'))+spaces*4)
return max(lst)
not much difference.
I also found out that the tabs are inconsistent I am not entirely sure of the reason. Setting self['tabs'] = '2c' gives more consistency you might want to check out more it here
Related
I have created a GUI where you can enter values (x values) manually. If you enter a value x1, trace-method will automatically calculate
f(x1)=x1^2=y1 and mean(y) = (1/5 sum_{i=1}^{5} y_i)
So every time an x-value is entered, the corresponding y-value and mean(y) is calculated. The code below works. If you start it you get:
I would like to remove the initial values 0.0 from some cells. The window should look like this when the code is executed:
To get the desired result, I added at the very end before mainloop()
for i in range(1,5):
y_values[i].set("")
cells[(i,0)].delete(0,END)
where i remove the initial values of certain cells. If you start the code with this change, the program will not work properly anymore. If you enter an x-value, only the corresponding y-value is calculated, but not mean(y).
Do any of you know why the code with y_values[i].set(""), cells[(i,0)].delete(0,END) no longer works correctly and how to solve this problem?
Here is the full Code (from picture 1):
from tkinter import *
import tkinter as tk
root = Tk()
Label(root, text = "x-values",padx = 10).grid(row = 0, column = 0)
Label(root, text = "y-values",padx = 10).grid(row = 0, column = 1)
Label(root, text = "Mean y", padx = 10).grid(row = 0, column = 2)
# Create Variables
x_values, y_values = ["x%d" % x for x in range(5)], ["y%d" % x for x in range(5)]
for i in range (5):
x_values[i], y_values[i] = DoubleVar(), DoubleVar()
mean = DoubleVar()
# Create Table
rows, columns, cells = 5, 2, {}
for i in range(columns):
for j in range(rows):
if i == 0: # x-values that can be entered
b = Entry(root, textvariable=x_values[j])
b.grid(row = j+1, column = i, sticky = W + E)
cells[(j,i)] = b
else: # y-values that are computed by f
b = Label(root, textvariable=y_values[j])
b.grid(row = j+1, column = i, sticky = W + E)
cells[(j,i)] = b
label_mean = Label(root, textvariable = mean).grid(row = 1, column = 2, rowspan = 5)
# compute y-values
def f(name, index, mode):
try:
for i in range(5):
y_values[i].set(x_values[i].get()**2)
except tk.TclError:
pass
# compute mean and standard deviation
def statistic(name, index, mode):
try:
y_sum = 0
for i in range(5):
y_sum += y_values[i].get()
y_normalized = y_sum / 5
mean.set(y_normalized)
except tk.TclError:
pass
# Traces to trigger the above functions
for i in range(5):
x_values[i].trace('w', f)
y_values[i].trace('w', statistic)
mainloop()
Mean is not calculating because it is raising exception when you tried to add None value to y_sum. Add try block in your statistics function.
def statistic(name, index, mode):
try:
y_sum = 0
for i in range(5):
try:
y_sum += y_values[i].get()
except:
pass
y_normalized = y_sum / 5
mean.set(y_normalized)
except tk.TclError:
pass
My code dies after about 140+ iterations, and I don't know why. I guess memory leak is a possibility, but I couldn't find it. I also found out that changing some arithmetic constants can prolong the time until the crash.
I have a genetic algorithm that tries to find best (i.e. minimal steps) route from point A (src) to point B (dst).
I create a list of random chromosomes, where each chromosome has:
src + dst [always the same]
list of directions (random)
I then run the algorithm:
find best route and draw it (for visualization purposes)
Given a probability P - replace the chromosomes with cross-overs (i.e. pick 2, and take the "end" of one's directions, and replace the "end" of the second's)
Given probability Q - mutate (replace the next direction with a random direction)
This all goes well, and most of the times I do find a route (usually not the ideal one), but sometimes, when it searches for a long time (say, about 140+ iterations) it just crushes. No warning. No error.
How can I prevent that (a simple iteration limit can work, but I do want the algorithm to run for a long time [~2000+ iterations])?
I think the relevant parts of the code are:
update function inside GUI class
which calls to cross_over
When playing with the update_fitness() score values (changing score -= (weight+1)*2000*(shift_x + shift_y) to score -= (weight+1)*2*(shift_x + shift_y) it runs for a longer time. Could be some kind of an arithmetic overflow?
import tkinter as tk
from enum import Enum
from random import randint, sample
from copy import deepcopy
from time import sleep
from itertools import product
debug_flag = False
class Direction(Enum):
Up = 0
Down = 1
Left = 2
Right = 3
def __str__(self):
return str(self.name)
def __repr__(self):
return str(self.name)[0]
# A chromosome is a list of directions that should lead the way from src to dst.
# Each step in the chromosome is a direction (up, down, right ,left)
# The chromosome also keeps track of its route
class Chromosome:
def __init__(self, src = None, dst = None, length = 10, directions = None):
self.MAX_SCORE = 1000000
self.route = [src]
if not directions:
self.directions = [Direction(randint(0,3)) for i in range(length)]
else:
self.directions = directions
self.src = src
self.dst = dst
self.fitness = self.MAX_SCORE
def __str__(self):
return str(self.fitness)
def __repr__(self):
return self.__str__()
def set_src(self, pixel):
self.src = pixel
def set_dst(self, pixel):
self.dst = pixel
def set_directions(self, ls):
self.directions = ls
def update_fitness(self):
# Higher score - a better fitness
score = self.MAX_SCORE - len(self.route)
score += 4000*(len(set(self.route)) - len(self.route)) # penalize returning to the same cell
score += (self.dst in self.route) * 500 # bonus routes that get to dst
for weight,cell in enumerate(self.route):
shift_x = abs(cell[0] - self.dst[0])
shift_y = abs(cell[1] - self.dst[1])
score -= (weight+1)*2000*(shift_x + shift_y) # penalize any wrong turn
self.fitness = max(score, 0)
def update(self, mutate_chance = 0.9):
# mutate #
self.mutate(chance = mutate_chance)
# move according to direction
last_cell = self.route[-1]
try:
direction = self.directions[len(self.route) - 1]
except IndexError:
print('No more directions. Halting')
return
if direction == Direction.Down:
x_shift, y_shift = 0, 1
elif direction == Direction.Up:
x_shift, y_shift = 0, -1
elif direction == Direction.Left:
x_shift, y_shift = -1, 0
elif direction == Direction.Right:
x_shift, y_shift = 1, 0
new_cell = last_cell[0] + x_shift, last_cell[1] + y_shift
self.route.append(new_cell)
self.update_fitness()
def cross_over(p1, p2, loc = None):
# find the cross_over point
if not loc:
loc = randint(0,len(p1.directions))
# choose one of the parents randomly
x = randint(0,1)
src_parent = (p1, p2)[x]
dst_parent = (p1, p2)[1 - x]
son = deepcopy(src_parent)
son.directions[loc:] = deepcopy(dst_parent.directions[loc:])
return son
def mutate(self, chance = 1):
if 100*chance > randint(0,99):
self.directions[len(self.route) - 1] = Direction(randint(0,3))
class GUI:
def __init__(self, rows = 10, cols = 10, iteration_timer = 100, chromosomes = [], cross_over_chance = 0.5, mutation_chance = 0.3, MAX_ITER = 100):
self.rows = rows
self.cols = cols
self.canv_w = 800
self.canv_h = 800
self.cell_w = self.canv_w // cols
self.cell_h = self.canv_h // rows
self.master = tk.Tk()
self.canvas = tk.Canvas(self.master, width = self.canv_w, height = self.canv_h)
self.canvas.pack()
self.rect_dict = {}
self.iteration_timer = iteration_timer
self.iterations = 0
self.MAX_ITER = MAX_ITER
self.chromosome_list = chromosomes
self.src = chromosomes[0].src # all chromosomes share src + dst
self.dst = chromosomes[0].dst
self.prev_best_route = []
self.cross_over_chance = cross_over_chance
self.mutation_chance = mutation_chance
self.no_obstacles = True
# init grid #
for r in range(rows):
for c in range(cols):
self.rect_dict[(r, c)] = self.canvas.create_rectangle(r *self.cell_h, c *self.cell_w,
(1+r)*self.cell_h, (1+c)*self.cell_w,
fill="gray")
# init grid #
# draw src + dst #
self.color_src_dst()
# draw src + dst #
# after + mainloop #
self.master.after(iteration_timer, self.start_gui)
tk.mainloop()
# after + mainloop #
def start_gui(self):
self.start_msg = self.canvas.create_text(self.canv_w // 2,3*self.canv_h // 4, fill = "black", font = "Times 25 bold underline",
text="Starting new computation.\nPopulation size = %d\nCross-over chance = %.2f\nMutation chance = %.2f" %
(len(self.chromosome_list), self.cross_over_chance, self.mutation_chance))
self.master.after(2000, self.update)
def end_gui(self, msg="Bye Bye!"):
self.master.wm_attributes('-alpha', 0.9) # transparency
self.canvas.create_text(self.canv_w // 2,3*self.canv_h // 4, fill = "black", font = "Times 25 bold underline", text=msg)
cell_ls = []
for idx,cell in enumerate(self.prev_best_route):
if cell in cell_ls:
continue
cell_ls.append(cell)
self.canvas.create_text(cell[0]*self.cell_w, cell[1]*self.cell_h, fill = "purple", font = "Times 16 bold italic", text=str(idx+1))
self.master.after(3000, self.master.destroy)
def color_src_dst(self):
r_src = self.rect_dict[self.src]
r_dst = self.rect_dict[self.dst]
c_src = 'blue'
c_dst = 'red'
self.canvas.itemconfig(r_src, fill=c_src)
self.canvas.itemconfig(r_dst, fill=c_dst)
def color_route(self, route, color):
for cell in route:
try:
self.canvas.itemconfig(self.rect_dict[cell], fill=color)
except KeyError:
# out of bounds -> ignore
continue
# keep the src + dst
self.color_src_dst()
# keep the src + dst
def compute_shortest_route(self):
if self.no_obstacles:
return (1 +
abs(self.chromosome_list[0].dst[0] - self.chromosome_list[0].src[0]) +
abs(self.chromosome_list[0].dst[1] - self.chromosome_list[0].src[1]))
else:
return 0
def create_weighted_chromosome_list(self):
ls = []
for ch in self.chromosome_list:
tmp = [ch] * (ch.fitness // 200000)
ls.extend(tmp)
return ls
def cross_over(self):
new_chromosome_ls = []
weighted_ls = self.create_weighted_chromosome_list()
while len(new_chromosome_ls) < len(self.chromosome_list):
try:
p1, p2 = sample(weighted_ls, 2)
son = Chromosome.cross_over(p1, p2)
if son in new_chromosome_ls:
continue
else:
new_chromosome_ls.append(son)
except ValueError:
continue
return new_chromosome_ls
def end_successfully(self):
self.end_gui(msg="Got to destination in %d iterations!\nBest route length = %d" % (len(self.prev_best_route), self.compute_shortest_route()))
def update(self):
# first time #
self.canvas.delete(self.start_msg)
# first time #
# end #
if self.iterations >= self.MAX_ITER:
self.end_gui()
return
# end #
# clean the previously best chromosome route #
self.color_route(self.prev_best_route[1:], 'gray')
# clean the previously best chromosome route #
# cross over #
if 100*self.cross_over_chance > randint(0,99):
self.chromosome_list = self.cross_over()
# cross over #
# update (includes mutations) all chromosomes #
for ch in self.chromosome_list:
ch.update(mutate_chance=self.mutation_chance)
# update (includes mutations) all chromosomes #
# show all chromsome fitness values #
if debug_flag:
fit_ls = [ch.fitness for ch in self.chromosome_list]
print(self.iterations, sum(fit_ls) / len(fit_ls), fit_ls)
# show all chromsome fitness values #
# find and display best chromosome #
best_ch = max(self.chromosome_list, key=lambda ch : ch.fitness)
self.prev_best_route = deepcopy(best_ch.route)
self.color_route(self.prev_best_route[1:], 'gold')
# find and display best chromosome #
# check if got to dst #
if best_ch.dst == best_ch.route[-1]:
self.end_successfully()
return
# check if got to dst #
# after + update iterations #
self.master.after(self.iteration_timer, self.update)
self.iterations += 1
# after + update iterations #
def main():
iter_timer, ITER = 10, 350
r,c = 20,20
s,d = (13,11), (7,8)
population_size = [80,160]
cross_over_chance = [0.2,0.4,0.5]
for pop_size, CO_chance in product(population_size, cross_over_chance):
M_chance = 0.7 - CO_chance
ch_ls = [Chromosome(src=s, dst=d, directions=[Direction(randint(0,3)) for i in range(ITER)]) for i in range(pop_size)]
g = GUI(rows=r, cols=c, chromosomes = ch_ls, iteration_timer=iter_timer,
cross_over_chance=CO_chance, mutation_chance=M_chance, MAX_ITER=ITER-1)
del(ch_ls)
del(g)
if __name__ == "__main__":
main()
I do not know if you know the Python Profiling tool of Visual Studio, but it is quite useful in cases as yours (though I usually program with editors, like VS Code).
I have run your program and, as you said, it sometimes crashes. I have analyzed the code with the profiling tool and it seems that the problem is the function cross_over, specifically the random function:
I would strongly suggest reviewing your cross_over and mutation functions. The random function should not be called so many times (2 millions).
I have previously programmed Genetic Algorithms and, to me, it seems that your program is falling into a local minimum. What is suggested in these cases is playing with the percentage of mutation. Try to increase it a little bit so that you could get out of the local minimum.
there.
Using pyglet.image.ImageGrid(), is there any way to start off the grid from the top left, instead of the bottom left?
You can use this FlippedImageGrid class. Credits to caffeinepills
import pyglet
class TopLeftTextureGrid(pyglet.image.TextureGrid):
def __init__(self, grid):
image = grid.get_texture()
if isinstance(image, TextureRegion):
owner = image.owner
else:
owner = image
super(TextureGrid, self).__init__(
image.x, image.y, image.z, image.width, image.height, owner
)
items = []
y = image.height - grid.item_height
for row in range(grid.rows):
x = 0
for col in range(grid.columns):
items.append(
self.get_region(x, y, grid.item_width, grid.item_height)
)
x += grid.item_width + grid.column_padding
y -= grid.item_height + grid.row_padding
self.items = items
self.rows = grid.rows
self.columns = grid.columns
self.item_width = grid.item_width
self.item_height = grid.item_height
class FlippedImageGrid(pyglet.image.ImageGrid):
def _update_items(self):
if not self._items:
self._items = []
y = self.image.height - self.item_height
for row in range(self.rows):
x = 0
for col in range(self.columns):
self._items.append(
self.image.get_region(
x, y, self.item_width, self.item_height
)
)
x += self.item_width + self.column_padding
y -= self.item_height + self.row_padding
def get_texture_sequence(self):
if not self._texture_grid:
self._texture_grid = TopLeftTextureGrid(self)
return self._texture_grid
So, the only 'awfull' solution I currently have is:
To verticaly flip the image on the drive
Load the image as a texture and flip it back with get_texture()
Put it into an ImageGrid()
Reverse() the ImageGrid-sequence
This question is 4 years old, but since it's one of the top results on Google I thought I'd share my answer:
def reverse_rows(grid, columns):
# split the grid into rows
temp = [grid[i:i + int(columns)] for i in range(0, len(grid), int(columns))]
temp.reverse() # reverse the order of the rows
reversed = []
for grid in temp: # reassemble the list
reversed += grid
return reversed # and return the reversed list
Note that this returns a list of textures, not an ImageGrid or TextureGrid, so you might lose some functionality.
We have a code to draw circles on the Location on the map with the name of each category. Now the circles and text are one color. How do we get them in different color's by category? Example: Category Garden: Blue, Category Stone: Grey.
So far the code:
size(1500,800)
background(1)
nofill()
stroke('#f91')
pen(.2)
fill('#f91', 0.05)
rotate(90)
font("Avenir", "bold", 10)
align('left')
def mapValue(value, fromMin, fromMax, toMin, toMax):
# Figure out how 'wide' each range is
fromSpan = fromMax - fromMin
toSpan = toMax - toMin
# Convert the from range into a 0-1 range (float)
valueScaled = float(value - fromMin) / float(fromSpan)
# Convert the 0-1 range into a value in the to range.
return toMin + (valueScaled * toSpan)
def xOfDot(lon):
return mapValue(lon, -100, 100, 0, WIDTH)
def yOfDot(lat):
return mapValue(lat, -90, 90, HEIGHT, 0)
with open('theft-alerts.json', 'r') as inputFile:
data = json.load(inputFile)
print len(data)
artworksPerCity = {}
for stolenArt in data:
if stolenArt.has_key('Category'):
city = stolenArt['Category']
if stolenArt.has_key('nItemsStolen'):
numbersStolen = int(stolenArt['nItemsStolen'])
if artworksPerCity.has_key(city):
# Adjust the value stored for this city
artworksPerCity[city] = artworksPerCity[city] + numbersStolen
else:
# Create new key with new value
artworksPerCity[city] = numbersStolen
# Draw circle on the map
radius = artworksPerCity[city] /2
x = xOfDot(stolenArt['Lon'])
y = yOfDot(stolenArt['Lat'])
arc(x, y, radius)
text(city, x, y)
print artworksPerCity
Here is a sketch of what I intend to include in my pure python data utility.
def hexidecimalDiget(n,deHex = false):
if(n<0):
print "negitive values not supported by call to hexidecimalDiget("+str(n)+")"
return None
elif(n < 10):
return str(n)
elif(n < 15):
return ["a","b","c","d","e"][n-10]
elif(n in ["a","b","c","d","e"]):
if deHex:
return ["a","b","c","d","e"].index(n)
return n
else:
print "call to hexidecimalDiget("+str(n)+") not supported!"
return None
def colorFormHexArray(arr):
if len(arr)!=3 and len(arr)!=6:
print "invalid length for color on call to colorFormHexArray("+str(arr)+")"
return None
elif None in arr:
print "cannot make color from None arguments in "+str(arr)
return None
else:
ret = "#"
for k in arr:
if(type(k) == list):
for k2 in k:
ret+=hexidecimalDiget(k)
else:
ret+=hexidecimalDiget(k)
return ret
def arrayFromColor(c):
c = c.replace("#","")
col = []
for n,k in enumerate(c):
if(len(c) == 3):
col.append([hexidecimalDiget(k,deHex = True)])
elif(len(c) == 6):
col.append([hexidecimalDiget(c[(n+1)*2-2],deHex = True),hexidecimalDiget(c[(n+1)*2-2],deHex = True)])
return(col)
def intFromHexPair(hp):
ret = 0
for n,k in enumerate(hp):
digBase = 16**(len(hp)-n-1)
ret+=digBase*hexidecimalDiget(hp[0],deHex = True)
return ret
def hexPairFromInt(I,minDigits = 1,maxDigits = 256):
if I<0:
print "negitive numbers not supported by hexPairFromInt"
k= 0
while(16**(k+1) <= I):
k+=1
if k < minDigits:
k = minDigits
if k > minDigits:
print("maxDigitsExceeded")
ret = []
while k>=0
dig = 16**k
ret.append(hexidecimalDiget(int(I)%(dig))
I -= dig
k-=1
return ret
def specColor(start,end,bottom,top):
start = arrayFromColor(start)
end = arrayFromColor(end)
def ret(v):
if( v<start or c>end ):
print("value out of range "+str([start,end]))
return('#aa0000') #eyo <- error red
else:
starts = [intFromHexPair(k) for k in start]
ends = [intFromHexPair(hp) for k in end]
normalized = (v-bottom)/(top-bottom)
return colorFormHexArray([hexPairFromInt(int((starts[n]-ends[n])*normalized),minDigits = 1,maxDigits = 256) for n,k in enumerate(starts)])
return ret
This seems excessive and hasn't even been slightly tested yet (just a stetch up atm) but I'll be testing and incorporating this code here tonight :: http://krewn.github.io/KPlot/
Question source: SPOJ.. ORDERS
def swap(ary,idx1,idx2):
tmp = ary[idx1]
ary[idx1] = ary[idx2]
ary[idx2] = tmp
def mkranks(size):
tmp = []
for i in range(1, size + 1):
tmp = tmp + [i]
return tmp
def permutations(ordered, movements):
size = len(ordered)
for i in range(1, size): # The leftmost one never moves
for j in range(0, int(movements[i])):
swap(ordered, i-j, i-j-1)
return ordered
numberofcases = input()
for i in range(0, numberofcases):
sizeofcase = input()
tmp = raw_input()
movements = ""
for i in range(0, len(tmp)):
if i % 2 != 1:
movements = movements + tmp[i]
ordered = mkranks(sizeofcase)
ordered = permutations(ordered, movements)
output = ""
for i in range(0, sizeofcase - 1):
output = output + str(ordered[i]) + " "
output = output + str(ordered[sizeofcase - 1])
print output
Having made your code a bit more Pythonic (but without altering its flow/algorithm):
def swap(ary, idx1, idx2):
ary[idx1], ary[idx2] = [ary[i] for i in (idx2, idx1)]
def permutations(ordered, movements):
size = len(ordered)
for i in range(1, len(ordered)):
for j in range(movements[i]):
swap(ordered, i-j, i-j-1)
return ordered
numberofcases = input()
for i in range(numberofcases):
sizeofcase = input()
movements = [int(s) for s in raw_input().split()]
ordered = [str(i) for i in range(1, sizeofcase+1)]
ordered = permutations(ordered, movements)
output = " ".join(ordered)
print output
I see it runs correctly in the sample case given at the SPOJ URL you indicate. What is your failing case?