EDIT: Completely fixed now.
EDIT: Okay so now I got it to change '... --- ...' to 'sos' (yippee!) But for some reason, it gives me a KeyError when I input '... --- ... / ... --- ...'.
This should give me 'sos sos' but I get a KeyError for ' '.
I think this is because after the '/', there's a space which the program sees as a trigger to call the dictionary value of the current key. Problem being, the current key at that time is blank since the previous character was the '/'. How would I be able to fix this?
Thanks.
I'm pretty new to programming with python (well, programming in general, really...) and today I had the bright idea of making a morse code converter.
I have the "plain text to morse code" working flawlessly, but the "morse code to plain text"?
Not so much.
The problem is that when I run the program, it doesn't give me anything, it just breaks its loop (like I told it to) without anything coming back to me.
If you guys could help me out, I'd very much appreciate it.
Oh also, 'decoding_dict' is the dictionary which I made which correlates morse code values to plain text.
For example,
decoding_dict = {'...' : 's' , '---' : 'o'}
And so on and so forth.
def decode(text):
text += ' '
#I have it set up to trigger when there's a space, hence this.
global key
global decoded_text
#I thought maybe this would fix it, it didn't. :(
key = ''
decoded_text = ''
for i in text:
if i == '.':
key += i #This adds a '.' to the key to reference later.
continue
elif i == '-':
key += i #See above comment.
continue
elif i == ' ':
decoded_text += decoding_dict[key]
text = text[(len(key) + 1) :]
key = '' #Calls the value of the key, cuts out the used text, and resets key.
continue
elif i == '/':
decoded_text += decoding_dict['/']
continue #In morse code, a '/' is a ' ' and that's in the dict.
elif text == '':
print "Result: " + decoded_text
break #This is basically the end of the loop
else:
print "Error, please try again."
break
Now when I run it with '... --- ...' , it goes back to the beginning and doesn't print anything.
(By beginning, I mean the menu I made beforehand.)
According to your code try something like this:-
def decode(text):
text += '$'
#I have it set up to trigger when there's a space, hence this.
global key
global decoded_text
#I thought maybe this would fix it, it didn't. :(
key = ''
decoded_text = ''
for i in text:
if i == '.':
key += i #This adds a '.' to the key to reference later.
continue
elif i == '-':
key += i #See above comment.
continue
elif i == ' ':
decoded_text += decoding_dict[key]
text = text[(len(key) + 1) :]
key = '' #Calls the value of the key, cuts out the used text, and resets key.
continue
elif i == '/':
decoded_text += decoding_dict['/']
continue #In morse code, a '/' is a ' ' and that's in the dict.
elif text == '$':
print "Result: " + decoded_text
break #This is basically the end of the loop
else:
print "Error, please try again."
break
According to My Suggestion Try This:-
def decode(text):
error = False
#I have it set up to trigger when there's a space, hence this.
global key
global decoded_text
#I thought maybe this would fix it, it didn't. :(
key = ''
decoded_text = ''
for i in text:
if i == '.':
key += i #This adds a '.' to the key to reference later.
continue
elif i == '-':
key += i #See above comment.
continue
elif i == ' ':
decoded_text += decoding_dict[key]
text = text[(len(key) + 1) :]
key = '' #Calls the value of the key, cuts out the used text, and resets key.
continue
elif i == '/':
decoded_text += decoding_dict['/']
continue #In morse code, a '/' is a ' ' and that's in the dict.
else:
print "Error, please try again."
error = True
break
else:
If not error:
print "Result: " + decoded_text
Last else is used with for instead of if else
Assuming space ' ' is a separator in the input you specify, you may use this:
decoding_dict = {'...' : 's' , '---' : 'o'}
my_text = '... --- ...'
print(''.join(list(map(lambda x: decoding_dict.get(x, None),
Output:
sos
As for the code above, there are couple of issues:
modifying 'text' while iterating over it
checking if text == '', which never happens. Hence, the result is never printed.
Try this:
def decode(text):
text += ' '
#I have it set up to trigger when there's a space, hence this.
global key
global decoded_text
#I thought maybe this would fix it, it didn't. :(
key = ''
decoded_text = ''
for i in text:
if i == '.':
key += i #This adds a '.' to the key to reference later.
continue
elif i == '-':
key += i #See above comment.
continue
elif i == ' ':
decoded_text += decoding_dict[key]
key = '' #Calls the value of the key, cuts out the used text, and resets key.
continue
elif i == '/':
decoded_text += decoding_dict['/']
continue #In morse code, a '/' is a ' ' and that's in the dict.
else:
print("Error, please try again.")
break
print("Result: " + decoded_text)
call: decode(my_text)
Output:
Result: sos
The for loop only considers the initial value of text. Your changes to text in the loop have no effect, because text is a string, and strings are immutable, so your modifications don't modify the original object that you're iterating over. The result is that your loop iterates over all of the original text, completing the loop without ever entering either of your break conditions.
Just get rid of the if text == '' check and move the "print results" line outside the for loop. You don't need to "cut out the used text", because by the time you get to the point where you want to do that, you've already iterated past the entire key. If you just pick up where you left off, you'll begin parsing the next Morse letter on the next loop iteration anyway.
Related
I'm still learning the ropes with my programming and have run into an issue that I can't seem to solve after searching for the answers
I have a while loop that is checking if a dictionary is not empty, or if the user entered a specific character (escape character).
The program works as expected if the user enters the escape character on the first prompt but seems to not function correctly if they first enter something else and then try it.
Can anyone help?
hand = {'p':1, 'y':1, 't':1, 'h':1, 'o':1, 'n':1}
def play_hand(hand):
print hand
word = raw_input('Enter word, or a "." to indicate that you are finished: ')
while any(hand) is True or word not in '.':
if word == '.':
break
elif (word == 'toy' or word == 'python') and (word != '.'):
print '"'+ word +'"', 'earned', 'points.'
play_hand(hand)
else:
print 'Invalid word, Please try again.'
return word, play_hand(hand)
else:
print 'Ending'
return
So as suggested I restructured the code and removed the recursion from the inner IF ELSE statements. It did the trick!
Thanks for the help.
Here's the sample from above done in the same fashion. You can now enter the valid word and also exit using the escape character.
hand = {'p':1, 'y':1, 't':1, 'h':1, 'o':1, 'n':1}
def play_hand(hand):
while any(hand) is True:
print hand
word = raw_input('Enter word, or a "." to indicate that you are finished: ')
if word == '.':
print 'Goodbye!'
break
else:
if not (word == 'toy'):
print 'Invalid word, Please try again.'
else:
print '"'+ word +'"', 'earned', 'points.'
hand = {'p':1, 'h':1, 'n':1}
Today I made a .py file that decrypts strings encrypted with a vigenere square. I have gotten this far but I cant seem to add spaces to the ciphr list and encr_txt because it garbles the decrypted message. Instead of "message is, hello my name is slim shady", you get "message is, hellprvmwhwebwrw k d thady", where as if i leave spaces out of encr_txt and the ciphr list I get a fine message. I do not know how to fix this there are no errors either, I just started coding in python a couple days ago so if its obvious i'm sorry. Also I know this could be done way easier but im learning lists so i chose to make it this way instead of something like this:
Another question i found relating my problem but does not describe my situation
Code :
# -*- coding: utf-8 -*-
# ^ encoding
# Encrypted text
# encr_txt = 'tkedobaxoudqrrffhhhalbmmcnedeo'
encr_txt = 'qexpg vy zeen ie wdrm elsmy'
#encr_list = list(encr_txt)
txtpos = 0
# Key to ^
key = 'james'
keypos = 0
limit = len(encr_txt)
limitpos = 0
# Vigenere square
ciphr = ['abcdefghijklmnopqrstuvwxyz ',
'bcdefghijklmnopqrstuvwxyz a',
'cdefghijklmnopqrstuvwxyz ab',
'defghijklmnopqrstuvwxyz abc',
'efghijklmnopqrstuvwxyz abcd',
'fghijklmnopqrstuvwxyz abcde',
'ghijklmnopqrstuvwxyz abcdef',
'hijklmnopqrstuvwxyz abcdefg',
'ijklmnopqrstuvwxyz abcdefgh',
'jklmnopqrstuvwxyz abcdefghi',
'klmnopqrstuvwxyz abcdefghij',
'lmnopqrstuvwxyz abcdefghijk',
'mnopqrstuvwxyz abcdefghijkl',
'nopqrstuvwxyz abcdefghijklm',
'opqrstuvwxyz abcdefghijklmn',
'pqrstuvwxyz abcdefghijklmno',
'qrstuvwxyz abcdefghijklmnop',
'rstuvwxyz abcdefghijklmnopq',
'stuvwxyz abcdefghijklmnopqr',
'tuvwxyz abcdefghijklmnopqrs',
'uvwxyz abcdefghijklmnopqrst',
'vwxyz abcdefghijklmnopqrstu',
'wxyz abcdefghijklmnopqrtsuv',
'xyz abcdefghijklmnopqrtsuvw',
'yz abcdefghijklmnopqrtsuvwx',
'z abcdefghijklmnopqrtsuvwxy',
'abcdefghijklmnopqrtsuvwxyz ']
first = ciphr[0]
string = ''
def start():
global limitpos
limitpos += 1
global keypos
for i in ciphr:
if keypos == len(key):
keypos = 0
else:
pass
if i[0] == key[keypos]:
#print "%s, %s" % (i[0], i)
global currenti
currenti = i
#print currenti
finder()
break
else:
pass
def finder():
global keypos
global txtpos
done = False
position = 0
while done == False:
for i in currenti[position]:
if i == '_':
pass
if i == encr_txt[txtpos]:
global string
string = string + first[position]
#print "message is, %s" % string
keypos += 1
txtpos += 1
done = True
if limitpos == limit:
print "message is, %s" % string
break
else:
start()
else:
position += 1
pass
start()
Adding spaces to the table changes the way the cipher works. You can't expect to make that kind of change and not affect the way messages are encrypted and decrypted!
As an aside, the last row of your table is incorrect. It's identical to the first row, but it should have the space in the first position.
I am needing a bit of help on my encryption program. Instead of having the program just move the letters by two (c would become a or r would become p) I'd like to be able to have it reference 2 lists, the first one going from a-z normally and the other with letters in different order to act as the encrypt/decrypt side. Hopefully that makes sense. Here's what i have so far.
result = ''
choice = ''
message = ''
while choice != 0:
choice = input("\n Do you want to encrypt or decrypt the message?\n 1 to encrypt, 2 to decrypt or 0 to exit program. ")
if choice == '1':
message = input('\nEnter message for encryption: ')
for i in range(0, len(message)):
result = result + chr(ord(message[i]) - 2)
print(result + '\n\n')
result = ''
if choice == '2':
message = input('\nEnter message to decrypt: ')
for i in range(0, len(message)):
result = result + chr(ord(message[i]) + 2)
print(result + '\n\n')
result = ''
elif choice != '0':
print('You have entered an invalid input, please try again. \n\n')
This works fine and dandy but i'd like to have the lists. Lets say list 1 is A,B,C,D,E and list 2 would be W,N,U,D,P. just for ease of use purposes.
Here is a solution, for small letters only. It can easily be modified to handle also capital letters, by adding them to the text strings.
As can be seen, the space character is at the same position in both lists. This is not necessary, as any character can be translated to any other. However if the decrypted or encrypted is not containing unique characters only, the program will break down.
decrypted = b"abcdefghijklmnopqrstuvwxyz "
encrypted = b"qwertyuiopasdfghjklzxcvbnm "
encrypt_table = bytes.maketrans(decrypted, encrypted)
decrypt_table = bytes.maketrans(encrypted, decrypted)
result = ''
choice = ''
message = ''
while choice != '0':
choice = input("\n Do you want to encrypt or decrypt the message?\n 1 to encrypt, 2 to decrypt or 0 to exit program. ")
if choice == '1':
message = input('\nEnter message for encryption: ')
result = message.translate(encrypt_table)
print(result + '\n\n')
elif choice == '2':
message = input('\nEnter message to decrypt: ')
result = message.translate(decrypt_table)
print(result + '\n\n')
elif choice != '0':
print('You have entered an invalid input, please try again. \n\n')
Ok, so a few things here...
First I'll give you exactly what you were looking for and explain what I used and some of the changes that needed to be made to your original code. Then I'll explain some inherent issues what what you're trying to do and suggest some areas to read up on/some ways you might want to improve what you've got.
Here's the code you're looking for (while retaining the same flow as what you submitted put above):
import random
result = ''
choice = ''
message = ''
characters_in_order = [chr(x) for x in range(32,127)]
while choice != 0:
choice = input("\n Do you want to encrypt or decrypt the message?\n 1 to encrypt, 2 to decrypt or 0 to exit program. ")
if str(choice) == '1':
message = input('\nEnter message for encryption: ')
r_seed = input('Enter an integer to use as a seed: ')
random.seed(r_seed)
shuffled_list = [chr(x) for x in range(32,127)]
random.shuffle(shuffled_list)
for i in range(0, len(message)):
result += shuffled_list[characters_in_order.index(message[i])]
print(result + '\n\n')
result = ''
elif str(choice) == '2':
message = input('\nEnter message to decrypt: ')
r_seed = input('Enter an integer to use as a seed (should be the same one used to encrypt): ')
random.seed(r_seed)
shuffled_list = [chr(x) for x in range(32,127)]
random.shuffle(shuffled_list)
for i in range(0, len(message)):
result += characters_in_order[shuffled_list.index(message[i])]
print(result + '\n\n')
result = ''
elif str(choice) != '0':
print('You have entered an invalid input, please try again. \n\n')
You'll notice that I set a global 'characters in order' list, which is just every ASCII character (32-126) in order. I also imported the 'random' module and used this to shuffle the characters in order according to a seed that the user inputs. As long as this seed is the same on the encryption and decryption end, it will produce the same shuffled list and it should work to encrypt or decipher the same string. Also notice the str() around your input choices. Without that, the user had to input '1', rather than 1 to submit a choice without an error.
All of that said...
Notice that the way the new function works is by looking at a character's index in one list and pulling out the character at that index in another. The method you were using, of incrementing or decrementing a character's ASCII code is basic (though not much more basic than this), but it also has a pretty critical flaw, which is that characters on one end or another of the ASCII set wouldn't return ASCII characters. If you were encrypting it at a bit-level, which would be preferred, this wouldn't matter/would be irrelevant, but here you're not going to get the kind of string back that you want if you were to, for example, enter a [space] (ASCII 32) into your plaintext to be encrypted.
If you're interested, you might want to read up on symmetric key encryption/DES for some ideas on how encryption is really done, though props on the start/interest and this can certainly be a fun way to create some sort of cryptogram puzzle or something along those lines. I won't pretend to be any kind of expert, but I can at least point you in the write direction. (https://en.wikipedia.org/wiki/Data_Encryption_Standard https://en.wikipedia.org/wiki/Symmetric-key_algorithm)
Consider having your code read in a .txt file and print out to a .txt file, rather than using user input for the message.
Again, I'm not an expert by any means and there are definitely some fun uses of the kind of program you're aiming for, just trying to point you in the right direction if this is something that you're interested in. Hope all of that is helpful!
Here is my solution. It uses a randomizer to encrypt the file by assigning a ASCII value to the plain text and randomly shifts it around.
from random import randint
import sys
def menu():
input1=int(input(""" please select what you want to do:
1.Encrypt
2.Decrypt
3.Extended Encryption
4.exit
"""))#menu to choose what you want to do
if input1==1:
encrypt() #takes you to the encrypt function
elif input1==2:
decrypt()#takes you to the decrypt function
elif input1==3:
enxtended()#takes you to the extended encryption function
elif input1==4:
sys.exit #exits the program
else:
print("invalid entry try again")
menu()
def encrypt():
file_name=str(input("please enter the name of the file that you want to open\n"))
try:
text_file=open(file_name + ".txt","r")#puts the text file into read
text_file=text_file.read()#reads the text file
print(text_file)#prints the strings in the document
except:
print("error try again")
encrypt()
random(text_file)
def random(text_file):
list1=("")#creates blank string
for x in range (0,8):
num=(randint(33,126))#generates a random number between33 and 126
ascii1=chr(num) #converts it into an ascii character
list1=list1+ascii1#adds the ascii character to the blank string list1
print (f"your 8 key code is {list1}") #prints 8 character code
offset(list1,text_file)
def offset(list1,text_file):
total=0
for x in range (8,):
total=total+ord(list1[x]) #turns each character into an ascii value
total=total/8 #divides it by
total=round(total,0)#rounds it to 0 decimel places
print(total)
total=total-32#minuses 32 from total
print(f"your offset factor is {total}")
encrypting(total,text_file)
def encrypting(total,text_file):
length=len(text_file)
string1=("")
for x in range (length,):
numascii=ord(text_file[x])#turns the characters into its ascii value
numascii=int(numascii)#makes sure they are integers
if numascii==32:
letter=chr(32)#converts spaces back into spaces
string1=string1+letter#adds space to thestring
else:
numascii1=numascii+total#adds the character value to the offset factor
numascii1=int(numascii1)#makes sure it is an integer
if numascii1>126:# if the ascii value is great then 126
numascii1=numascii1-94#minus 94 from it
letter=chr(numascii1)#turn it into a character
string1=string1+letter#add it to the string
else:
letter=chr(numascii1)#turn the ascii value into a character
string1=string1+letter#add it to the string
print(f"your encrypted file is {string1}")
savefile(string1)
menu()
I have written separate programs for encryption and decryption. Both of these use file manipulation techniques. Use the username 'eggs' and password 'chicks' so that not anyone can see my secret code. I have used hashlib for more security. Just change the User 'Soumajit' to your respective Username to make it work. The first one is encryption and the next one is for decryption.
#ENCRYPTION
from time import sleep
import subprocess
import hashlib
def copy2clip(txt):
cmd='echo '+txt.strip()+'|clip'
return subprocess.check_call(cmd, shell=True)
def en():
alphabet = "abcdefghijklmnopqsrtuwvxyzABCDEFGHIJKLMNOPQSRTUVWXYZ,./?:;!##$%_&* ()`-+=1234567890"
encrypt = ""
decrypt = ""
print
print "Type y for yes and anything else for no"
start = raw_input("Do you want to import file from desktop? ")
if start == "y":
Open = raw_input("Enter the .txt file you want to open in desktop: ")
a = open("C://Users//Soumajit//Desktop//" + Open + ".txt", "r")
print
x = (a.read())
copy2clip(x)
a.close()
print "Right click and select paste below to encrypt"
print
message = raw_input()
for i in message:
x = alphabet.find(i)
new = (x - 5) % 74
encrypt += alphabet[new]
e2 = encrypt[::-1]
else:
print "Type your message below"
message = raw_input("")
for i in message:
x = alphabet.find(i)
new = (x - 5) % 74
encrypt += alphabet[new]
e2 = encrypt[::-1]
print
a = raw_input("By what name do you want to save it?: ")
file = open(a + ".txt", 'wb')
file.write(e2)
file.close()
copy = raw_input("Do you want to copy your file? ")
if copy == 'y':
copy2clip(e2)
print 'Your encrypted file has been copied to the clipboard'
else:
print "Your encrypted file has been saved with the name " + str(a) + " in desktop"
print "To decrypt it, use my other program"
sleep(3)
u = 'e415bf03b4d860dccba57cea46371f831d772ba1deca47f28fa7d1f7'
p = 'c35f7f79dc34a678beb2b4106c84c9963561e7c64bc170e50c429b9a'
ur = raw_input('Enter your username: ')
ur1 = hashlib.sha224(ur).hexdigest()
pr = raw_input('Enter your password: ')
pr1 = hashlib.sha224(pr).hexdigest()
if ur1 == u and pr1 == p:
print 'Access granted'
sleep(1)
en()
else:
print "Incorrect username or password"
sleep(1)
#DECRYPTION
from time import sleep
import subprocess
import hashlib
def copy2clip(txt):
cmd='echo '+txt.strip()+'|clip'
return subprocess.check_call(cmd, shell=True)
def de():
print "Type y for yes and anything else for no"
start = raw_input("Do you want to import file from desktop? ")
if start == "y":
Open = raw_input("Enter the .txt file you want to open from folder: ")
a = open("C://Users//Soumajit//Desktop//" + Open + ".txt", "r")
x = (a.read())
#print x
copy2clip(x)
print "Right click and select paste below to decrypt"
print
message = raw_input()
a.close()
alphabet = "abcdefghijklmnopqsrtuwvxyzABCDEFGHIJKLMNOPQSRTUVWXYZ,./?:;!##$%_&*()`-+=1234567890"
decrypt = ''
for i in message:
x = alphabet.find(i)
new = (x + 5) % 74
decrypt += alphabet[new]
d2 = decrypt[::-1]
d3 = d2.replace("`", " ")
final = d3.replace("2", " ")
print
print final
else:
print "Type or paste your encrypted text below"
print
message = raw_input()
alphabet = "abcdefghijklmnopqsrtuwvxyzABCDEFGHIJKLMNOPQSRTUVWXYZ,./?:;!##$%_&*()`-+=1234567890"
decrypt = ''
for i in message:
x = alphabet.find(i)
new = (x + 5) % 74
decrypt += alphabet[new]
d2 = decrypt[::-1]
d3 = d2.replace("`", " ")
final = d3.replace("2", " ")
print
print final
u = 'e415bf03b4d860dccba57cea46371f831d772ba1deca47f28fa7d1f7'
p = 'c35f7f79dc34a678beb2b4106c84c9963561e7c64bc170e50c429b9a'
ur = raw_input('Enter your username: ')
ur1 = hashlib.sha224(ur).hexdigest()
pr = raw_input('Enter your password: ')
pr1 = hashlib.sha224(pr).hexdigest()
if ur1 == u and pr1 == p:
print 'Access granted'
sleep(1)
de()
print
end = raw_input('press q to quit: ')
while end != 'q':
print 'You did not type q'
end = raw_input('press q to quit: ')
if end == 'q':
quit()
else:
print 'Incorrect username or password'
sleep(1)
quit()
I am trying to create a python code which will encrypt and decrypt words and everything works except the block encryption. I just need to find a way to get rid of all of the spaces - here is the code I've been using
#Stops the program going over the 25 (because 26 would be useless)
#character limit
MAX = 25
#Main menu and ensuring only the 3 options are chosen
def getMode():
while True:
print('Main Menu: Encrypt (e), Decrypt (d), Stop (s), Block Encrypt (be).')
mode = input().lower()
if mode in 'encrypt e decrypt d block encrypt be'.split():
return mode
if mode in 'stop s'.split():
exit()
else:
print('Please enter only "encrypt", "e", "decrypt", "d", "stop", "s" or "block encrypt", "be"')
def getMessage():
print('Enter your message:')
return input()
#Creating the offset factor
def getKey():
key = 0
while True:
print('Enter the offset factor (1-%s)' % (MAX))
key = int(input())
if (key >= 1 and key <= MAX):
return key
#Decryption with the offset factor
def getTranslatedMessage(mode, message, key):
if mode[0] == 'd':
#The key is inversed so that it simply takes away the offset factor instead
#of adding it
key = -key
translated = ''
if mode[0] == 'be':
string.replace(" ","")
#The spaces are all removed for the block encryption
#Ensuring that only letters are attempted to be coded
for symbol in message:
if symbol.isalpha():
number = ord(symbol)
number += key
#Ensuring the alphabet loops back over to "a" if it goes past "z"
if symbol.isupper():
if number > ord('Z'):
number -= 26
elif number < ord('A'):
number += 26
elif symbol.islower():
if number > ord('z'):
number -= 26
elif number < ord('a'):
number += 26
translated += chr(number)
else:
translated += symbol
return translated
#Returns translated text
mode = getMode()
message = getMessage()
key = getKey()
#Retrieving the mode, message and key
print('The translated message is:')
print(getTranslatedMessage(mode, message, key))
#Tells the user what the message is
This is my code. At the bit where it says:
if mode[0] == 'be':
string.replace(" ","")
This is my attempt at getting rid of the spaces which does not work. If anyone could help, that would be good. Making it one space every 5 letters would be even better, but I don't need that.
Thank you for your help
Python strings are immutable.
Therefore string.replace(" ","") doesn't modify string, but returns a copy of string without spaces. The copy is discarded later, because you do not associate a name with it.
Use
string = string.replace(" ","")
import re
myString = "I want to Remove all white \t spaces, new lines \n and tabs \t"
myString = re.sub(r"[\n\t\s]*", "", myString)
print myString
I currently have the following code: You enter a string, the computer then pulls random letters and tries to match it to the letters in your string. This repeates and with each iteration the computer gets closer to guessing your string. I would like to output the initial string entered or the 'target' and the string format of the number of iterations it took to get the correct match. I want to output this to a text document. So far the script produces a text document but does not output to it. I would like it to save the data after each iteration from the main loop. I have the working program i just need assitance with the output, any ideas on how that could be done?
Here is the progress i made:
import string
import random
possibleCharacters = string.ascii_lowercase + string.digits + string.ascii_uppercase + ' .,!?;:£$^%&*|'
file = open('out.txt', 'w')
again = 'Y'
while again == 'Y' or again == 'y':
target = input("Enter your target text: ")
attemptThis = ''.join(random.choice(possibleCharacters) for i in range(len(target)))
attemptNext = ''
completed = False
generation = 0
while completed == False:
print(attemptThis)
attemptNext = ''
completed = True
for i in range(len(target)):
if attemptThis[i] != target[i]:
completed = False
attemptNext += random.choice(possibleCharacters)
else:
attemptNext += target[i]
generation += 1
attemptThis = attemptNext
genstr = str(generation)
print("Target matched! That took " + genstr + " generation(s)")
file.write(target)
file.write(genstr)
again = input("please enter Y to try again: ")
file.close()
Addressing both the original question and the one in the comments:
How to write to file after each iteration of the loop: call file.flush() after file.write(...) :
file.write(target)
file.write(genstr)
file.flush() # flushes the output buffer to the file
To add a newline after each "target" and "genstring" that you write, well, add a newline to the string (or whatever other output formatting you want) :)
file.write(target + '\n')
file.write(genstr + '\n')