I am trying to make a script where a '-' is put in between all odd digits in a given number (ie 991453 would be 9-9-145-3), but for some reason python wont allow me to insert a str into a list of integers. The error I keep on getting is 'TypeError: not all arguments converted during string formatting'
My code:
def DashInsert(text):
list_int = map(int, list(text))
for i in xrange(len(list_int)-1):
if (list_int[i] % 2 == 1) and (list_int[i+1] % 2 == 1):
print i
list_int.insert(i+1,'-')
return list_int
Here is my actual input and error:
999472
0
Traceback (most recent call last):
File "DashInsert.py", line 17, in
print DashInsert(string)
File "DashInsert.py", line 11, in DashInsert
if (list_int[i] % 2 == 1) and (list_int[i+1] % 2 == 1):
TypeError: not all arguments converted during string formatting
Your error is because you are modifying the list that you are iterating over. When you insert - into the list, that becomes the target of % and you get a TypeError.
In Python, % is an operator for string formatting and '-' is a string; that is why you get a less than clear error:
>>> '-' % 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting
For strings you use % this way:
>>> 'x %s y %s %i' % ('and', 'is', 13)
'x and y is 13'
The fix to your code is to append to a separate list:
def DashInsert(s):
list_int = map(int, s)
rtr=[]
for i, e in enumerate(list_int[0:-1]):
rtr.append(str(e))
if e % 2 == 1 and list_int[i+1] % 2 == 1:
rtr.append('-')
rtr.append(str(list_int[-1]))
return rtr
You could do this through regex.
>>> import re
>>> s = 991453
>>> re.sub(r'(?<=[13579])(?=[13579])', r'-', str(s))
'9-9-145-3'
I suspect this is horrible code but it works-
number = 991453
number_list = []
for i, item in enumerate(str(number)):
try:
if int(item) % 2 != 0 and int(str(number)[i + 1]) % 2 != 0:
number_list.append(item + '-')
else:
number_list.append(item)
except:
number_list.append(item)
print(''.join(number_list))
Edit: Actually, there's no need to make a list so we can do this-
number = 991453
dash_number = ''
for i, item in enumerate(str(number)):
try:
if int(item) % 2 != 0 and int(str(number)[i + 1]) % 2 != 0:
dash_number += item + '-'
else:
dash_number += item
except:
dash_number += item
print(dash_number)
Edit: Here's how to do it without the try/except.
number = 991453
dash_number = ''
for i, item in enumerate(str(number)[:-1]):
if int(item) % 2 != 0 and int(str(number)[i + 1]) % 2 != 0:
dash_number += item + '-'
else:
dash_number += item
dash_number += str(number)[-1]
print(dash_number)
Related
I'm facing an issue with int has no len.
Below is the code and the issue
def find_pair(inArr):
outStr = -1
for i in range(len(inArr)):
for j in range(i+1, len(inArr)):
if len(set(inArr[i]) | set(inArr[j])) == 6:
if len(inArr[i] + inArr[j]) > len(outStr):
outStr = inArr[i] + inArr[j]
return outStr
inArr = ["30012","250232","53201","3004355","124111"]
print(find_pair(inArr))
The output is below
TypeError Traceback (most recent call last)
<ipython-input-7-6a7c01fe00b4> in <module>
9
10 inArr = ["30012","250232","53201","3004355","124111"]
---> 11 print(find_pair(inArr))
<ipython-input-7-6a7c01fe00b4> in find_pair(inArr)
4 for j in range(i+1, len(inArr)):
5 if len(set(inArr[i]) | set(inArr[j])) == 6:
----> 6 if len(inArr[i] + inArr[j]) > len(outStr):
7 outStr = inArr[i] + inArr[j]
8 return outStr
TypeError: object of type 'int' has no len()
The expected output is
Input: ["30012","250232","53201","3004355","124111"]
Output: 300123004355
And
Input: ["01221","21313","12321"]
Output: -1
Can anyone help me with this issue?
You defined outStr as -1 which is of type integer. I assume you want to define it as an empty string.
As a consequence you have to subtract 1 when comparing - as an empty string has a length of 0.
This modified function returns the desired values:
def find_pair(inArr):
outStr = ""
for i in range(len(inArr)):
for j in range(i + 1, len(inArr)):
if len(set(inArr[i]) | set(inArr[j])) == 6:
if len(inArr[i] + inArr[j]) - 1 > len(outStr):
outStr = inArr[i] + inArr[j]
return outStr or -1
print(find_pair(["30012", "250232", "53201", "3004355", "124111"])) # 300123004355
print(find_pair(["01221", "21313", "12321"])) # -1
in this line if len(inArr[i] + inArr[j]) > len(outStr): you try to do this len(outStr) when outStr = -1 is integer
so of course you can't measure the length of an integer and you get an error
I am trying to make a transposition cipher encryption function for a class project.
from string import ascii_lowercase
def swap(s: str, index0: int, index1: int):
smaller = index0 if index0 < index1 else index1
bigger = index0 if index0 >= index1 else index1
if bigger >= len(s) or smaller < 0:
return None
ret = s[:smaller] + s[bigger] + s[smaller+1:] # swap first
ret = ret[:bigger] + s[smaller] + s[bigger+1:] # swap second
return ret
def swap_encrypt(s: str, key:str):
ret = s
for key_chr in key:
index = ascii_lowercase.index(key_chr)
swap_this = index % len(ret)
with_this = (swap_this + 1) % len(ret)
ret = swap(ret, swap_this, with_this)
return ret
s = ''
key = ''
def main2():
s = input('Enter your message: ')
s = cleanup(s)
key = input('Enter your keyword: ')
key = cleanup(key)
ret= swap_encrypt((s), (key))
print(cleanup(ret))
main2()
I am getting the error 'substring not found', is there something I am doing wrong?
If my input is =(‘SLOTH POWER’) for s, (‘TOP’) for the key, my output should be: ‘RLOTPOHWES’
Is there also another to limit the functions to ord(), len(), and range()? If so, could I be shown how as well?
error:
Traceback (most recent call last):
File "c:\Users\darks\OneDrive\Documents\7\ciphers.py", line 139, in <module>
main2()
File "c:\Users\darks\OneDrive\Documents\7\ciphers.py", line 136, in main2
ret= swap_encrypt((s), (key))
File "c:\Users\darks\OneDrive\Documents\7\ciphers.py", line 123, in swap_encrypt
index = ascii_lowercase.index(key_chr)
ValueError: substring not found
It can't find the character in the ascii_lowercase, because your input is uppercase. Try "sloth power" instead of "SLOTH POWER", or use s.lower().
I need to identify if theres a space between a number and comma then that number is invalid. So if the number has more or less than 2 decimal places and/or white spaces in between the commas then it is INVALID but if it has no whitespaces in between the commas and has 2 decimal places then it it a VALID number. That's why the first number in Line 1 is VALID
There's two methods, I prefer to work on method 2 but I thought if I put two methods it might help any of you to add on
#-----------Method 1------------------------------------------
res = 0
outfile = "output2.txt"
baconFile = open(outfile,"wt")
index = 0
invalid_string = "INVALID"
valid_string = "VALID"
with open('file.txt') as file:
for line in file:
carrera = ''
index = index + 1
print("Line {}: ".format(index), end='')
baconFile.write("Line {}: ".format(index))
number_list = line.strip().split(',')
for number in number_list:
if len(number.split('.')[-1]) == 2:
#res += 1
## print("VALID")
carrera = valid_string
if len(number.split('.')[-1]) != 2:
#res += 1
carrera = invalid_string
if len(number.split(',')[-1]) == " ": #checking for whitespace
carrera = invalid_string
print (carrera, end=' ')
baconFile.write(carrera + " ")
print('\n', end='')
baconFile.write('\n')
baconFile.close()
#-----------Method 2------------------------------------------
res = 0
outfile = "output2.txt"
baconFile = open(outfile,"wt")
index = 0
invalid_string = "INVALID"
valid_string = "VALID"
with open('file.txt') as file:
for line in file:
index = index + 1
o = "Line {}: ".format(index)
number_list = line.strip().split(',')
for x in number_list:
if len(x.split('.')[-1]) == 2:
o += valid_string + " "
if len(x.split('.')[-1]) != 2:
o += invalid_string + " "
if len(x.split(',')[-1]) == " ":
o += valid_string + " "
Here's my list of numbers in Text.file:
1,1.02, 123.0005
1.02, 1.02 , 1.02
Expected:
Line 1: INVALID VALID INVALID
Line 2: VALID INVALID INVALID (since there's spaces between the last number that's why it is INVALID)
ACTUAL:
Line 1: INVALID VALID INVALID
Line 2: VALID INVALID VALID
You can split the strings with , and decide if the string is valid or invalid based on whether the string stars with a whitespace
#Open the files
with open('file.txt') as fp:
#Extract out non-empty lines from file
lines = [line for line in fp.readlines() if line.strip()]
res = []
#Iterate over the lines
for idx, line in enumerate(lines):
#Number is valid if it doesn't start with a whitespace, has a decimal part and the decimal part is two digits long
res = ['VALID' if not item.startswith(' ') and '.' in item and len(item.split('.')[1]) == 2 else 'INVALID' for item in line.split(',')]
#Print the result
print("Line {}: {}".format(idx+1, ' '.join(res)))
The output will be
Line 1: INVALID VALID INVALID
Line 2: VALID INVALID INVALID
try this:
line="1,1.02, 123.0005"
reslt=line.split(",")
Res=" "
for i in reslt:
if " "in i:
line1="INVALID "
else:
line1="VALID "
Res +="".join(line1)
print("line1:"+Res)
READ from file :
nbline
with open('file.txt') as f:
for line in f.readlines():
print(line)
reslt=line.split(",")
Res=" "
for i in reslt:
if " "in i:
line1="INVALID "
else:
line1="VALID "
Res +="".join(line1)
nbline = nbline+1
print("line {}:{}".format(nbline,Res))
output:
line1: VALID VALID INVALID
A list comprehension based on splitting on commas, and a little string trickery would be much simpler:
line="1,1.02, 123.0005"
result = " ".join("IN"*(" " in s)+"VALID" for s in line.split(","))
print(result) # VALID VALID INVALID
With decimal.Decimal object, you can retrieve the exponent, which somehow tells you the number of decimal places (see docs):
import decimal
o += " ".join(['INVALID' if x[0] == ' ' or decimal.Decimal(x).as_tuple().exponent != -2 else 'VALID' for x in line.split(',')])
Output
#with line = "1,1.02, 123.0005"
'Line 1: INVALID VALID INVALID'
#with line = "1.02, 1.02 , 1.02"
'Line 2: VALID INVALID INVALID'
def cipherText():
text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
key = int(input("Enter numerical key--"))
word = str(input("Type word to be ciphered--"))
i = 0
k = 0
n = len(word)
print(n)
while n >= 0:
letter = word[i]
i = i + 1
while k <= 25:
textLetter = text[k]
if textLetter == letter:
givenLetter = letter
if k < (25 - key):
cipherLength = k + key
else:
cipherLength = k + key - 25
print(text[cipherLength])
k = k + 1
n = n - 1
cipherText()
WHEN I RUN THIS FOLLOWING MESSAGE POPS OUT:
Traceback (most recent call last): File "main.py", line 23, in
cipherText() File "main.py", line 10, in cipherText
letter=word[i] IndexError: string index out of range
You need to modify condition while n>=0:, as list starts with 0th index.
this line,
while n>=0:
should be,
while n-1>=0:
I don't know why I keep getting the error "string index out of range" and another error on line 47 print_data(data. Can someone please explain why? Thank you
def open_file():
user_input = input('Enter a file name: ')
try:
file = open(user_input, 'r')
return file
except FileNotFoundError:
return open_file()
def read_data(file):
counter = [0 for _ in range(9)]
for line in file.readlines():
num = line.strip()
if num.isdigit():
i = 0
digit = int(num[i])
while digit == 0 and i < len(num):
i += 1
digit = int(num[i])
if digit != 0:
counter[digit - 1] += 1
return counter
def print_data(data):
benford = [30.1, 17.6, 12.5, 9.7, 7.9, 6.7, 5.8, 4.1, 4.6]
header_str = "{:5s} {:7s}{:8s}"
data_str = "{:d}:{:6.1f}% ({:4.1f}%)"
total_count = sum(data)
print(header_str.format("Digit", "Percent", "Benford"))
for index, count in enumerate(data):
digit = index + 1
percent = 100 * count / total_count
print(data_str.format(digit, percent, benford[index]))
def main():
file = open_file()
data = read_data(file)
print_data(data)
file.close()
if __name__ == "__main__":
main()
This is the exact error I'm given
Traceback (most recent call last):
File "./lab08.py", line 52, in <module>
main()
File "./lab08.py", line 47, in main
data = read_data(file)
File "./lab08.py", line 26, in read_data
digit = int(num[i])
I believe the error stems from this:
while digit == 0 and i < len(num):
i += 1
digit = int(num[i])
If you swap the second two lines, you will properly index, i.e.:
while digit == 0 and i < len(num):
digit = int(num[i])
i += 1
If, for example, your string num is of length 10, then the final element is at index 9 (indexing from 0). for the first iteration of that loop, you will have digit be num[1], for the tenth iteration you would have it be num[10].
An alternative method would be to use list comprehension like this:
for n in num:
if digit != 0:
break
digit = int(n)