1

So I saw a screencast on youtube were this guy was using something called metasploit. And every time that program was loading, a welcome screen was presented. Every char was capitalized like a wave running from left to right, like a marquee function.

And as a python noob I thought that would be pretty simple to recreate :) but boi was I wrong!

This is what I´v got:

import time
import os

string = "this is a test"

count = 0
kuk = list(string)
for i in range(len(string)):
    os.system('clear')
    if i == count:
        string[i].upper()
    print(string)
    count += 1
    time.sleep(0.3)

The problem seems that I don't know how to iterate the kukvariable, and print the list like a string (if that makes sense) and at the same time manipulate the char to upper() on each iteration.

The expected result should be:

First iteration: This is a test

Second: tHis is a test

third: thIs is a test

fourth: thiS is a test

....

Adam
  • 1,231
  • 1
  • 13
  • 37
  • your line `string[i].upper()` have no effect because the function returns the capitalized string and doesn't change the original – Tomerikoo Dec 06 '19 at 20:20

5 Answers5

3

Short approach using sys.stdout.write with carriage return \r (allows to overwrite the current line in-place) and enumerate feature:

import time
from sys import stdout

string = "this is a test"
for i, c in enumerate(string):
    if c:
        stdout.write('\r' + string[:i] + c.upper() + string[i+1:])
    time.sleep(0.3)
  • if c: condition allows to skip redundant slicing and indexing on whitespace chars
  • if you're on Python >= 3.6 the currently printed line can be built with flexible f-string style: stdout.write(f'\r{string[:i]}{c.upper()}{string[i+1:]}')
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
1

You could use a generator function in combination with enumerate:

string = "this is a test"

def marquee(some_string):
    for idx, char in enumerate(some_string):
        yield some_string[0:idx] + char.upper() + some_string[idx + 1:]

for s in marquee(string):
    print(s)

Which yields

This is a test
tHis is a test
thIs is a test
thiS is a test
this is a test
this Is a test
this iS a test
this is a test
this is A test
this is a test
this is a Test
this is a tEst
this is a teSt
this is a tesT
Jan
  • 42,290
  • 8
  • 54
  • 79
0

The easiest way to do something like this is to keep track of the index that you want to capitalize, and print in three stages:

  1. The part of the string before what you want to capitalize
  2. The character you want to capitalize, converted to uppercase
  3. The part of the string after what you want to capitalize

We can use string slicing to do this.

import os, time
string = "this is a test"
count = 0
while True:
   # clear screen
   os.system('clear')
   # print each of the three section
   first_part = string[:count]
   second_part = string[count].upper()
   third_part = string[count + 1:]
   print(first_part + second_part + third_part)
   # increment to the next index. Once we reach the end of the string, wrap around.
   count = (count + 1) % len(string)
   time.sleep(0.1)
Green Cloak Guy
  • 23,793
  • 4
  • 33
  • 53
0

Python strings are immutable. This means the line string[i].upper() does not modify string.

You can use slicing instead.

For example:

myString = "this is a test"
for i in range(len(myString)):
    os.system('clear')
    print(myString[:i] + myString[i].upper() + myString[i+1:])
    time.sleep(0.3)
#This is a test
#tHis is a test
#thIs is a test
#thiS is a test
#this is a test
#this Is a test
#this iS a test
#this is a test
#this is A test
#this is a test
#this is a Test
#this is a tEst
#this is a teSt
#this is a tesT

This doesn't skip whitespace, but you can easily add that logic if that's what you want.

pault
  • 41,343
  • 15
  • 107
  • 149
0

You can use slicing:

s = 'abc'

for idx in range(len(s)):
    print(f'{s[:idx]}{s[idx:].title()}')

Output:

Abc
aBc
abC
Mykola Zotko
  • 15,583
  • 3
  • 71
  • 73