How can I append the same element several times in python? - python

I am creating a GUI with NUMBER of line edits. However, to get the text that is written in them I tried to make a list of LineEdits and append/add a LineEdit element to the list for each iteration.
Then I tried to add the current item to the layout and when pushing continue be able to change the NAME_LIST to the rename lineEdits.
I have tried to written out the length of the self.lineEditRename and it seems as the same item cannot be appended several times. Is this right, and how can I get around this?
I get this error when I run the file..
layout.addWidget(self.lineEditRename[i],2,i)
IndexError: list index out of range
please help:)
# NAME LIST
self.NAME_LIST = []
for i in range(0, NUMBER):
self.NAME_LIST.append("NUMBER: "+ str(i))
for i in range(0,NUMBER+1):
print(i)
if (i==0):
layout.addWidget(QtWidgets.QLabel("Rename: "),2,i))
else:
layout.addWidget(QtWidgets.QLabel(self.NAME_LIST[i-1]),0,i)
self.lineEditRename = [QtWidgets.QLineEdit(self), QtWidgets.QLineEdit(self)]
self.lineEditRename.append(QtWidgets.QLineEdit(self))
layout.addWidget(self.lineEditRename[i-1],2,i)
self.QContinueButton = QtWidgets.QPushButton("Continue")
self.QContinueButton.clicked.connect(lambda: self.windowtwo(NUMBER))
layout.addWidget(self.QContinueButton,10,2)
def windowtwo(self, NUMBER):
for i in range(1,NUMBER+1):
print(self.lineEditRename[i].text())
self.NAME_LIST[i-1]=self.lineEditRename[i].text()
self.switch_window.emit()

Your issue is because of this line self.lineEditRename = [QtWidgets.QLineEdit(self), QtWidgets.QLineEdit(self)]. The length of self.lineEditRename will always be 3 so as soon as i becomes 3, you will get a IndexError: list index out of range.
Did you mean to do this instead:
self.lineEditRename = [QtWidgets.QLineEdit(self), QtWidgets.QLineEdit(self)]
for i in range(0,NUMBER+1):
print(i)
if (i==0):
layout.addWidget(QtWidgets.QLabel("Rename: "),2,i))
else:
layout.addWidget(QtWidgets.QLabel(self.NAME_LIST[i-1]),0,i)
self.lineEditRename.append(QtWidgets.QLineEdit(self))
layout.addWidget(self.lineEditRename[i],2,i)

Related

Generating a list of random integers in python 3

I am getting a IndexError: list assignment index out of range error when trying to run this program. My index appears to be fine (0 through 8) and I don't think .append is needed since the equal sign assign the random value each pass. What am I missing?
import random
#The main function.
def main():
#Welcome message.
print("Welcome to the lottery number generator program!")
print()
#Explain what the program does.
print("Note: This program will randomly generate a 7 digit lottery number and display it to the screen. ")
print("________________________________________________________________________________________________")
print()
print()
#Call the generateNumbers function and store its returned list in variable lotteryNumbers.
lotteryNumbers = generateNumbers()
#Call the printLottery function and pass the lotteryNumbers list as argument.
printLottery(lotteryNumbers)
#The generateNumbers function generated 7 random digits between 0 and 9 stores them in a list and returns the list.
def generateNumbers():
#A list variable to hold empty list.
lotteryNumbers = []
#Declare and set loop counter to 0.
index = 0
for index in range (0,8):
lotteryNumbers[index] = random.randrange(0,10)
index += 1
return lotteryNumbers
def printLottery(lotteryNumbers):
print("Here are the 7 lucky numbers: {}".format(lotteryNumbers))
#End main
main()
Lists are not like arrays in other languages!
lotteryNumbers is initialised as an empty list. There is nothing in it. Its length is zero. You need to add random.randrange(0, 10) to the empty list. This is done through .append()
for index in range (0,8):
lotteryNumbers[index] = random.randrange(0,10)
index += 1
This doesn't do what you're hoping it does. You can't assign a value to a position that doesn't currently exist in a list, and as that list is currently empty, that means you can't do this at all.
what you want is:
for index in range (0,8):
lotteryNumbers.append(random.randrange(0,10))
You don't need index += 1 because python handles this for you int the for loop.
by the way, lotteries are generally picked without replacement, so don't you actually want to sample?
https://docs.python.org/2/library/random.html#random.sample
eg:
lotteryNumbers = random.sample(xrange(10), 7)
although it is also normal for lotteries to have far more than 10 options!
By initializing an list with
lotteryNumbers = []
it has exactly 0 elements. But with
lotteryNumbers[index] = random.randrange(0,10)
You try to access the 1st, the 2nd, .. , nth element of the list. Your code does not insert elements to the list. To avoid this there are serveral approaches.
Create a dict instead of a list. A dict actually creates nonexistent elements: lotteryNumbers = {}
Preinitialize the list with 8 elements:
lotteryNumbers = [0,0,0,0,0,0,0,0]
or lotteryNumbers = list(range(8))
But the most preferable variant should be to use append:
lotteryNumbers.append(random.randrange(0,10))
You should append the new values:
def generateNumbers():
#A list variable to hold empty list.
lotteryNumbers = []
#Declare and set loop counter to 0.
index = 0
for _ in range (0,8):
lotteryNumbers.append(random.randrange(0,10))
return lotteryNumbers
or build the list up to the size you want:
def generateNumbers():
#A list variable to hold empty list.
lotteryNumbers = [0]*8
#Declare and set loop counter to 0.
index = 0
for index in range (0,8):
lotteryNumbers[index] = random.randrange(0,10)
return lotteryNumbers
Also notice you dont neet to increment the index, you are already iterating through the range.
You are trying to access non-existing elements of the list.
To build your list, you can either keep appending to it with list.append():
lotteryNumbers = []
for _ in range(8):
lotteryNumbers.append(random.randrange(0,10))
or, as it's common in Python, use a list comprehension:
lotteryNumbers = [random.randrange(0,10) for _ in range(8)]
which is usually more efficient and succinct.
I thinks you try add element to array like
lotteryNumbers = [0,0,0,0,0,0,0]
This works. Make an array with the numbers you want and select randomly one item. Then, delete that item and decrease the length with one (using pop). In this example the numbers 1 till 7
lotteryNumbers = []
rij = []
for i in range(aantal):
rij.append(i)
for j in range(7):
r = random.randrange(0,7-j)
k = rij.pop(r)
lotteryNumbers.append(k+1)
print(lotteryNumbers)

How to print items from list that haven't been printed?

My question is, how to print only items that haven't been printed?
(it's just part of the code).
I have an array of 15 items that has to be shuffled, then print only the quantity that e/2 is. I've tried by making a second list with the indexes of the items from the array and then printing only the indexes and items that are present on my list. If an index is not on my list then it will not be printed. After every print the index of the item is removed from my made up list so it won't be printed for the second time.
def tryitem(self,c,list1):
if c not in lista:
c = random.randint(0, 14)
self.tryitem(c,list1)
else:
pass
...some code...
list1 = list(range(15))
for i in range(int(e/2)):
c = random.randint(0, 14)
print(c)
self.tryitem(c,list1)
but= ttk.Button(root, text=str(item.myItem[c][0])+" x"+str(item.myItem[c][1]))
but.place(anchor=W,x=20,y=wysokosc,width=170,height=25)
wysokosc+=25
list1.remove(item.myItem[c][2])
indexes of the items are at myItem[c][2] column
First of all this method doesn't work as it should, because it is printing some items two to three times, and after some prints I get the error
ValueError: list.remove(x): x not in list
I'll try answering your first question, assuming you have a list and you want to print it's items in some kind of iteration, and you want to keep track on what items has been printed already in order to not print them again.
The easiest way is to use a dictionary.
Every time you print an item, add his index to the dictionary.
Every time you want to print an item, check if his index is in the dictionary, and print only if it does not.
import random
e = random.randint(1, 30)
lst = [random.randint(1, 1000) for _ in range(100)]
printed = {} # To save if we perinted this index already
def print_next_values():
for x in range(int(e/2)): # print (e/2) items
index = random.randint(0, len(lst) - 1)
# Try to fetch new indexes until we get a new index we havn't printed yet
while index in printed:
index = random.randint(0, len(lst) - 1)
print(lst[index]) # Printing the item
printed[index] = True # Adding the item index to the dictionary
while len(printed.keys()) < len(lst):
print_next_values()
Here you can see a list of 1000 items, that will be printed in parts (e/2 every iteration, until there is no more items).
Before we print an item, we check if he has been printed already. If not, we print it.

List Index Out Of Range : PYTHON

Even though I am getting valid Prints but still I am getting List Index out of range. The list where I am getting "Out of Range" error is "lstSHADOW_LOG_TABLE"
if((int(len(lstSHADOW_LOG_TABLE[index_shadow_log][1]))) > 1):
print("Length={0} and Value={1}".format(len(lstSHADOW_LOG_TABLE[index_shadow_log][1]), lstSHADOW_LOG_TABLE[index_shadow_log][1]))
for l_inner_element in (lstSHADOW_LOG_TABLE[index_shadow_log:][1]):
if(lstSHADOW_LOG_TABLE[index_shadow_log][1] == lstCAN_LOG_TABLE[index_can_log][1]):
#Some Calculation
else:
break
OUTPUT:
Length=3 and Value=340
Traceback (most recent call last):
for l_inner_element in (lstSHADOW_LOG_TABLE[index_shadow_log:][1]):
IndexError: list index out of range
EDITED FROM HERE (CODE MODIFIED TO INCORPORATE SUGGESTION):
The List "lstSHADOW_LOG_TABLE" is a List of Lists. Now let us say I want the comparison to start fresh from index "index_shadow_log" (SubList "index_shadow_log" onwards)
for l_inner_element in (lstSHADOW_LOG_TABLE[index_shadow_log:]):
Thanks for your answers, I now understood that the meaning of this for loop would be start iteration for List "lstSHADOW_LOG_TABLE" starting from index "index_shadow_log:"
This is my extracted code:
for index in range(len(lstCAN_LOG_TABLE)):
for l_index in range(len(lstSHADOW_LOG_TABLE)):
#print(lstSHADOW_LOG_TABLE[l_index][0])
#print(lstSHADOW_LOG_TABLE[l_index][1])
if(lstSHADOW_LOG_TABLE[l_index][1] == lstCAN_LOG_TABLE[index][1]): #Consider for comparison only CAN IDs
print("matching")
#print(lstCAN_LOG_TABLE[index][0])
#print(lstSHADOW_LOG_TABLE[l_index][0])
index_can_log = index #Position where CAN Log is to be compared
index_shadow_log = l_index #Position from where CAN Shadow Log is to be considered
print("Length={0} and Value={1}".format(len(lstSHADOW_LOG_TABLE[index_shadow_log][1]), lstSHADOW_LOG_TABLE[index_shadow_log][1]))
bMatchFound = 1
for l_inner_element in (lstSHADOW_LOG_TABLE[index_shadow_log:]): #Start comparison
if(lstSHADOW_LOG_TABLE[index_shadow_log][1] == lstCAN_LOG_TABLE[index_can_log][1]): #Compare individual element
dump_file.write("\n")
dump_file.write("SHADOW: " + str(lstSHADOW_LOG_TABLE[index_shadow_log])) #Dump if equal
writer_two.writerow(lstSHADOW_LOG_TABLE[index_shadow_log][0]) #Update CSV File
dump_file.write("\n")
dump_file.write("CAN: " + str(lstCAN_LOG_TABLE[index_can_log])) #Dump if equal
writer_one.writerow(lstCAN_LOG_TABLE[index_can_log][0]) #Update CSV File
if(index_can_log < (input_file_one_row_count - 1)): #Update CAN LOG Index
index_can_log = index_can_log + 1
if(index_can_log >= (input_file_one_row_count - 1)):
break
else:
bMatchFound = 0
break
if(bMatchFound == 0):
break
dump_file.close()
I need to get rid of parenthesis (Sorry coming from C/C++ background we love braces and parenthesis :-P) and make the code a lot cleaner. Thanks all for your suggestions
Compare:
lstSHADOW_LOG_TABLE[index_shadow_log][1]
with
lstSHADOW_LOG_TABLE[index_shadow_log:][1]
The first indexes lstSHADOW_LOG_TABLE, then indexes whatever that returned. The second slices lstSHADOW_LOG_TABLE; this returns a new list. You then indexed that sliced list. If that sliced list has only 1 element, then indexing the second is going to fail.
You really need to cut back on the parentheses here, and simplify the code somewhat. Use a temporary variable to store the indexed element:
value = lstSHADOW_LOG_TABLE[index_shadow_log][1]
if value:
print("Length={0} and Value={1}".format(len(value), value))
for l_inner_element in value:
if value == lstCAN_LOG_TABLE[index_can_log][1]:
#Some Calculation
else:
break

Python number to word converter needs a space detector

I have been working on a sort of encryption tool in python. This bit of code is for the decryption feature.
The point is to take the given numbers and insert them into a list from where they will be divided by the given keys.
My idea for code is below but I keep getting the out of list index range whenever I try it out. Any suggestions? Keep in mind I'm a beginner:
need = []
detr = raw_input('What would you like decrypted?')
count = 0
for d in detr:
if (d == '.' or d == '!') or (d.isalpha() or d== " "):
count +=1
else:
need[count].append(d)
The problem is you are attempting to overwrite list values that don't exist.
list.append(item) adds item to the end of list. list[index] = item inserts item into list at position index.
list = [0,0,0]
list.append(0) # = [0,0,0,0]
list[0] = 1 # [1,0,0,0]
list[99] = 1 # ERROR: out of list index range
You should get rid of the count variable entirely. You could append None in the case of d==' ' etc. or just ignore them.
The way I understood your description you want to extract the numbers in a string and append them to a list using a for-loop to iterate over each character.
I think it would be easier doing it with regular expressions (something like r'([\d]+)').
But the way joconner said: "get rid of the count variable":
need = []
detr = input('What would you like decrypted?\n')
i = iter(detr) # get an iterator
# iterate over the input-string
for d in i:
numberstr = ""
try:
# as long as there are digits
while d.isdigit():
# append them to a cache-string
numberstr+= d
d = next(i)
except StopIteration:
# occurs when there are no more characters in detr
pass
if numberstr != "":
# convert the cache-string to an int
# and append the int to the need-array
need.append( int(numberstr) )
# print the need-array to see what is inside
print(need)

Removed element from list but range has changed?

I just learnt how to remove something from a list.
rando = keywords[random.randint(0, 14)]
h = 0
for h in range(len(keywords)):
if rando == keywords[h]:
position = h
realAns = definitions[position]
del keywords [h]
However, as I am using a while loop, a part of the code keeps repeating, and as I have changed the range by deleting an element, a traceback error occurs saying that it is out of range. How do i fix this?
Thanks :)
The code looks fine, may be you have not defined the list 'keywords' with 14 entries in the list.
You get the 'list out of range' error when you are trying to access a part of list which is not defined.
For example see following code
list_of_rollnumbers = [11,24,31,57,42,99,132]
print list_of_rollnumbers[7]
print list_of_rollnumbers[9] #both these would give list index out of range error
print list_of_rollnumbers[5] #this would print 99
Why are you even doing that loop? As I understand it, you pick the item at a random index, then look through the whole list to find the item so you can find its index. Just do:
position = random.randrange(len(keywords))
rando = keywords[position]
realAns = definitions[position]
Or, much simpler:
rando, realAns = random.choice(list(zip(keywords, definitions)))

Categories