how to fix ValueError: list index out of range - python-3.x

I keep getting this error:
line 23, in encode
raw_out[i][pos] = message[pos]
IndexError: list index out of range
for this part of the program:
def encode(message: str, key: int) -> str:
"""
Encode text using Rail-fence Cipher.
Replace all spaces with '_'.
:param message: Text to be encoded.
:param key: Encryption key.
:return: Decoded string.
"""
message = message.replace(" ", "_")
down = True
raw_out = []
out = ''
i = 0
for x in range(key):
raw_out.append({})
for pos in range(len(message)):
raw_out[i][pos] = message[pos]
if i == key - 1:
down = False
if i == 0:
down = True
if down:
i = i + 1
else:
i = i - 1
for p in raw_out:
for q in p:
out += p[q]
return out
I'm not sure how to fix the error. Any ideas?

When key is one or when the key is bigger than the length of the string return the string as it is. Doesn't make sense to do any processing.
right after the line
message = message.replace(" ", "_")
you can check for the condition
if key == 1 or key > len(message):
return message

Related

Function to read specified single column from a csv file in python without using libraries and it should return column name and values into list

Getting error "TypeError: 'list' object is not callable", I have changed the parenthesis into square bracket but still not working.
def getColumnType(value):
dataType = None;
try:
numericVal = int(value)
dataType =int;
except ValueError:
numericVal = float(value)
dataType = float;
return dataType
def extractColFromFile(fileName,colIdx):
try:
columnName = ""
datalist = []
with open(fileName) as file:
firstLine = file.readline().strip()
colCount = firstLine.count(',') + 1
contents = [x.strip() for x in file.readlines()]
floatCount = 0
if colIdx in range(0,colCount):
columnName = firstLine.split(',')[colIdx]
for line in contents:
columns = line.split(',')
for idx,data in enumerate(columns):
if (idx == colIdx):
if(getColumnType(data) == float):
floatCount += 1
datalist.append(data)
if( floatCount > 0):
classType = float
else:
classType = int
result = list(map(classType, datalist))
return columnName, result
else:
print("invalid column index value");
except OSError as e:
print(e)
x = int(input("Enter a number: "))
result = extractColFromFile("task1.csv",x)
print (result)

White Spaces issue while converting to binary

I'm implementing A5/1 algorithm, I have the following function:
def to_binary(plain):
print(plain)
binary = str(''.join(format(ord(x), 'b') for x in plain))
j = len(binary)
binary_values = []
k = 0
while(k < j):
binary_values.insert(k,int(binary[k]))
k = k + 1
return(binary_values)
then I'm reading the input as the following:
plainText = input("Please enter your plaintext : ")
print ("You entered : "+ plainText)
plainText = to_binary(plainText)
After that I generate a keyStream and I store it in a list, then I obtain the ciphered text as the following:
while(i < len(plainText)):
cipherText = cipherText + str(plainText[i] ^ keyStream[i])
i = i + 1
Now I can decrypt the ciphered text using the following function:
def decrypt(cipher,keystream):
s = ""
binary = []
i = 0
while(i<len(cipher)):
binary.insert(i,int(cipher[i]))
s = s + str(binary[i]^keystream[i])
i = i +1
print(s)
return convert_binary_to_str(s)
and the convert_binary_to_str function is:
def convert_binary_to_str(bin_data):
str_data =' '
for i in range(0, len(bin_data), 7):
temp_data = bin_data[i:i + 7]
decimal_data = BinaryToDecimal(temp_data)
str_data = str_data + chr(decimal_data)
return str_data
Everything is working fine if the input was a sentence with no white spaces, but if the sentence was for example "Hello There", the decryption is corrupted because the white space representation in binary this way is taking "6 bits" while the other alphabetical characters are "7-bits" long, what can I do to solve this?? I need to store the plain text in a list to apply the algorithm.

Encryption algorithm randomly replaces some letters

I have the following python code:
file = open("encryption.txt","r")
str1 = file.read()
file.close
charList = []
for char in str1:
charList.append(char)
bits = []
ascList = []
for i in range(len(charList)):
ascList.append(ord(charList[i]))
ascList[i] = "{0:08b}".format(ascList[i])
currentAsc = ascList[i]
currentStr = str(currentAsc)
for x in range(len(currentStr)):
currentChar = currentStr[x]
bits.append(int(currentChar))
keyChar = input("enter the character that should act as the key: ")
keyAsc = "{0:08b}".format(ord(keyChar))
keyStr = str(keyAsc)
keyBits = []
for x in range(len(keyStr)):
keyBits.append(int(keyStr[x]))
key = []
while len(key) != len(bits):
for i in range(len(keyBits)):
key.append(keyBits[i])
resultBits = []
for i in range(len(bits)):
if key[i] != bits[i]:
resultBits.append("1")
else:
resultBits.append("0")
resultSplitInt = []
resultInt = ''.join(resultBits)
for i in range(0,len(resultInt), 8):
resultSplitInt.append(resultInt[i:i+8])
resultSplit = []
for i in range(len(resultSplitInt)):
resultSplit.append(chr(int(resultSplitInt[i],2)))
result = ''.join(resultSplit)
file = open("encryption.txt","w")
print(str1)
print("--------------------")
print(result)
file.write(result)
print("done")
file.close()
running the program once should change the contents of "encryption.txt" based on the key, and running the program again should return the contents to their original form.
however, when I actually run the code, some letters are swapped out.
for example:
if the contents are "hello world"
and I use the key "a"
after running the code twice I am left with "hekko workd"
why does this happen, and how can I fix it?
p.s. I am aware that this is neither a secure encryption algorithm nor is my code very efficient. I am new to python and thought this would be a fun task to try. I got this far and can't find any reasons why it isn't working
Since you operate outside ASCII range, you should open the file in binary mode: open("encryption.txt","rb") and open("encryption.txt","wb")
However, in binary mode you get a byte array from the file, not a string:
file = open("encryption.txt","rb")
str1 = file.read()
file.close()
charList = []
for char in str1:
charList.append(char)
bits = []
ascList = []
for i in range(len(charList)):
ascList.append(charList[i])
ascList[i] = "{0:08b}".format(ascList[i])
currentAsc = ascList[i]
currentStr = str(currentAsc)
for x in range(len(currentStr)):
currentChar = currentStr[x]
bits.append(int(currentChar))
keyChar = input("enter the character that should act as the key: ")
keyAsc = "{0:08b}".format(ord(keyChar))
keyStr = str(keyAsc)
keyBits = []
for x in range(len(keyStr)):
keyBits.append(int(keyStr[x]))
key = []
while len(key) != len(bits):
for i in range(len(keyBits)):
key.append(keyBits[i])
resultBits = []
for i in range(len(bits)):
if key[i] != bits[i]:
resultBits.append("1")
else:
resultBits.append("0")
resultSplitInt = []
resultInt = ''.join(resultBits)
for i in range(0,len(resultInt), 8):
resultSplitInt.append(resultInt[i:i+8])
resultSplit = []
for i in range(len(resultSplitInt)):
resultSplit.append(chr(int(resultSplitInt[i],2)))
result = ''.join(resultSplit)
file = open("encryption.txt","wb")
print(str1)
print("--------------------")
print(result)
file.write(result.encode())
print("done")
file.close()
Close the file;
file = open("encryption.txt","r")
str1 = file.read()
file.close()
Then it works.
By the way, at least use 'a'='A'

Caesar Cipher shift on new lines

I am having a problem with my code trying to do an advanced caesar cipher shift. I changed a certain letter to another, and then added a string to certain parts of a file before encoding, but am having problems doing the shifting now. This is my code:
import string
import sys
count = 1
cont_cipher = "Y"
#User inputs text
while cont_cipher == "Y":
if count == 1:
file = str(input("Enter input file:" ""))
k = str(input("Enter shift amount: "))
purpose = str(input("Encode (E) or Decode (D) ?: "))
#Steps to encode the message, replace words/letter then shift
if purpose == "E":
my_file = open(file, "r")
file_contents = my_file.read()
#change all "e"s to "zw"s
for letter in file_contents:
if letter == "e":
file_contents = file_contents.replace(letter, "zw")
#add "hokie" to beginning, middle, and end of each line
lines = file_contents.split('\n')
def middle_message(lines, position, word_to_insert):
lines = lines[:position] + word_to_insert + lines[position:]
return lines
new_lines = ["hokie" + middle_message(lines[x], len(lines[x])//2, "hokie") + "hokie" for x in range(len(lines))]
#math to do the actual encryption
def caesar(word, shifts):
word_list = list(new_lines)
result = []
s = 0
for c in word_list:
next_ord = ord(c) + s + 2
if next_ord > 122:
next_ord = 97
result.append(chr(next_ord))
s = (s + 1) % shifts
return "".join(result)
if __name__ == "__main__":
print(caesar(my_file, 5))
#close file and add to count
my_file.close()
count = count + 1
The error I am getting is:
TypeError: ord() expected a character, but string of length 58 found
I know that I need to split it into individual characters, but am not sure how to do this. I need to use the updated message and not the original file in this step...

Python - Receiving an TypeError

So the code below:
Takes a given square, and if it is an X does nothing. If the square has an O in it, it changes the O to an X and autofills the square above, below, to the left, and to the right.
#openFile(filename): This function opens and prints the users txt file for paint
#input: none
#output: The file that needs to be painted
def openFile(filename):
file = open(filename, 'r')
for line in file:
print(line)
file.close()
#convertFile(filename): This function is used to convert the .txt file into a 2D arrary
#input: none
#output: none
def convertFile(filename):
empty = []
filename = open(filename, 'r')
for line in filename:
line = line.rstrip("\n")
empty.append(list(line))
return empty
#getCoordinates(x,y): This function is used to get the coordinates the user wants to pain from
#input: user coordinates.
#output: none
def getCoordinates(x, y):
coordinates = []
userInt = 0
user = []
try:
user = input("Please enter a square to fill , or q to exit: ")
user.split()
coordinates.append(int(user[0]))
coordinates.append(int(user[2]))
except ValueError:
print("Enter a valid input!")
user = input("Please enter a square to fill, or q to exit: ")
user.split()
coordinates.append(int(user[0]))
coordinates.append(int(user[2]))
return coordinates
def printGrid(grid):
for innerList in grid:
for item in innerList:
print(item, end = "")
print()
#autoFill(board, row, col): This is the heart of the program and the recursive program
# use to fill the board with x's
#input: none
#output: none
def autoFill(grid, rows, cols):
if grid[cols][rows] == "X":
return 0
else:
grid[cols][rows] = "X"
if rows > 0:
autoFill(grid, rows - 1, cols)
if rows < len(grid[cols]) - 1:
autoFill(grid, rows + 1, cols)
if cols > 0:
autoFill(grid, rows, cols - 1)
if cols < len(grid) - 1:
autoFill(grid, rows, cols + 1)
def main():
coordinates = []
empty = []
while True:
filename = input("Please enter a filename: ")
openFile(filename)
empty = convertFile(filename)
coordinates = getCoordinates(len(empty), len(empty[0]))
empty = autoFill(empty(coordinates[0], coordinates[1]))
for item in empty:
s = ""
s.join(item)
for x in item:
s += str(x)
print(s)
if user == "q":
return 0
main()
output should look like:
Please enter a filename: input.txt
OOOOOOXOOOO
OOOOOXOOOOO
OOOOXOOOOOO
XXOOXOOOOOO
XXXXOOOOOOO
OOOOOOOOOOO
Please enter a square to fill, or q to exit: 1, 1
XXXXXXXOOOO
XXXXXXOOOOO
XXXXXOOOOOO
XXXXXOOOOOO
XXXXOOOOOOO
OOOOOOOOOOO
But when i type in the coordinate points i get:
empty = autoFill(empty(coordinates[0], coordinates[1]))
TypeError: 'list' object is not callable
Any guidance in fixing this issue will be much appreciated
The particular error you're asking about is happening because you're trying to call empty (which is a list, as returned by convertFile) as if it were a function.

Resources