1

I want to make a script which will type string letters one by one

def autotype(info):
 count = len(info) #Countign number of letters of the string
 splitlist = list(info) 
 i = int(count) #getting an error on this line! it accept i=int(0) but my loop doesnt work because of this
 while i>0:
 sys.stdout.write(splitlist[i])
 time.sleep(0.2)
 i -= 1
info = str("hello world")
autotype(info)

the error is: list index out of range how do i fix it?

Darek
2,8964 gold badges30 silver badges52 bronze badges
asked Jul 22, 2013 at 17:29
4
  • OP: are you trying to go backwards through the string? Because that's what your code does. Commented Jul 22, 2013 at 17:36
  • @2rs2ts no, I just want to make a script which will type text exactly as it is Commented Jul 22, 2013 at 17:38
  • Then definitely do go with what I wrote originally. Commented Jul 22, 2013 at 17:40
  • 2
    don't forget to flush! (see my answer below) Commented Jul 22, 2013 at 17:41

7 Answers 7

7

The length of a list is the number of elements in a list. But, lists start at index 0, and so they will end at index length - 1. So, to fix your code as is, it should be i = count - 1. (You don't need to cast it to an int, it's already one.)

Better yet, rather than iterating using a counter in a while loop, just use a for loop. You can use the for loop to iterate over the characters in a string.

for ch in info:
 sys.stdout.write(ch)
 sys.stdout.flush() # as mawimawi suggests, if you don't do this, it will
 # actually just come out all on one line at once.
 time.sleep(0.2)

You also don't need to cast "hello world" to a string - it's already one.

answered Jul 22, 2013 at 17:31
Sign up to request clarification or add additional context in comments.

2 Comments

But note that this won't run through the string backwards.
Yeah, but does OP really want that? (I asked him as much in a comment.)
2

Your script is quite un-pythonic. Here is something that would do the same. Strings are iterables, so:

def autotype(info):
 for x in info:
 sys.stdout.write(x)
 sys.stdout.flush() # you need this, because otherwise its' buffered!
 time.sleep(0.2)

That's all you need.

answered Jul 22, 2013 at 17:39

1 Comment

Good call on the flush(), I'll add it to mine (but credit you!)
2

You're starting your loop at i=len(info), which is one more than the final index in the string. The last index in a string (or other iterable) is len(string) - 1, because indices begin at 0.

Note that in Python, you can (and are encouraged to) make use of the natural language constructs and the fact that collections are easy to iterate over:

for letter in reversed(info): # Much clearer way to go backwards through a string
 sys.stdout.write(letter)

Since you've clarified in your comments that you actually want to go forwards through the text, you can just take out the reversed bit. The code as you posted will iterate backwards through the text, not forwards -- another benefit to using the standard iteration techniques is that it's much easier to see if you've done something you didn't mean to do!

for letter in info: # Very clear that you're going forward through the string
 sys.stdout.write(letter)

Finally, as others have mentioned, you should add an explicit call to sys.stdout.flush() after every write, because otherwise there's no guarantee that you'll see output at regular intervals (it could be written to the buffer but not flushed to the screen until much later).

answered Jul 22, 2013 at 17:31

8 Comments

I agree, this is pythonic way and should be used. Also no explicit type declarations are needed. I would also change sys.stdout.write to print.
@Dārayavahuštdi Is there a way to do print and flush the buffer every time to make it look like it's getting typed?
@Dārayavahuštdi print will flush the buffer (I think), but it also adds spaces before each letter (without further manipulations), which is presumably not what the OP wants.
@2rs2ts print does flush the buffer as far as I know, but it introduces formatting problems. These can be circumvented with print(letter, sep=''), but I think the explicit flush is probably better anyway.
@HenryKeiter When I tried for c in "hello": time.sleep(0.2); print c, I got it all at once after 1 second. An explicit sys.stdout.flush() a la mawimawi's answer worked as expected.
|
0

Lists are zero-indexed, so the last element is at len(info)-1.

To fix this, you need to subtract 1 from the count:

i = int(count) - 1
answered Jul 22, 2013 at 17:31

Comments

0

Indexes are counted from zero... if you have 5 items in a list, then indexes are 0,1,2,3,4

you are setting index out of bounds in this line:

i = int(count)

If count is 5 then max index is 4. To fix this change that line into:

i = int(count) - 1

Next thing, you won't print the first character. to fix that change a line:

while i>0:

into:

while i>=0:

By the way all your characters are printed backwards.

answered Jul 22, 2013 at 17:31

Comments

0

Unidiomatically, but concisely:

import time
import sys
autotype = lambda instr:map((lambda ch:(sys.stdout.write(ch), time.sleep(0.2))), instr)
autotype("hello world")

The main problem with the above code is that it's not usual to sequence two functions using tuple if you don't care for their return values.

answered Jul 22, 2013 at 17:48

Comments

0

Here is code to "make a script which will type string letters one by one"

print info

If what you need is to type letters in a string consecutively, there is no need to reinvent the wheel.

More than likely, your question was underspecified.

answered Jul 22, 2013 at 19:13

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.