Here is my code for 8 queen problem and why my output are all empty list ([])?
I have checked this statement print "result ok", result will get non-empty results.
class Solution(object):
def __init__(self, finalResult):
self.finalResult = finalResult
def Valid(self,result):
currentX = len(result) - 1
currentY = result[-1]
if currentX == 0:
return True
for i in range(0, len(result) - 1):
if result[i] == currentY:
return False
elif abs(i - currentX) == abs(result[i] - currentY):
return False
return True
def NQueens(self, result):
if result == []:
row = 0
else:
row = len(result)
for col in range(0, 8):
result.append(col)
if self.Valid(result) == True:
# print "check valid ok", row, col, result
if row == 7:
# print "result ok", result
self.finalResult.append(result)
else:
self.NQueens(result)
result.pop(-1)
return
if __name__ == "__main__":
finalResult = []
s = Solution(finalResult)
s.NQueens([])
print len(s.finalResult)
for i in s.finalResult:
print i
Output,
92
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
You should replace
self.finalResult.append(result)
with
self.finalResult.append(result[:])
This will create a copy of the "result". Your current code is creating several references to the same result which all get emptied by result.pop(-1)
You have only one list result that you manipulate. When you append, you append a 'reference' to that list and then you keep modifiying it. At the end it is empty so you print 92 times that empty list. You just need to create a copy of the current result before appending it.
Related
I'm creating a calculator and here's part of the code:
def _digit_formatting(x):
numbers = '1234567890.'
start_idxs = []
end_idxs = []
is_start = True
try:
for idx, value in enumerate(x):
if value in numbers and is_start:
start_idxs.append(idx)
is_start = False
elif value in numbers and idx == len(x) - 1:
end_idxs.append(len(x) - 1)
elif value in numbers and not is_start:
pass
elif value not in numbers and len(start_idxs) > len(end_idxs):
end_idxs.append(idx-1)
is_start = True
except:
...
if len(start_idxs) > len(end_idxs):
end_idxs.append(start_idxs[-1])
start_idxs.reverse()
end_idxs.reverse()
x = list(x)
for idx in range(len(start_idxs)):
if start_idxs[idx] == end_idxs[idx]:
num = x[start_idxs[idx]:end_idxs[idx]+1]
else:
num = x[start_idxs[idx]:end_idxs[idx]+1]
num = ''.join(num)
x = ''.join(x)
x = x[::-1]
num = num[::-1]
x = x.replace(num, '', 1)
x = list(x)
x.reverse()
num = num[::-1]
temp = f'{int(num):,}'
x.insert(start_idxs[idx], temp)
x = ''.join(x)
return x
def calculate(sv):
# This function is called when there's changes in entry box
if self.input_string_var.get() == '':
self.result_string_var.set('')
# Start
real_result = self.input_string_var.get().replace(',', '')
percent_count = self.input_string_var.get().count('%')
# Formatting input string
x = _digit_formatting(real_result)
print(x)
self.input_string_var.set(x)
if percent_count != 0:
numbers = '0123456789.'
for cnt in range(percent_count):
percent_idx = real_result.find('%', 0)
limit_operator = 2
percent_number = ''
for i in range(percent_idx - 1, -1, -1):
if real_result[i] not in numbers:
limit_operator -= 1
if limit_operator == 0:
break
if limit_operator == 1:
if real_result[i] in '*/':
percent_number = ''
break
else:
percent_number += real_result[i]
if percent_number == '':
percent_number = '1'
else:
percent_number = percent_number[1:][::-1]
real_result = list(real_result)
real_result[percent_idx] = f'/100*{percent_number}'
real_result = ''.join(real_result)
else:
real_result = self.input_string_var.get().replace(',', '')
try:
if eval(real_result) == int(eval(real_result)):
self.result_string_var.set(f'{int(eval(real_result)):,}')
else:
self.result_string_var.set(f'{int(eval(real_result)):,}')
except:
None
if self.input_string_var.get() == '':
self.result_string_var.set('')
# Entry box string variable
self.input_string_var = tk.StringVar()
self.input_string_var.trace('w', lambda name, index, mode: calculate(self.input_string_var))
There is two functions, first is _digit_formatting which is to format the equation to put comma like thousands, million and billion. The calculate function is called every time there's changes on the input string variable. But when I try to set the string variable to equation after formatting there seems to be a mistake, but if I print the value, it is correct. Example if I enter 1200 the value I printed is 1,200 which is correct but the value on the text box is not correct. Sorry if the code is messy, I'm still learning to make a clean code.
I cannot reproduce your code.
If you can take a look of my example.
n = 1234567890
print(f"I have {n:,} Reputations")
Result:
I have 1,234,567,890 Reputations
Hi I am learning Python from the week, and I got the idea to make maze in python. After a long time trying to do this, I always came to this starting point:
I would like to get the effect of what is on the 2 selection
My code:
def make(x):
if x%2 !=0:
return False
else:
table = []
for i in range(0,x):
if i == 0:
table.append([0]*x)
elif i == x-1:
table.append([0]*x)
return table
else:
if i == 1:
table.append([0])
table[i].extend([1]*(x-2))
table[i].extend([0])
elif i==x-2:
table.append([0])
table[i].extend([1]*(x-2))
table[i].extend([0])
else:
table.append([0]*(x))
for j in make(20):
print j
Try this. It's generic enough for any value of x that satisfies x%2==0:
def make(x):
if x%2 != 0:
return False
else:
table = []
for i in range(0,x):
if i>=x/2:
fac, rem = divmod(x-i-1,2)
else:
fac, rem = divmod(i,2)
table.append([0,1]*(fac+rem))
table[i].extend([rem]*(x-4*(fac+rem)))
table[i].extend([1,0]*(fac+rem))
return table
Probably better form to raise an exception instead of returning false but I don't know the larger context of what this fits into so I'll just leave it as is.
Or using the same approach as above you can split the single loop into two loops with a separate function like this:
def makeRow(x,fac,rem):
row=[0,1]*(fac+rem)
row.extend([rem]*(x-4*(fac+rem)))
row.extend([1,0]*(fac+rem))
return row
def make2(x):
if x%2 != 0:
return False
else:
table = []
for i in range(0,int(x/2)):
table.append(makeRow(x,*divmod(i,2)))
for i in range(int(x/2),x):
table.append(makeRow(x,*divmod(x-i-1,2)))
return table
Or if you prefer to turn the above into something more pythonic:
def make3(x):
if x%2 != 0:
return False
else:
table=[makeRow(x,*divmod(i,2)) for i in range(0,int(x/2))]
table.extend([makeRow(x,*divmod(x-i-1,2)) for i in range(int(x/2),x)])
return table
Why point out the error "table [i + j]. extend ([int (j% 2)] * (x-(4 * s))) IndexError: list index out of range" and whether in general has the right to work
def fun(x):
table=[]
s=0
for i in range(0,int(x/2)):
if i ==0:
table.append([0]*x)
else:
if i==((x/2)-1):
table.append([0,1]*(x/4))
table[i].extend([1,0]*(x/4))
elif i==(x/2):
table.append([0,1]*(x/4))
table[i].extend([1,0]*(x/4))
elif i == (x/2-1):
table.append([0]*x)
return table
else:
if i<(((x/2)/2)-2):
s+=1
for j in range(0,2):
table.append([0,1]*s)
table[i+j].extend([int(j%2)]*(x-(4*s)))
table[i+j].extend([1,0]*s)
if i>((x/2)/2):
for j in range(0,2):
if len(table) == (x-2):
break
else:
table.append([0,1]*s)
table[i+j].extend([int(j%2)]*(x-(4*s)))
table[i+j].extend([1,0]*s)
s-=1
for j in fun(20):
print j
I am trying to implement Quicksort using Python.
This is my code:
import random
def quickSort(lst):
randomIndex = random.randint(0,len(lst)-1)
pivot = lst[randomIndex]
greater = []
less = []
equal = []
if len(lst) > 1:
for num in lst:
if num > pivot:
greater.append(num)
elif num == pivot:
equal.append(num)
else:
less.append(num)
return quickSort(less)+equal+quickSort(greater)
else:
return lst
def main():
lst = [1000000,100000,1000,10000,100,10]
sortedLst = quickSort(lst)
print("Quicksorted List: ", sortedLst)
main()
How come when I run my code, it says that it runs into this error:
ValueError: empty range for randrange() (0,0, 0)
The only problem is that you try to select randomIndex even, when lst is empty, just move your initializations into if condition where you are sure that they are non empty
import random
def quickSort(lst):
if len(lst) > 1:
randomIndex = random.randint(0,len(lst)-1)
pivot = lst[randomIndex]
greater = []
less = []
equal = []
for num in lst:
if num > pivot:
greater.append(num)
elif num == pivot:
equal.append(num)
else:
less.append(num)
return quickSort(less)+equal+quickSort(greater)
else:
return lst
def main():
lst = [1000000,100000,1000,10000,100,10]
sortedLst = quickSort(lst)
print("Quicksorted List: ", sortedLst)
main()
I'm having a problem returning both False, and the append number in the def checkit function. I'm not sure if I have miscoded the checkrow functions. It is able to return true when given a correctly solved Sudoku puzzle, but when we are to call an incorrect Sudoku puzzle, it is to return False, and provide the problematic row. Currently, it is only returning the problematic row, aka the location of what makes the puzzle fail, but not including false. any idea on how to make it so that it returns both?
import sys
from scanner import *
def createList(size):
if size == 0: return []
else:
return [0] + createList(size -1)
def printGrid(gridlist):
for row in gridlist:
print (str(row)+"\n")
def rows(g):
return len(g)
def cols(g):
return len(g[0])
def printMatrix(g):
for i in range(0,rows(g),1):
for j in range(0,cols(g),1):
print(g[i][j],end=' ')
print('')
print('')
def readinput(filename,grid):
s = Scanner(filename)
r = s.readtoken()
while r != "":
r = int(r)
c = s.readint()
v = s.readint()
grid[r][c]=v
r = s.readtoken()
def checkRows(g):
for rows in g:
numbersInRow = []
for number in rows:
if number != 0 and number in numbersInRow:
return g.index(rows)
else:
numbersInRow.append(number)
return True
def checkIt(g):
checkRows(g)
rowSuccess = checkRows(g)
print(rowSuccess)
def main():
grid = createList(9)
for i in range(9):
grid[i] = createList(9)
readinput(sys.argv[1],grid)
printMatrix(grid)
checkIt(grid)
main()
You can return both of them:
def checkRows(g):
for rows in g:
numbersInRow = []
for number in rows:
if number != 0 and number in numbersInRow:
return g.index(rows), False
else:
numbersInRow.append(number)
And to read it:
problematic_row, result = checkRows(g)
return False, g.index(rows) will return two values as a tuple.
The following script is supposed to fetch a specific line number and parse it from a live website. It works for like 30 loops but then it seems like enumerate(f) stops working correctly... the "i" in the for loop seems to stop at line 130 instead of like 200 something. Could this be due to the website I'm trying to fetch data from or something else? Thanks!!
import sgmllib
class MyParser(sgmllib.SGMLParser):
"A simple parser class."
def parse(self, s):
"Parse the given string 's'."
self.feed(s)
self.close()
def __init__(self, verbose=0):
"Initialise an object, passing 'verbose' to the superclass."
sgmllib.SGMLParser.__init__(self, verbose)
self.divs = []
self.descriptions = []
self.inside_div_element = 0
def start_div(self, attributes):
"Process a hyperlink and its 'attributes'."
for name, value in attributes:
if name == "id":
self.divs.append(value)
self.inside_div_element = 1
def end_div(self):
"Record the end of a hyperlink."
self.inside_div_element = 0
def handle_data(self, data):
"Handle the textual 'data'."
if self.inside_div_element:
self.descriptions.append(data)
def get_div(self):
"Return the list of hyperlinks."
return self.divs
def get_descriptions(self, check):
"Return a list of descriptions."
if check == 1:
self.descriptions.pop(0)
return self.descriptions
def rm_descriptions(self):
"Remove all descriptions."
self.descriptions.pop()
import urllib
import linecache
import sgmllib
tempLine = ""
tempStr = " "
tempStr2 = ""
myparser = MyParser()
count = 0
user = ['']
oldUser = ['none']
oldoldUser = [' ']
array = [" ", 0]
index = 0
found = 0
k = 0
j = 0
posIndex = 0
a = 0
firstCheck = 0
fCheck = 0
while a < 1000:
print a
f = urllib.urlopen("SITE")
a = a+1
for i, line in enumerate(f):
if i == 187:
print i
tempLine = line
print line
myparser.parse(line)
if fCheck == 1:
result = oldUser[0] is oldUser[1]
u1 = oldUser[0]
u2 = oldUser[1]
tempStr = oldUser[1]
if u1 == u2:
result = 1
else:
result = user is oldUser
fCheck = 1
user = myparser.get_descriptions(firstCheck)
tempStr = user[0]
firstCheck = 1
if result:
array[index+1] = array[index+1] +0
else:
j = 0
for z in array:
k = j+2
tempStr2 = user[0]
if k < len(array) and tempStr2 == array[k]:
array[j+3] = array[j+3] + 1
index = j+2
found = 1
break
j = j+1
if found == 0:
array.append(tempStr)
array.append(0)
oldUser = user
found = 0
print array
elif i > 200:
print "HERE"
break
print array
f.close()
Perhaps the number of lines on that web page are fewer than you think? What does this give you?:
print max(i for i, _ in enumerate(urllib.urlopen("SITE")))
Aside: Your indentation is stuffed after the while a < 1000: line. Excessive empty lines and one-letter names don't assist the understanding of your code.
enumerate is not broken. Instead of such speculation, inspect your data. Suggestion: replace
for i, line in enumerate(f):
by
lines = list(f)
print "=== a=%d linecount=%d === % (a, len(lines))
for i, line in enumerate(lines):
print " a=%d i=%d line=%r" % (a, i, line)
Examine the output carefully.