getting into infinite loop when using a while loop - python

I am using this code to use a dataframe lookup for every single record in the first dataframe.
for i in range(len(a1)):
title_derived = []
k = 100000
print(i)
for j in range(len(b1)):
print(j)
while j < (k + 6):
#print(b1.iloc[i][10], a1.iloc[j][3])
if b1.iloc[j][10] == a1.iloc[i][3]:
print(j,k)
print('1st if ' + str(j))
print (b1.iloc[j][1], a1.iloc[i][11], b1.iloc[j][5])
if (((pd.to_datetime(b1.iloc[j][1]) <= pd.to_datetime(a1.iloc[i][11]) <= pd.to_datetime(b1.iloc[j][5]))) or ((pd.to_datetime(b1.iloc[j][1]) <= pd.to_datetime(a1.iloc[i][8]) <= pd.to_datetime(b1.iloc[j][5])))) :
print('2nd if' + str(j))
title_derived.append(b1.iloc[j][15])
print('inserted ' + b1.iloc[j][15] + ' in ' + str(i) + ' th record ')
a1.iat[i,65] = title_derived
It prints,
0
0
and then goes into a an infinite loop.

May be it is because you are length of "b1" in lesser than value of "k + 6". And in that case you will never get out of while loop and in the last it will throw and error.
In this case you should first check the least possible length of "b1" and then decide your wile condition.

Related

How to remove a certain string before printing?

answer = input('Enter a number: ')
x = 10**(len(answer) - 1)
print(answer, end = ' = ')
for i in answer:
if '0' in i:
x = x//10
continue
else:
print('(' + i + ' * ' + str(x) + ')' , end = '')
x = x//10
print(' + ', end = '')
so i have this problem, when i enter any number, everything is great but at the end there is an extra ' + ' that i do not want. Now normally this wouldnt be an issue with lists and .remove function, however i am not allowed to use these for this problem. I cannot come up with any sort of solution that does not involve functions
I tried matching the length but it didnt work because of '0'
you can insert an extra condition in the else block:
else:
print('(' + i + ' * ' + str(x) + ')' , end = '')
x = x//10
if x:
print(' + ', end = '')
this will help not to insert the last plus when it is not needed
The error is that there is an extra '+' at the end of the output. This can be fixed by adding an 'if' statement to the end of the code that checks if the last character in the output is a '+' and, if so, removes it.
Well Valery's answer is the best just add one more condition in case the answer was a 10 multiple
if x and int(answer)%10 != 0:
This kind of problem is best solved using the str.join() method.
answer = input("Enter a number: ")
x = 10**(len(answer) - 1)
terms = []
for i in answer:
if i == "0":
x = x//10
continue
else:
terms.append(f"({i} * {x})")
x = x//10
print(f"{answer} =", " + ".join(terms))
Sample interaction:
Enter a number: 1025
1025 = (1 * 1000) + (2 * 10) + (5 * 1)
Notes
We build up the terms by appending them into the list terms
At the end of the for loop, given 1025 as the input, the terms looks like this
['(1 * 1000)', '(2 * 10)', '(5 * 1)']
Update
Here is a patch of your original solution:
answer = input('Enter a number: ')
x = 10**(len(answer) - 1)
print(answer, end = ' = ')
for i in answer:
if '0' in i:
x = x//10
continue
else:
print('(' + i + ' * ' + str(x) + ')' , end = '')
x = x//10
if x == 0:
print()
else:
print(' + ', end = '')
The difference is in the last 4 lines where x (poor name, by the way), reaches 0, we know that we should not add any more plus signs.
answer = input('Enter a number: ')
#finds length of answer
length = 0
for n in answer:
length += 1
loop_counter = 0
##
zero_counter = 0
multiple_of_ten = 10
#finds if answer is multiple of 10 and if so by what magnitude
while True:
if int(answer) % multiple_of_ten == 0:
#counts the zeroes aka multiple of 10
zero_counter += 1
multiple_of_ten = multiple_of_ten*10
else:
break
#finds the multiple of 10 needed for print output
x = 10**(length - 1)
print(answer, end = ' = ')
for i in answer:
# if its a 0 it will skip
if '0' in i:
x = x//10
#still divises x by 10 for the next loop
pass
else:
print('(' + i + ' * ' + str(x) + ')' , end = '')
x = x//10
#if position in loop and zeroes remaining plus one is equal to
#the length of the integer provided, it means all the reamining
#digits are 0
if loop_counter + zero_counter + 1 == length:
break
else:
#adds ' + ' between strings
print(' + ', end = '')
# keeps track of position in loop
loop_counter += 1
ended up implementing a counter to see how many zeroes there are, and a counter to see where we are in the for loop and stop the loop when its the same as amount of zeroes remaining
I tested this code and it worked fine
if x and int(answer)%10 != 0:
Enter a number: 25
25 = (2 * 10) + (5 * 1)
Enter a number: 1000
1000 = (1 * 1000)
Enter a number: 117
117 = (1 * 100) + (1 * 10) + (7 * 1)

while loop in line 36 won't exit despite fulfilling condition

The outer while loop should exit when current_digit and powers[digit_of_powers] both equal 26 but the while-loop doesn't exit as it should.
As a proof of what I'm claiming, see for yourself, the last line never executes. The program is stuck in the stopped while loop.
I'm new to programming so I may do daft mistakes
#enter a number in base 10 and find how it's written in choosen base... or at least thats what it should do
import math
def find_powers(num, base, start_num): #stackoverflow experts, this function is not important for my problem
power = 1 # power starts as a '1' each iteration
while start_num + power <= num:
power *= base
if start_num != num:
power /= base
powers.append(round(math.log(power, base)))
find_powers(num, base, start_num + power)
num = 7892 #enter choosen number in base 10 here
base = 10 #enter choosen base here. I put ten because its much easier to check the program with a base I'm familiar with
powers = []
find_powers(num, base, 0)
print(powers)
print('')
check = 0 #this script is not necessary, it's just a way for me to check if it can find the input of the def find_powers function from its output.
for i in powers: # It if it does then the function still work
check += base**i
print(check)
print('')
string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
digits = []
# Two things to check here
# 1. if powers[i] misses a digit or not.
# If it does, digits.append(0)
# 2. How many times the same power comes (it'll always be in row)
digit_of_powers = 0
while digit_of_powers != len(powers):
digit_of_powers += 1
print('digits_of_powers = ' + str(digit_of_powers))
current_digit = powers[digit_of_powers]
print('current_digit = ' + str(current_digit))
print('powers[digit_of_powers] = ' + str(powers[digit_of_powers]))
print('')
digit_thatll_go_in_digits = 1
while current_digit == powers[digit_of_powers]:
digit_thatll_go_in_digits += 1
digit_of_powers += 1
print('digit_thatll_go_in_digits = ' + str(digit_thatll_go_in_digits))
print('digits_of_powers = ' + str(digit_of_powers))
print(digits)
print('while ' + str(digit_of_powers) + ' != ' + str(len(powers)))
print('while ' + str(current_digit) + ' == ' + str(powers[digit_of_powers]))
print('')
digits.append(digit_thatll_go_in_digits)
print('fin du while')
print('')
print('this last line never executes for some reason')
You are increasing (conditionally) digit_of_powers twice, but condition is exact value while digit_of_powers != len(powers): (not equal)
It means that your code can jump over this condition and run further.
For example, if len(powers) == 10, digit_of_powers + 1 + 1 will increase from 9 to 11 and can be never the same.
Try this:
while digit_of_powers <= len(powers): (if it starts with 1)
or
while digit_of_powers < len(powers): (if it starts with 0)

Alternating sums of a list [duplicate]

This question already has answers here:
Writing a function that alternates plus and minus signs between list indices
(7 answers)
Closed 2 years ago.
9.Write a program that accepts 9 integers from the user and stores them in a list. Next, compute the alternating sum of all of the elements in the list. For example, if the user enters
1 4 9 16 9 7 4 9 11
then it computes
1 – 4 + 9 – 16 + 9 – 7 + 4 – 9 + 11 = –2
myList = []
value = None
count = 0
while count != 9:
value = int(input("Please enter a number: "))
myList.append(value)
count = count + 1
if count == 9:
break
print(myList)
def newList(mylist):
return myList[0] - myList[1] + myList[2] - myList[3] + myList[4] - myList[5] + myList[6] - myList[7] + myList[8]
x = newList(myList)
print(x)
My code returns the correct answer, but I need it to print out the actual alternating sums as in the example. I have been stuck on this for a while. I am having a mental block on this and havent been able to find anything similar to this online.
I appreciate any help or tips.
Also, this is python 3.
Thank you.
a=[1, 4, 9, 16, 9, 7, 4, 9, 11]
start1=0
start2=1
sum1=0
first_list=[a[i] for i in range(start1,len(a),2)]
second_list=[a[i] for i in range(start2,len(a),2)]
string=''
for i,j in zip(first_list,second_list):
string+=str(i)+'-'+str(j)+'+'
string.rstrip('+')
print('{}={}'.format(string,str(sum(first_list)-sum(second_list))))
Output
1-4+9-16+9-7+4-9+=-2
Try doing this:
positives = myList[::2]
negatives = myList[1::2]
result = sum(positives) - sum(negatives)
print ("%s = %d" % (" + ".join(["%d - %d" % (p, n) for p, n in zip(positives, negatives)]), result))
I'll explain what I'm doing here. The first two lines are taking slices of your list. I take every other number in myList starting from 0 for positives and starting from 1 for negatives. From there, finding the result of the alternating sum is just a matter of taking the sum of positives and subtracting the sum of negatives from it.
The final line is somewhat busy. Here I zip positives and negatives together which produces a list of 2-tuples where of the form (positive, negative) and then I use string formatting to produce the p - n form. From there I use join to join these together with the plus sign, which produces p0 - n0 + p1 - n1 + p2 - n2.... Finally, I use string formatting again to get it in the form of p0 - n0 + p1 - n1 + p2 - n2 ... = result.
You can do as you did but place it in a print statement
print(myList[0] + " - " + myList[1] + " + " + myList[2] + " - " + myList[3] + " + " + myList[4] + " - " + myList[5] + " + " + myList[6] + " - " + myList[7] + " + " + myList[8] + " = " + x)
Its not perfectly clean, but it follows your logic, so your teacher won't know you got your solution from someone else.
Something along the lines of the following would work:
def sumList(theList):
value = 0
count = 0
steps = ""
for i in theList:
if count % 2 == 0:
value += i
steps += " + " + str(i)
else:
value -= i
steps += " - " + str(i)
count += 1
print(steps[3:])
return value
print(sumList(myList))
It alternates between + and - by keeping track of the place in the list and using the modulus operator. Then it calculates the value and appends to a string to show the steps which were taken.
You can also do something like below once your 9 or more numbers list is ready
st = ''
sum = 0
for i, v in enumerate(myList):
if i == 0:
st += str(v)
sum += v
elif i % 2 == 0:
st += "+" + str(v)
sum += v
else:
st += "-" + str(v)
sum -= v
print("%s=%d" % (st, sum))
It prints : 1-4+9-16+9-7+4-9+11=-2

I want to save all outputs in a variable-type list

for i in range(9999999):
if i <= 9:
print '000',i,'000000'
elif i <= 99:
print '000',i,'00000'
elif i <= 999:
print '000',i,'0000'
elif i <= 9999:
print '000',i,'000'
elif i <= 99999:
print '000',i,'00'
elif i <= 999999:
print '000',i,'0'
elif i <= 9999999:
print '000',i
I want to save all outputs in a variable-type list
The output looks like this : 000 000 0000
The code below shows a simpler way to generate your strings, and also shows how to append them to a list instead of printing them.
lst = []
for i in range(9999999):
if 100 <= i <= 999:
prefix = "050"
else:
prefix = "000"
i_str = str(i)
suffix = "0" * (7-len(i_str))
result = prefix + " " + i_str + " " + suffix
# or result = " ".join((prefix, i_str, suffix))
lst.append(result)
It seems that, for each i less than 9 999 999, your goal is to build a string formed by three parts:
'000';
the string representation of i;
a sequence of zeros depending on the length of the string representation of i.
You can achieve this goal with a simple list comprehension:
lst = ['000 %d %s'.strip() % (i, '0' * (7-len(str(i)))) for i in xrange(9999999)]
Note however that such a big list takes some time to be built and occupies some memory.
In case you don't need the whole list at once, but you are going to process its elements one by one, I suggest you to create a generator:
lst_gen = ('000 %d %s'.strip() % (i, '0' * (7-len(str(i)))) for i in xrange(9999999))
and then loop over it:
for s in lst_gen:
print s
or ask for subsequent elements and process them one by one:
s = next(lst_gen)
print s
s = next(lst_gen)
print s

Python IndexError: list index out of range with long string

My code seems to work with shorter strings, but inexplicably to me gets stuck on others. The function of this is to replace characters with digits, and I have it print out the new string after each part is replaced. Any help you can give me is appreciated, thanks!
By the way, I did look at the similar questions on this and they did not answer my particular question, please don't remove my question.
possibleChars = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W',
'X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','1','2','3','4','5','6','7','8','9','0',' ',',','.','?','!','/','\\','[',']','{','}',
'|','<','>',';',':','+','=','-','_','(',')','#','#','$','%','^','&','*','~','`'] #0-92
possibleCharsToDigit = ['1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3',
'4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8',
'9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3',
'4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3'] #0-92
password = "How is your day today?"
def passwordToDigit(passToConvert):
passLen = len(passToConvert) #puts the length of the password in a variable
i = 0 #i is the selected character in the password
j = 0 #j is the selected possible char, i.e. '0' is 'A' in possibleChars or '1' in possibleCharsToDigit
while i < passLen:
if passToConvert[i] == possibleChars[j]:
passToConvert = passToConvert[0:i] + possibleCharsToDigit[j] + passToConvert[i + 1:]
i += 1
print passToConvert
else:
j += 1
print passToConvert
passwordToDigit(password)
When you are incrementing j variable inside the while loop, notice that when j gets bigger than the length of possibleCharsToDigit list then you are trying to access its element with index out of bounds.
you should set j = 0 in the if passToConvert[i] == possibleChars[j] clause:
def passwordToDigit(passToConvert):
passLen = len(passToConvert) #puts the length of the password in a variable
i = 0 #i is the selected character in the password
j = 0 #j is the selected possible char, i.e. '0' is 'A' in possibleChars or '1' in possibleCharsToDigit
while i < passLen:
if passToConvert[i] == possibleChars[j]:
passToConvert = passToConvert[0:i] + possibleCharsToDigit[j] + passToConvert[i + 1:]
i += 1
j = 0
print passToConvert
else:
j += 1
print passToConvert
As you increment j within your while loop, without ever resetting it, each time you successfully match a character and move onto the next one. This will cause your code to fail as soon as you have a character earlier in possibleChars than a previous one.
To illustrate:
passwordToDigit('ABCDEFGHIJKLMNOP') #will work correctly
passwordToDigit('BA') #will fail with IndexError
Quick Solution
The quickest solution would be to reset the j index when you find a match.
ie
# ...
if passToConvert[i] == possibleChars[j]:
passToConvert = passToConvert[0:i] + possibleCharsToDigit[j] + passToConvert[i + 1:]
i += 1
print passToConvert
j = 0 #Reset tje j index to start searching from beginning
else:
#...
Dict Solution
You could also spend some time refactoring your code to use a dict to map characters to digits as in:
import string
charopts = string.ascii_uppercase + string.ascii_lowercase + string.digits[1:] + r'0 ,.?!/\[]{}|<>;:+=-_()##$%^&*~`'
char2dig = dict((k,str((i+1)%10)) for i,k in enumerate(charopts))
def passwordToDigitDic(passToConvert):
newpass = ''
for c in passToConvert:
newpass += char2dig[c]
print(newpass + passToConvert[len(newpass):])
passwordToDigitDic('ABCDEFGH')
passwordToDigitDic('HGEFBCA')
Note, if you are ever interested in doing the translation in one go as opposed to step by step with prints, look into the string.translate function.
When i=passLen-1, then you are trying to access passToConvert[i+1], which is out of the range of passToConvert. Hence you are getting this error. Try this:
if passToConvert[i] == possibleChars[j]:
if i<passLen-1:
passToConvert = passToConvert[0:i] + possibleCharsToDigit[j] + passToConvert[i + 1:]
else:
passToConvert = passToConvert[0:i] + possibleCharsToDigit[j]
i += 1
print passToConvert

Categories

Resources