4

Question

Why is my random ascii character selector function outputting fours, and what is the significance of the number four in this context? Why am I not recieving an error message?

Remember, the question is not about how to solve the issue, it is about why that particular number was output.

Background and Code

I am trying to creating a basic email client. I thought that it would be cool for my password box to show random characters instead of the obvious *. So, I created a function which chose a random ascii letter.

import random
import string

def random_char():

    char_select = random.randrange(52)

    char_choice = string.ascii_letters[char_select]

    return char_choice

When I run this in an interactive terminal, it spits out a random letter. But, when I run it through my widget

self.Password = Entry (self, show = lambda: random_char())

I am met with a bunch of fours.

Extra Credit

If you have the time, please visit my related question, How to have a Tkinter Entry box repeat a function each time a character is inputted?

Cœur
  • 37,241
  • 25
  • 195
  • 267
xxmbabanexx
  • 8,256
  • 16
  • 40
  • 60
  • 1
    Why would you even want to do that? Don't you think it would confuse users? – lllluuukke Apr 20 '13 at 00:18
  • @lllluuukke Now this isn't even about that. I want to know, *what is the significance of 4 when one feeds a callback to the show argument?* – xxmbabanexx Apr 21 '13 at 17:04
  • I messed around this on one of my little apps. One thing worked for me, try it: `self.Password = Entry (self, show = random_char())` – lllluuukke Apr 21 '13 at 19:14

1 Answers1

1

The show parameter accepts a value not a callback. Tkinter is taking your callback object and trying to convert it to a string and that is what you get when you type in the Entry box.

Instead you can re-configure your Entry after you type by using binding:

def key(event):
    entry.configure(show = random_char())

entry = tk.Entry (self)
entry.pack()
entry.bind("<Key>", key)

EDIT

Bryan Oakley is correct in that this will change all the characters to the same single random character as you type. Showing different random characters as you type is not the way you are supposed to use the Entry widget. You can try something like:

def key(event):
    global real_password
    global garbage
    current_len = len(v.get())
    if event.char and event.char in string.ascii_letters:
        real_password += event.char
        garbage += random_char()
    garbage = garbage[:current_len]
    v.set(garbage)

v = tk.StringVar()
real_password = ""
garbage = ""
entry = tk.Entry (self, textvariable = v)
entry.pack()
entry.bind("<KeyRelease>", key)

Of course there are lots of limitations, the last character typed is changed when the key is released not when is pressed, so you have to type fast :) , there is not control over the cursor movement keys etc. But anyway it was fun trying.

jujaro
  • 447
  • 2
  • 4
  • I don't think this will do what the OP wants. This will change all the characters to something random, rather than just the last typed character. – Bryan Oakley Apr 20 '13 at 12:28