I need to encrypt a message. The message follows, it is saved in a file named assignmenttest.txt
Hi my name is Allie
I am a Junior
I like to play volleyball
I need the program to encrypt each line and keep it's format so that So, I wrote the following program:
fileInputName = input("Enter the file you want to encrypt: ")
key = int(input("Enter your shift key: "))
outputFileName = input("Enter the file name to write to: ")
fileInputOpen = open(fileInputName, "r")
message = fileInputOpen.read()
alphabet = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
shiftedStart = alphabet[len(alphabet) - key:]
shiftedEnd = alphabet[:len(alphabet) - key]
shiftedAlphabet = shiftedStart + shiftedEnd
encryptedMessage = ""
for character in message:
letterIndex = message.split("\n")
letterIndex = alphabet.find(character)
encryptedCharacter = shiftedAlphabet[letterIndex]
#print( "{0} -> {1}".format(character, encryptedCharacter))
encryptedMessage += encryptedCharacter
print("The encrypted message is: {0}".format(encryptedMessage))
outputFile = open( outputFileName, "w")
print(encryptedMessage, file=outputFile)
outputFile.close()
print("Done writing encrypted message to file {0}".format(outputFileName))
I tried to use a split at \n, but the output is not formatted in three separate lines, instead it is all just one long string of encrypted letters.
Any ideas on how to split the encrypted message at the correct spot and have it display as such? I've tried multiple split methods and none have worked. Thank you so much.
As the other answers have said, you can replace
fileInputOpen = open(fileInputName, "r")
message = fileInputOpen.read()
with
with open(fileInputName, "r") as f:
messages = f.readlines()
This way, messages will be a list of strings, where each string is the text from a single line in your input file. Then, with some slight modifications to your loop over each character in messages, you can encrypt each string from your messages list. Here, I replaced your encryptedMessage with currentEncryptedMessage and added encryptedMessages, a list that keeps track of the encrypted version of each string in messages.
encryptedMessages = []
currentEncryptedMessage = ""
for message in messages:
for character in message:
... # same as code provided
currentEncryptedMessage += encryptedCharacter
encryptedMessages.append(currentEncryptedMessage)
When writing to your file, you can iterate through each element in encryptedMessages to print line-by-line.
with open( outputFileName, "w") as outputFile:
for message in encryptedMessages:
print(message, file=outputFile)
And so your output text file will preserve the line breaks from your input file.
Instead of splitting at '\n', you can append all the characters in message that are not in alphabet to encryptedMessage when you encounter one.
for character in message:
if !(character in alphabet):
encryptedMessage += character
continue # this takes back to begin of the loop
letterIndex = alphabet.find(character)
encryptedCharacter = shiftedAlphabet[letterIndex]
#print( "{0} -> {1}".format(character, encryptedCharacter))
encryptedMessage += encryptedCharacter
Try changing:
message = fileInputOpen.read()
to
message = fileInputOpen.readlines()
This will make your file reads handle the file line by line. This will allow you to do your processing on a line by line basis first. Beyond that, If you want to encrypt each character, you'll need another for loop for the characters.
Instead of reading the file all at once. Read the lines individually.
f = open("file.txt")
for i in f.readlines():
print (i)
You'll have to loop each line and every character you want to
un-shift;
The script should only un-shift characters present in alphabet;
Checking for file existence is also a must or you may get errors if it doesn't exist.
with open... is the recommended way of reading and writing files in python.
Here's an approach:
import os
import string
fileInputName = input("Enter the file you want to encrypt: ")
while not os.path.exists(fileInputName):
fileInputName = input("{} file doesn't exist.\nEnter the file you want to encrypt : ".format(fileInputName))
key = int(input("Enter your shift key (> 0): "))
while key < 1 :
key = int(input("Invalid shift key value ({}) \nEnter your shift key (> 0): ".format(key)))
fileOutputName = input("Enter the file name to write to: ")
if os.path.exists(fileOutputName) :
ow = input("{} exists, overwrite? (y/n): ".format(fileOutputName))
if not ow.startswith("y"):
fileOutputName = input("Enter the file name to write to: ") # asks for output filename again
alphabet = string.ascii_letters + " "
shiftedStart = alphabet[len(alphabet) - key:]
shiftedEnd = alphabet[:len(alphabet) - key]
shiftedAlphabet = shiftedStart + shiftedEnd
with open(fileOutputName, "a") as outputFile: # opens out file
with open(fileInputName, "r") as inFile: # opens in file
for line in inFile.readlines(): # loop all lines in fileInput
encryptedCharacter = ""
for character in line: # loop all characters in line
if character in alphabet: # un-shift only if character is present in `alphabet`
letterIndex = alphabet.find(character)
encryptedCharacter += shiftedAlphabet[letterIndex]
else:
encryptedCharacter += character # add the original character un-shifted
outputFile.write("{}".format(encryptedCharacter)) # append line to outfile
Related
I am having trouble with matching variables to lines in txt, and removing the lines.
I am currently doing a hotel room booking program in which I am having trouble removing a booking from my text file.
This is how my lines in my text file are formatted:
first_name1, phonenumber1 and email 1 are linked to entry boxes
jeff;jeff#gmail.com;123123123;2019-06-09;2019-06-10;Single Room
def edit_details(self,controller):
f = open("Bookings.txt")
lines = f.readlines()
f.close()
x = -1
for i in lines:
x += 1
data = lines[x]
first_name1 = str(controller.editName.get())
phonenumber1 = str(controller.editPhone.get())
email1 = str(controller.editEmail.get())
checkfirst_name, checkemail, checkphone_num, checkclock_in_date, checkclock_out_date, checkroom = map(str, data.split(";"))
if checkfirst_name.upper() == first_name1.upper() and checkemail.upper() == email1.upper() and checkphone_num == phonenumber1:
controller.roomName.set(checkfirst_name)
controller.roomEmail.set(checkemail)
controller.roomPhone.set(checkphone_num)
controller.roomCheckin.set(checkclock_in_date)
controller.roomCheckout.set(checkclock_out_date)
controller.roomSelect.set(checkroom)
print(controller.roomName.get())
print(controller.roomSelect.get())
controller.show_frame("cancelBooking")
break
elif x > len(lines) - int(2):
messagebox.showerror("Error", "Please Enter Valid Details")
break
I have the user to enter their details to give me the variables but I don't know how to match these variables to the line in the text file to remove the booking.
Do I have to format these variables to match the line?
This is what i have tried but it deletes the last line in my file
line_to_match = ';'.join([controller.roomName.get(),controller.roomEmail.get(),controller.roomPhone.get()])
print(line_to_match)
with open("Bookings.txt", "r+") as f:
line = f.readlines()
f.seek(0)
for i in line:
if i.startswith(line_to_match):
f.write(i)
f.truncate()
I have kind of added a pseudocode here. You can join the variables using ; and validate if the line startswith those details, like below.
first_name1, phonenumber1, email1 = 'jeff', 'jeff#gmail.com', '123123123'
line_to_match = ';'.join([first_name1, email1, phonenumber1])
for i in line:
...
if i.startswith(line_to_match):
# Add your removal code here
...
I am new to python and am stuck on the task below. Below is an example of my input file and what I want it to output.
Input File Message (from online sample)
So pure of heart
And strong of mind
So true of aim with his marshmallow laser
Marshmallow laser
Output File Message
LhtinkXthYtaXTkm
ugWtlmkhgZthYtfbgW
LhtmknXthYtTbftpbmatabltfTklafTeehpteTlXk
FTklafTeehpteTlXk
Below is my syntax and guidance as to why it isn't completing the task intended would be helpful. It is printing 'wwww'....I believe it is a 'w' for each line.
inputFileName = input("Enter the message to encrypt: ")
key = int( input("Enter the shift key: " ))
outputFileName = input("Enter the output file name: " )
infile=open(inputFileName,"r")
outfile = open( outputFileName, "w" )
sequence=infile.readlines()
alphabet = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
shiftedAlphabetStart = alphabet[len(alphabet) - key:]
shiftedAlphabetEnd = alphabet[:len(alphabet) - key]
shiftedAlphabet = shiftedAlphabetStart + shiftedAlphabetEnd
print( alphabet )
print( shiftedAlphabet )
encryptedMessage = ''
for character in sequence:
letterIndex = alphabet.find( character )
encryptedCharacter = shiftedAlphabet[letterIndex]
#print( "{0} -> {1}".format( character, encryptedCharacter ) )
encryptedMessage = encryptedMessage + encryptedCharacter
print( "The encrypted message is: {0}".format( encryptedMessage ))
If you print(sequence), you'll realize that it's a List of lines, not a string.
So when you iterate through it with for character in sequence:, you're not iterating through the original text character by character, you're iterating through the list line by line.
This is because readlines() return a list of lines.
You can, if you still want to use readlines(), try adding something like:
original_text = ''
for line in sequence:
original_text += line
A better way however, is to simply change sequence = infile.readlines() to sequence = infile.read().
This program is supposed to replace the letters ö,ä,õ,ü with different letters. After completing one row it produces an empty row and I don't know why. I have tried to understand it for some time, but I couldn't really understand why it doesn't give me desired output.
f = input("Enter file name: ")
file = open(f, encoding="UTF-8")
for sentence in file:
sentence = sentence.upper()
for letter in sentence:
if letter == "Ä":
lause = sentence.replace(letter, "AE")
elif letter == "Ö" or täht == "Õ":
lause = sentence.replace(letter, "OE")
elif letter == "Ü":
lause = sentence.replace(letter, "UE")
print(sentence)
Reading each line in includes the trailing newline. Your print() also includes a newline so you will get an empty row. Try print(sentence, end='') as follows:
filename = input("Enter file name: ")
with open(filename, encoding="UTF-8") as f_input:
for sentence in f_input:
sentence = sentence.upper()
for letter in sentence:
if letter == "Ä":
lause = sentence.replace(letter, "AE")
elif letter == "Ö" or täht == "Õ":
lause = sentence.replace(letter, "OE")
elif letter == "Ü":
lause = sentence.replace(letter, "UE")
print(sentence, end='')
Note: using with open(... will also automatically close your file afterwards.
You might also want to consider the following approach:
# -*- coding: utf-8
filename = input("Enter file name: ")
replacements = [('Ä', 'AE'), ('ä', 'ae'), ('Ö', 'OE'), ('ö', 'oe'), ('Õ', 'OE'), ('õ', 'oe'), ('Ü', 'UE'), ('ü', 'ue')]
with open(filename, encoding='utf-8') as f_input:
text = f_input.read()
for from_text, to_text in replacements:
text = text.replace(from_text, to_text)
print(text)
This does each replacement on the whole text rather than line by line. It also preserves the case.
I won't fix your program, just try to answer why it doesn't do what you are expecting:
The program doesn't run: in line 14 the variable "täht" might be a typo, supposed to be "letter"
You store the result of replace() in variable "lause" but never use it
by default print() adds "\n" at the end, but you can override it (see help(print) in the python shell)
I've created a function and got stuck on it.
Meaning of the function:
User types in a file, number and own name.
Program writes the name at the end of the file 'number' times.
And just prints out contents of the file.
What's the problem?
There are strange characters and a big space under it when program reads the file.
Like this: 圀漀爀氀搀眀椀搀攀㬀 ㈀ 㐀 ⴀ 瀀爀攀猀攀渀琀ഀഀ (and then there is a huge space for 10-15 lines in Powershell)
Error: 'str' object has no attribute 'close'.
def filemania():
print "Great! This way is called \"Filemania\""
file_name = raw_input("Type in any text file> ")
enter_1 = int(raw_input("Enter an integer> "))
enter_2 = raw_input("Enter your name> ")
print "Now your name will apear in the file %d times at the end" % enter_1
open_file = open(file_name, 'a+')
listok = []
while len(listok) < enter_1:
open_file.write(enter_2 + " ")
listok.append(enter_2)
print "Contains of the file:"
read_file = open_file.read()
print read_file
file_name.close()
filemania()
I think the problem is somewhere here:
open_file = open(file_name, 'a+')
Does somebody know how to solve these problems?
Firstly you set file_name = raw_input("Type in any text file> ") so you are trying to close a string with file_name.close():
When you write to open_file you move the pointer to the end of the file because you are appending so read_file = open_file.read() is not going to do what you think.
You will need to seek to the start of the file again to print the content, open_file.seek(0).
def filemania():
print "Great! This way is called \"Filemania\""
file_name = raw_input("Type in any text file> ")
enter_1 = int(raw_input("Enter an integer> "))
enter_2 = raw_input("Enter your name> ")
print "Now your name will apear in the file %d times at the end" % enter_1
# with automatically closes your files
with open(file_name, 'a+') as open_file:
listok = []
# use range
for _ in range(enter_1):
open_file.write(enter_2 + " ")
listok.append(enter_2)
print "Contains of the file:"
# move pointer to start of the file again
open_file.seek(0)
read_file = open_file.read()
print read_file
filemania()
For your second error, you are trying to close file_name, which is the raw input string. You mean to close open_file
Try that and report back.
The goal of this code is to find the frequency of words used in a book.
I am tying to read in the text of a book but the following line keeps throwing my code off:
precious protégés. No, gentlemen; he'll always show 'em a clean pair
specifically the é character
I have looked at the following documentation, but I don't quite understand it: https://docs.python.org/3.4/howto/unicode.html
Heres my code:
import string
# Create word dictionary from the comprehensive word list
word_dict = {}
def create_word_dict ():
# open words.txt and populate dictionary
word_file = open ("./words.txt", "r")
for line in word_file:
line = line.strip()
word_dict[line] = 1
# Removes punctuation marks from a string
def parseString (st):
st = st.encode("ascii", "replace")
new_line = ""
st = st.strip()
for ch in st:
ch = str(ch)
if (n for n in (1,2,3,4,5,6,7,8,9,0)) in ch or ' ' in ch or ch.isspace() or ch == u'\xe9':
print (ch)
new_line += ch
else:
new_line += ""
# now remove all instances of 's or ' at end of line
new_line = new_line.strip()
print (new_line)
if (new_line[-1] == "'"):
new_line = new_line[:-1]
new_line.replace("'s", "")
# Conversion from ASCII codes back to useable text
message = new_line
decodedMessage = ""
for item in message.split():
decodedMessage += chr(int(item))
print (decodedMessage)
return new_line
# Returns a dictionary of words and their frequencies
def getWordFreq (file):
# Open file for reading the book.txt
book = open (file, "r")
# create an empty set for all Capitalized words
cap_words = set()
# create a dictionary for words
book_dict = {}
total_words = 0
# remove all punctuation marks other than '[not s]
for line in book:
line = line.strip()
if (len(line) > 0):
line = parseString (line)
word_list = line.split()
# add words to the book dictionary
for word in word_list:
total_words += 1
if (word in book_dict):
book_dict[word] = book_dict[word] + 1
else:
book_dict[word] = 1
print (book_dict)
# close the file
book.close()
def main():
wordFreq1 = getWordFreq ("./Tale.txt")
print (wordFreq1)
main()
The error that I received is as follows:
Traceback (most recent call last):
File "Books.py", line 80, in <module>
main()
File "Books.py", line 77, in main
wordFreq1 = getWordFreq ("./Tale.txt")
File "Books.py", line 60, in getWordFreq
line = parseString (line)
File "Books.py", line 36, in parseString
decodedMessage += chr(int(item))
OverflowError: Python int too large to convert to C long
When you open a text file in python, the encoding is ANSI by default, so it doesn't contain your é chartecter. Try
word_file = open ("./words.txt", "r", encoding='utf-8')
The best way I could think of is to read each character as an ASCII value, into an array, and then take the char value. For example, 97 is ASCII for "a" and if you do char(97) it will output "a". Check out some online ASCII tables that provide values for special characters also.
Try:
def parseString(st):
st = st.encode("ascii", "replace")
# rest of code here
The new error you are getting is because you are calling isalpha on an int (i.e. a number)
Try this:
for ch in st:
ch = str(ch)
if (n for n in (1,2,3,4,5,6,7,8,9,0) if n in ch) or ' ' in ch or ch.isspace() or ch == u'\xe9':
print (ch)