Code randomly doesn't follow instructions of For Loop - python

I am attempting to create a program that finds the number of possible configurations using factorials. Here is my code so far:
from collections import Counter
letters = []
lettnum = []
trash = []
booleans = []
boolet = {}
def fact(n):
if n == 0:
return 1
else:
return n * fact(n - 1)
word = input("Word: ")
x = fact(len(word))
for char in word:
letters.append(char)
z = Counter(letters)
y = list(z.values())
ans = "print("
print(letters)
print(y)
for element in y:
if y[0] == element:
ans = ans + str(fact(element))
else:
ans = ans + "*" + str(fact(element))
ans = ans + ")"
print(ans)
If you enter the word tool, it is supposed to give an answer of
print(1*2*1)
but instead prints out
print(1*1*21*1)
I've noticed that it combines the 2 and 1 without adding a *, and it also adds random 1's for absolutely no reason. What's up with my code?
Some more info:
Text editor: Visual Studio Code
Python Version: Python 3.7.3

I don't fully understand the goal your program is trying to accomplish however I do see the issue of the behavior you are seeing
Your issue lies in how you are checking the first element
Notice this line is checking that element is == 1
if y[0] == element:
The last element is also 1 so it goes along the same path
A solution to this would be to write the loop like this
ans = "print(" + str(fact(y[0]))
for element in y[1:]:
ans += "*" + str(fact(element))
ans = ans + ")"
print(ans)

Related

How can I fix this error for popping a word in a list/string? (Python 3.x)

I'm not exactly the kind of guy you call "good" at coding. In this particular scenario, on line 13, I'm trying to pop the first word in the list until I'm done, but it keeps giving me the 'str' object can not be interpreted as an integer issue.
What am I doing wrong here?
n = n.split(" ")
N = n[0]
K = n[1]
f1 = input()
f1 = f1.split(" ")
f1 = list(f1)
current = 0
for x in f1:
while current <= 7:
print(x)
f1 = list(f1.pop()[0])
current = current + len(x)
if current > 7:
print("\n")
current = 0
According your comments, this program will split lines to contain max K characters:
K = 7
s = "hello my name is Bessie and this is my essay"
out, cnt = [], 0
for word in s.split():
l = len(word)
if cnt + l <= K:
cnt += l
if not out:
out.append([word])
else:
out[-1].append(word)
else:
cnt = l
out.append([word])
print("\n".join(" ".join(line) for line in out))
Prints:
hello my
name is
Bessie
and this
is my
essay
You could try splitting the string on the index, and inserting a newline there. Each time you do this your string gets one character longer, so we can use enumerate (which starts counting at zero) to add a number to our slice indexes.
s = 'Thanks for helping me'
new_line_index = [7,11, 19]
for i, x in enumerate(new_line_index):
s = s[:x+i] + '\n' + s[x+i:]
print(s)
Output
Thanks
for
helping
me

Check result using 4 operations based with Python

I'm struggling to make a Python program that can solve riddles such as:
get 23 using [1,2,3,4] and the 4 basic operations however you'd like.
I expect the program to output something such as
# 23 reached by 4*(2*3)-1
So far I've come up with the following approach as reduce input list by 1 item by checking every possible 2-combo that can be picked and every possible result you can get to.
With [1,2,3,4] you can pick:
[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]
With x and y you can get to:
(x+y),(x-y),(y-x),(x*y),(x/y),(y/x)
Then I'd store the operation computed so far in a variable, and run the 'reducing' function again onto every result it has returned, until the arrays are just 2 items long: then I can just run the x,y -> possible outcomes function.
My problem is this "recursive" approach isn't working at all, because my function ends as soon as I return an array.
If I input [1,2,3,4] I'd get
[(1+2),3,4] -> [3,3,4]
[(3+3),4] -> [6,4]
# [10,2,-2,24,1.5,0.6666666666666666]
My code so far:
from collections import Counter
def genOutputs(x,y,op=None):
results = []
if op == None:
op = str(y)
else:
op = "("+str(op)+")"
ops = ['+','-','*','/','rev/','rev-']
z = 0
#will do every operation to x and y now.
#op stores the last computated bit (of other functions)
while z < len(ops):
if z == 4:
try:
results.append(eval(str(y) + "/" + str(x)))
#yield eval(str(y) + "/" + str(x)), op + "/" + str(x)
except:
continue
elif z == 5:
results.append(eval(str(y) + "-" + str(x)))
#yield eval(str(y) + "-" + str(x)), op + "-" + str(x)
else:
try:
results.append(eval(str(x) + ops[z] + str(y)))
#yield eval(str(x) + ops[z] + str(y)), str(x) + ops[z] + op
except:
continue
z = z+1
return results
def pickTwo(array):
#returns an array with every 2-combo
#from input array
vomit = []
a,b = 0,1
while a < (len(array)-1):
choice = [array[a],array[b]]
vomit.append((choice,list((Counter(array) - Counter(choice)).elements())))
if b < (len(array)-1):
b = b+1
else:
b = a+2
a = a+1
return vomit
def reduceArray(array):
if len(array) == 2:
print("final",array)
return genOutputs(array[0],array[1])
else:
choices = pickTwo(array)
print(choices)
for choice in choices:
opsofchoices = genOutputs(choice[0][0],choice[0][1])
for each in opsofchoices:
newarray = list([each] + choice[1])
print(newarray)
return reduceArray(newarray)
reduceArray([1,2,3,4])
The largest issues when dealing with problems like this is handling operator precedence and parenthesis placement to produce every possible number from a given set. The easiest way to do this is to handle operations on a stack corresponding to the reverse polish notation of the infix notation. Once you do this, you can draw numbers and/or operations recursively until all n numbers and n-1 operations have been exhausted, and store the result. The below code generates all possible permutations of numbers (without replacement), operators (with replacement), and parentheses placement to generate every possible value. Note that this is highly inefficient since operators such as addition / multiplication commute so a + b equals b + a, so only one is necessary. Similarly by the associative property a + (b + c) equals (a + b) + c, but the below algorithm is meant to be a simple example, and as such does not make such optimizations.
def expr_perm(values, operations="+-*/", stack=[]):
solution = []
if len(stack) > 1:
for op in operations:
new_stack = list(stack)
new_stack.append("(" + new_stack.pop() + op + new_stack.pop() + ")")
solution += expr_perm(values, operations, new_stack)
if values:
for i, val in enumerate(values):
new_values = values[:i] + values[i+1:]
solution += expr_perm(new_values, operations, stack + [str(val)])
elif len(stack) == 1:
return stack
return solution
Usage:
result = expr_perm([4,5,6])
print("\n".join(result))

Create multiplication table?

Am a beginner in Programming and am practicing how to use nested for loops to make a multiplication table in python 2.7.5.
Here is my code
x=range(1,11)
y=range(1,11)
for i in x:
for j in y:
print i*j
pass
well,the result is correct but it does not appear in a square matrix form as i wish.Please help me improve the code
You should print without a line break.
x = range(1,11)
y = range(1,11)
for i in x:
for j in y:
print i*j, # will not break the line
print # will break the line
you may add formatting to keep constant cell width
x = range(1,11)
y = range(1,11)
for i in x:
for j in y:
# substitute value for brackets
# force 4 characters, n stands for number
print '{:4n}'.format(i*j), # comma prevents line break
print # print empty line
Python's print statement adds new line character by default to the numbers you wish to have in your output. I guess you would like to have just a trailing spaces for inner loop and a new line character at the end of the outer loop.
You can achieve this by using
print i * j, # note the comma at the end (!)
and adding just a new line at the end of outer loop block:
print ''
To learn more about the trailing coma, and why it works, look here: "How to print in Python without newline or space?". Mind that it works differently in Python 3.
The final code should look like:
x=range(1,11)
y=range(1,11)
for i in x:
for j in y:
print i*j,
print ''
You can also look for '\t' special character which would allow you to get better formatting (even this old resource is good enough: https://docs.python.org/2.0/ref/strings.html)
USE This Code. It works MUCH better. I had to do this for school, and I can tell you that after putting about 4 hours into this it works flawlessly.
def returnValue(int1, int2):
return int1*int2
startingPoint = input("Hello! Please enter an integer: ")
endingPoint = input("Hello! Please enter a second integer: ")
int1 = int(startingPoint)
int2 = int(endingPoint)
spacing = "\t"
print("\n\n\n")
if int1 == int2:
print("Your integers cannot be the same number. Try again. ")
if int1 > int2:
print("The second number you entered has to be greater than the first. Try again. ")
for column in range(int1, int2+1, 1): #list through the rows(top to bottom)
if column == int1:
for y in range(int1-1,int2+1):
if y == int1-1:
print("", end=" \t")
else:
individualSpacing = len(str(returnValue(column, y)))
print(y, " ", end=" \t")
print()
print(column, end=spacing)
for row in range(int1, int2+1, 1): #list through each row's value. (Go through the columns)
#print("second range val: {:}".format(row))
individualMultiple = returnValue(row, column)
print(individualMultiple, " ", end = "\t")
print("")
Have a good day.
#Generate multiplication table by html
import random
from copy import deepcopy
N = 15
colors = ['F','E','D','C','B','A']
i = 0
colorsall = []
while i < N:
colornow = deepcopy(colors)
random.shuffle(colornow)
colornow = "#"+"".join(colornow)
colorsall.append(colornow)
i += 1
t = ""
for i in range(1,N+1):
s = ''
for j in range(1,N+1):
if j >= i:
s += '<td style="background-color:' + colorsall[i-1] + '">'+str(i*j)+'</td>'
else:
s += '<td style="background-color:' + colorsall[j-1] + '">'+str(i*j)+'</td>'
s = "<tr>" + s + "</tr>"
t = t + s + '\n'
print('<table>' + t + '</table>')
Taken from https://todaymylearn.blogspot.com/2022/02/multiplication-table-in-html-with-python.html [Disclosure : my blog]

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

How do you use a string to solve a math equation using python?

I'm trying to make a python program which takes in a user equation, for example: "168/24+8=11*3-16", and tries to make both sides of the equation equal to each other by removing any 2 characters from the user input. This is what I have so far:
def compute(side):
val = int(side[0])
x= val
y=0
z=None
for i in range(1, len(side)-1):
if side[i].isdigit():
x= (x*10)+ int(side[i])
if x == side[i].isdigit():
x= int(side[i])
else:
op = side[i]
if op=="+":
val += x
elif op == "-":
val -= x
elif op == "*":
val *= x
else:
val /= x
return print(val)
I have edited my compute function.
def evaluate(e):
side1 = ""
side2 = ""
equalsign = e.index("=")
side1= e[:equalsign - 1]
side2= e[:equalsign + 1]
if compute (side1) == compute(side2):
return True
else:
return False
def solve():
# use a for loop with in a for loop to compare all possible pairs
pass
def main():
e= input("Enter an equation: ")
evaluate(e)
main()
For the actual solve function I want to test all possible pairs for each side of the equation and with every pair removed check if the equation is equal to the other side. I was thinking of using a for loop that said:
for i in side1:
j= [:x]+[x+1:y]+[y+1:]
if compute(j)==compute(side2):
val= compute(j)
return val
How should I go about doing this? I'm getting a little confused on how to really approach this program.
Let's get to the preliminary issues.
e = raw_input("Enter an equation: ") # input is fine if you are using Python3.x
side1 = e[:equalsign] #note that a[start:end] does not include a[end]
side2 = e[equalsign + 1:] # not e[:equalsign + 1].
val = int(side[0]) # not val = side[0] which will make val a string
In the operations part, you are doing val += side # or -= / *= / /= .. remember side is a string
Edits:
Yeah, I'm still stuck up with Python 2.7 (use input if Python 3)
To solve for the value of each side, you could simply use eval(side1) # or eval(side2). There could be alternatives to using eval. (I am a novice myself). eval will also take care of PEMDAS.
Added edit to side1 expression.
Updated with code written so far.
def compute(side):
return eval(side)
def evaluate(e):
side1, side2 = e.split('=')
if compute(side1) == compute(side2):
return (True, e)
else:
return (False, 'Not Possible')
def solve(e):
for i in range(len(e)): # loop through user input
if e[i] in '=': # you dont want to remove the equal sign
continue
for j in range(i+1, len(e)): # loop from the next index, you dont want
if e[j] in '=': # to remove the same char
continue # you dont want to remove '=' or operators
new_exp = e[:i] + e[i+1:j] + e[j+1:] # e[i] and e[j] are the removed chars
#print e[i], e[j], new_exp # this is the new expression
s1, s2 = new_exp.split('=')
try:
if compute(s1) == compute(s2):
return (True, new_exp)
except:
continue
return (False, 'not possible')
def main():
e= raw_input("Enter an equation: ")
print evaluate(e.replace(' ', ''))
main()
This is what I have come up with so far (works for your example at least).
It assumes that operators are not to be removed
Final edit: Updated code taking into account #Chronical 's suggestions
Removed the try-except block in each loop and instead just use it after calculating each side
Here is code that does exactly what you want:
from itertools import combinations
def calc(term):
try:
return eval(term)
except SyntaxError:
return None
def check(e):
sides = e.split("=")
if len(sides) != 2:
return False
return calc(sides[0]) == calc(sides[1])
equation = "168/24+8 = 11*3-16".replace(" ", "")
for (a, b) in combinations(range(len(equation)), 2):
equ = equation[:a] + equation[a+1:b] + equation[b+1:]
if check(equ):
print equ
Core tricks:
use eval() for evaluation. If you use this for anything, please be aware of the security implications of this trick.
use itertools.combinations to create all possible pairs of characters to remove
Do not try to handle = too specially – just catch it in check()

Categories

Resources