How do i access the '\n' (newline) character in text widget? because I've a problem doing my project.


I would like to ignore the character but .........

if (A2int[plain]=='\n') do the trick. Any ideas?

KeyError: '\n'

Dani AI

Generated

Short answer: the Text widget always leaves a trailing newline when you call get(1.0, END), so your loop will eventually try to look up '\n' in your map and raise KeyError. Rather than adding a special mapping for '\n', fetch the text without the trailing newline or strip it, and skip any characters not in your alphabet.

A small, safe pattern to apply before you loop:

plain = self.text3.get("1.0", "end-1c").upper()   # end-1c omits the final newline
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ "

for i, ch in enumerate(plain):
    if ch not in alphabet:
        continue            # skip newlines, tabs, punctuation, etc.
    idx = alphabet.index(ch)
    key = key_odd if (i % 2) == 0 else key_even   # decide parity (see note below)
    out += alphabet[(idx + key) % len(alphabet)]

Notes and practical improvements

  • Parity: index 0 is the first character. If you want the “first” character to use the odd-key, test (i % 2) == 0 (or use (i+1) % 2 == 1 to read positions 1-based). That frequently causes confusion, so pick one convention and comment it.
  • Avoid repeating large dicts in multiple methods. Define your alphabet (or the two dicts) once (e.g., in __init__) and reuse them.
  • Replace manual binary-to-decoding with int(binstring, 2) after validating the string contains only 0 and 1. It’s shorter, faster and clearer.
  • Validate inputs (empty keys, non-binary characters) and show an error or ignore those characters rather than letting exceptions bubble up.

This addresses the KeyError and also cleans up the design. As showed, checking the string helps, and ’s request for more code was exactly what made these fixes testable for .

Recommended Answers

All 3 Replies

Honestly, few of us are mind-readers, you need to give us more information and code.

bah, im sorry about the insufficient information to my question.

I am doing a program to encrypt a text from plaintext to ciphertext and the other way around, using Caesar Cipher idea. The only difference is this program has two keys. One to encrypt characters in odd position and the second key is to encrypt the characters in even position.

The key is in binary form due to the requirement of my system implementing binary input. It converts binary to decimal then uses the decimal value to add with the ascii value for the result = ciphertext.

When i was using text widget somehow '\n' exist and i've only mapped characters from A-Z and space. So I thought of doing it by mapping the '\n' character with a value.

Is there any better solution to my codings? Any improvement to be done and suggestions?
I've only started learning python 4 days ago. Sorry for the newb post =( .The code is posted as below.

from Tkinter import *

class App(object):
  
  def __init__(self, master):
    frame = Frame(master, bg="black", borderwidth=30)
    frame.pack(expand=NO)
    
    self.enc=Button(frame, width=12, font = "Verdana 14 bold",
                    text="Encrypt", command=self.caesar_encrypt)
    self.dec=Button(frame, width=12, font = "Verdana 14 bold",
                    text="Decrypt", command=self.caesar_decrypt)
    self.exit=Button(frame, width=12, font = "Verdana 14 bold",
                     text="Clear All", command=self.clear_all)

    Label(frame, font = "Verdana 14 bold", fg='cyan', bg="black", text="Key").grid(row=0, column=1)
    Label(frame, font = "Verdana 14 bold", fg='cyan', bg="black", text="Plaintext").grid(row=2, column=1)
    Label(frame, font = "Verdana 14 bold", fg='cyan', bg="black", text="Ciphertext").grid(row=4, column=1)

    self.entry1=Entry(frame, font = "Verdana 14", width=25, bg = 'orange')
    self.entry2=Entry(frame, font = "Verdana 14", width=25, bg = 'orange')
     
    self.text3=Text(frame, font = "Verdana 14", width=50, height=10, bg = 'orange')
    self.text4=Text(frame, font = "Verdana 14", width=50, height=10, bg = 'orange')
    
    self.entry5=Entry(frame, font = "Verdana 14", width=25, bg = 'orange')
    self.entry6=Entry(frame, font = "Verdana 14", width=25, bg = 'orange')

    self.enc.grid(row=2, column=0)
    self.dec.grid(row=3, column=0)
    self.exit.grid(row=4, column=0)

    self.entry1.grid(row=1, column=1, sticky=W)
    self.entry2.grid(row=1, column=1, sticky=E)

    self.text3.grid(row=3, column=1)
    self.text4.grid(row=5, column=1)

    self.entry5.grid(row=6, column=1, sticky=W)
    self.entry6.grid(row=6, column=1, sticky=E)

  def clear_all(self):
    self.entry1.delete(0,END)
    self.entry2.delete(0,END)

    self.text3.delete(1.0,END)
    self.text4.delete(1.0,END)
    
    self.entry5.delete(0,END)
    self.entry6.delete(0,END)
    
  def binary2dec(self):
    s = list(self.entry1.get().strip())
    s.reverse()
    
    t = list(self.entry2.get().strip())
    t.reverse()
    
    result1 = 0
    result2 = 0
    
    for i, n in enumerate(s):
      result1 += int(s[i]) * pow(2, i)
    self.entry5.delete(0, END)
    self.entry5.insert(0, result1)
    
    for i, n in enumerate(t):
      result2 += int(t[i]) * pow(2, i)
    self.entry6.delete(0, END)
    self.entry6.insert(0, result2)
    
    return result1, result2


  def caesar_encrypt(self):
    A2int = {'A':0, 'B':1, 'C':2, 'D':3, 'E':4, 'F':5, 'G':6,'H':7,'I':8, 'J':9, 'K':10,
             'L':11, 'M':12, 'N':13, 'O':14, 'P':15, 'Q':16, 'R':17, 'S':18, 'T':19, 'U':20,
             'V':21, 'W':22, 'X':23, 'Y':24, 'Z':25, ' ':26, '\n':999}
    int2A = {0:'A', 1:'B', 2:'C', 3:'D', 4:'E', 5:'F', 6:'G', 7:'H', 8:'I', 9:'J', 10:'K',
             11:'L', 12:'M', 13:'N', 14:'O', 15:'P', 16:'Q', 17:'R', 18:'S', 19:'T', 20:'U',
             21:'V', 22:'W', 23:'X', 24:'Y', 25:'Z', 26:' ', 999:'\n'}
    plain = self.text3.get(1.0,END).upper()
    key_odd, key_even = self.binary2dec()
    ciphertext = ''
    
    for i, n in enumerate(plain):
      a='';
      a=A2int[plain[i]]
      if (a==999): continue
      #ODD KEY
      if (i%2==1):
          n = A2int[plain[i]] + key_odd
          if (n == 26): n = n
          if (n > 26): n = n % 27
          ciphertext += int2A[n]
          
      #EVEN KEY
      if (i%2==0):
          
          n = A2int[plain[i]] + key_even
          if (n == 26): n = n
          if (n > 26): n = n % 27
          ciphertext += int2A[n]
          

    self.text4.delete(1.0, END)
    self.text4.insert(1.0, ciphertext)

  def caesar_decrypt(self):
    A2int = {'A':0, 'B':1, 'C':2, 'D':3, 'E':4, 'F':5, 'G':6,'H':7,'I':8, 'J':9, 'K':10,
             'L':11, 'M':12, 'N':13, 'O':14, 'P':15, 'Q':16, 'R':17, 'S':18, 'T':19, 'U':20,
             'V':21, 'W':22, 'X':23, 'Y':24, 'Z':25, ' ':26, '\n':999}
    int2A = {0:'A', 1:'B', 2:'C', 3:'D', 4:'E', 5:'F', 6:'G', 7:'H', 8:'I', 9:'J', 10:'K',
             11:'L', 12:'M', 13:'N', 14:'O', 15:'P', 16:'Q', 17:'R', 18:'S', 19:'T', 20:'U',
             21:'V', 22:'W', 23:'X', 24:'Y', 25:'Z', 26:' ', 999:'\n'}
    cipher = self.text4.get(1.0,END).upper()
    key_odd, key_even = self.binary2dec()
    plaintext = ''

    
    for i, n in enumerate(cipher):
      a='';
      a=A2int[cipher[i]]
      if (a==999): continue
        #ODD KEY
      if (i%2==1):
        n = A2int[cipher[i]] - key_odd
        while (n<0): n = n + 27
        plaintext += int2A[n]
        #EVEN KEY
      if (i%2==0):
        n = A2int[cipher[i]] - key_even
        while (n<0): n = n + 27
        plaintext += int2A[n]
        
    self.text3.delete(1.0, END)
    self.text3.insert(1.0, plaintext)

root = Tk()
root.title("Caesar Cipher")
root.maxsize(834,695)
app = App(root)

root.mainloop()

How do i access the '\n' (newline) character in text widget? because I've a problem doing my project.


I would like to ignore the character but .........

if (A2int[plain]=='\n') do the trick. Any ideas?

KeyError: '\n'

hey, if you are asking how to get index of '\n' character or to find whether string is having that character, then

from Tkinter import *

root = Tk()

def func():
    if '\n' in text.get(1.0, END):
        print 'at: ', text.get(1.0, END).index('\n')        

text = Text(root, height=10, width=50)
text.grid(row=0, column=0)
b = Button(root, text='click', command=func)
b.grid(row=1)

root.mainloop()
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.