Alternative newline character? python
I'm looking for a way to represent '\ n' with only one character. I am writing a program that uses dictionaries to "encrypt" text. Since each character is represented in the dictionary, I am having a problem where my program hits the string "\ n" in the string, but reads it as "\" n. Is there an alternative way to represent a newline, i.e. only one character? This is my code below, sorry if some of the indents are broken. I don't quite understand how to enter code into this window. :)
##################################
#This program will take an input and encrypt it or decrypt it
#A cipher is used to transform the text, which can either be
#input or from a text file.
#The cipher can be any letter a-z, as well as most commonly used special characters
#numbers and spaces are not allowed.
#For the text, a-z, most special characters, space, and new line may be used.
#no numbers can be encrypted.
##################################
#These three dictionaries are used during the encryption process.
keyDict={'a': 17,'b': 3,'c':16,'d':26,'e':6,'f':19,'g':10,'h':12,
'i':22,'j':8,'k': 11,'l':2,'m':18,'n':9,'o':23,'p':7,
'q':5,'r': 20,'s': 1,'t': 24,'u':13,'v':25,'w':21,'x':15,
'y':4,'z': 14, ' ':42, '.':0,'!': 27, '@': 34, '#': 35, '%': 37,
'$': 36, "'": 33,'&': 39, '*': 40, ',': 29, '.': 30, '~': 41, ';': 31,
':': 32, '?': 28, '^': 38}
refDict2={' ': 43, 'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4, 'g': 7, 'f': 6, 'i': 9,
'h': 8, 'k': 11, 'j': 10, 'm': 13, 'l': 12, 'o': 15, 'n': 14, 'q': 17,'\n': 42,
'p': 16, 's': 19, 'r': 18, 'u': 21, 't': 20, 'w': 23, 'v': 22, 'y': 25,
'x': 24, 'z': 26, ' ':0, '!': 27, '@': 34, '#': 35, '%': 37, '$': 36, "'": 33,
'&': 39, '*': 40, ',': 29, '.': 30, '~': 41, ';': 31, ':': 32, '?': 28, '^': 38}
refDict={0: ' ', 1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i',
10: 'j', 11: 'k', 12: 'l', 13: 'm', 14: 'n', 15: 'o', 16: 'p', 17: 'q', 42:'\n',
18: 'r', 19: 's', 20: 't', 21: 'u', 22: 'v', 23: 'w', 24: 'x', 25: 'y', 26: 'z', 43:' ',
32: ':', 33: "'", 34: '@', 35: '#', 36: '$', 37: '%', 38: '^', 39: '&', 40: '*',
41: '~', 27: '!', 28: '?', 29: ',', 30: '.', 31: ';'}
#switch1 reverses a list. It is its own inverse, so we don't need an unswitch function.
def switch1(l):
return l[::-1]
#switch2 takes a list as input and moves every fourth entry to the front
#so switch2([a,b,c,d,e,f,g]) returns ([a,e,b,c,d,f,g])
#unswitch2 undoes this, so unswitch2([a,e,c,d,f,g]) returns [a,b,c,d,e,f,g]
def switch2(l):
List4 = []
ListNot4 = []
for i in range(0,len(l)):
if i%4 == 0:
List4.append(l[i])
else:
ListNot4.append(l[i])
return List4+ListNot4
def unswitch2(l):
num4 = len(l)/4 + 1
fixedList = l[num4:]
for i in range (0,num4):
fixedList.insert(4*i,l[i])
return fixedList
#switch3 takes a list as input and returns a list with the first half moved to the end.
#so switch3([a,b,c,d,e,f]) returns [d,e,f,a,b,c]
#for lists of odd length, switch3 puts the separation closer to the beginning of the list, so the
#middle entry becomes the first entry.
#For example, switch3([a,b,c,d,e,f,g]) returns [d,e,f,g,a,b,c]
def switch3(l):
return l[len(l)/2:] + l[:len(l)/2]
def unswitch3(l):
if len(l)%2==0:
return switch3(l)
else:
return l[len(l)/2+1:] + l[:len(l)/2+1]
##################################
#This is the Crypt function.
##################################
def Crypt(text, cipher):
counter=0
text=text.lower()
cipher=cipher.lower()
keyValue=[]
textValue=[]
newValue=[]
newString=''
for letter in cipher:
keyValue.append(keyDict[letter])
for letter in text:
textValue.append(refDict2[letter])
for num in textValue:
newValue.append(num+keyValue[counter%len(keyValue)])
counter+=1
newValue = switch1(newValue)
newValue = switch2(newValue)
newValue = switch3(newValue)
for num in newValue:
newString+=refDict[num%43]
return newString
##################################
#This is the Decrypt function
##################################
def Decrypt(encryptedText, cipher):
counter=0
cipher=cipher.lower()
keyValue=[]
textValue=[]
finalValue=[]
finalString=''
for letter in encryptedText:
textValue.append(refDict2[letter])
textValue = unswitch3(textValue)
textValue = unswitch2(textValue)
textValue = switch1(textValue)
for letter in cipher:
keyValue.append(keyDict[letter])
for num in textValue:
finalValue.append((num-keyValue[counter%len(keyValue)])%43)
counter+=1
for num in finalValue:
finalString+=refDict[num]
return finalString
##################################
#This is the user interface.
##################################
choice=raw_input('Would you like to: 1)Encrypt or 2)Decrypt? Pick 1 or 2: ')
if choice=='1':
textType=raw_input("Would you like to: 1)encrypt a text file or 2) input the text to be encrypted? Pick 1 or 2: ")
if textType=='1':
cryptName=raw_input( 'Please enter the name of the text file you would like to encrypt(eg. text.txt): ')
newName=raw_input('Please name the file in which the encrypted text will be stored(eg. secret.txt):' )
cipher=raw_input("Now enter your personal encryption key(eg. secret code):" )
cryptFile=open(cryptName, 'r')
newFile=open(newName, 'w')
print >> newFile, Crypt(cryptFile.read(),cipher)
cryptFile.close()
newFile.close()
print "Ok, all done!"
elif textType=='2':
inputText=raw_input('Ok, please input the text you would like to encrypt(eg. computers rock!): ')
cipher=raw_input("Now enter your personal encryption key (eg. ultra secret code): ")
if inputText=='': print 'Oops, no text was entered! Try again!'
else:
print Crypt(inputText, cipher)
else:
print 'Try again!'
elif choice=='2':
textType=raw_input("Would you like to:1)decrypt a text file or 2) input the text to be decrypted? Pick 1 or 2: ")
if textType=='1':
decryptName=raw_input( 'Please enter the name of the text file you would like to decrypt(eg. text.txt): ')
newName2=raw_input('Please name the file in which the decrypted text will be stored(eg. secret.txt):' )
cipher=raw_input("Now enter the encryption key that was used to encrypt the file(eg. secret code):" )
#Text decrypt
decryptFile=open(decryptName, 'r')
newFile2=open(newName2, 'w')
print>> newFile2, Decrypt(decryptFile.read(),cipher)
#other stuff
#textTodecrypt=decryptFile.read()
#newFile2.writelines(Decrypt(textTodecrypt, cipher))
decryptFile.close()
newFile2.close()
print "Ok, all done!"
elif textType=='2':
inputText=raw_input('Ok, please input the text you would like to decrypt(eg. dig&ak:do): ')
cipher=raw_input("Now enter the encryption key that was used to encrypt the text (eg. ultra secret code): ")
if inputText=='': print 'Oops, no text was entered! Try again!'
else:
print Decrypt(inputText, cipher)
print "Have a nice day!"
#there is an issue with the newline character
'\ n' is one character. This is a new escape line character and is simply a newline representation.
please rephrase your question in a readable way.
[Edit] I think I know what your problem is. I ran your program and it works fine. You are probably trying to pass '\ n' to your program from the command line. It won't work!
You see, if you gave raw_input () this line: line1\nline2
it will exit \n
and make it \\n
like this:'line1\\nline2'
So, a quick hacky fix is to find and replace "\\ n" with "\ n":
text.replace('\\n', '\n')
I do not like this. But it will work for you.
Your best bet is to read multiple lines, for example:
input = raw_input('Please type in something: ') lines = [input] while input: input = raw_input() lines.append(input) text = '\n'.join(lines) print text
a source to share
I guess your real problem is not reading into \ n, but "\ n" - inside, Python should automatically convert \ n to a single character.
My guess is that the real problem is that your newlines are probably actually two characters - a carriage return ('\ r') and a newline ('\ n'). Try to handle \ r in addition to \ n and I wonder if your problem will go away.
a source to share
I guess the problem is that in the text to be decrypted, \ n, it breaks off:
KeyError: \
module body in untitled at line 166
function Crypt in untitled at line 94
Basically, it raw_input()
returns a string containing two characters \
and n
- and you have no mapping for \
, thus an error.
The simplest solution is to just replace literal characters \n
with an escape sequence\n
def Crypt(text, cipher):
text.replace(r"\n", "\n")
...
The raw string r"\n"
creates a string containing an alphabetic character \
followed by n
(same as for "\\n"
).
In a regular string, "\n"
it is treated as an escape sequence for a newline. So the above code block replaces the \n
text on a new line.
Perhaps you need to define a mapping for "\ n" in your mapping keyDict
.
Another solution would be to split the text with text.split(r"\n")
and process each line separately. Or, as others have suggested, use ord()
each character and handle the numbers rather than create your own numeric display.
ord(c)
For a given string of length one, returns an integer representing the Unicode code point of the character when the argument is a unicode object or a byte value when the argument is an 8-bit string. For example,ord('a')
returns integer 97,ord(u'\u2020')
returns 8224. This is the inversechr()
for 8-bit strings andunichr()
for unicode objects.
As the docs explains, chr()
is the opposite, and it will return the number in ASCII or Unicode character:
chr(i)
Returns a single character string whose ASCII code is an integer i. For example, itchr(97)
returns the string 'a'. This is inversionord()
. The argument must be in the range [0..255], inclusive; ValueError will be raised if I am out of this range.
Basically you would.
def Crypt(text, cipher):
keyvalue = [ord(x) for x in cipher)
textvalue = [ord(x) for x in text]
.. instead of two for loops ( list-comprehension is basically the same as making a list, looping over each character into text or cipher and adding to the list each time)
a source to share
I'm new to Python, but there might be a way to simplify what you're doing by using the ord and chr functions to change characters to ASCII values and vice versa. Here's a link to the built-in documentation of functions in Python .
a source to share
A quick and easy way to replace normal screens with the corresponding ASCII characters is str.decode
:
>>> s = r'This string has\tsome\nescapes'
>>> s
'This string has\\tsome\\nescapes'
>>> s.decode('string-escape')
'This string has\tsome\nescapes'
>>> print s
This string has\tsome\nescapes
>>> print s.decode('string-escape')
This string has some
escapes
a source to share