0

I'm learning about recursion in Python, and I wrote a small program that I'd like to improve on for the sake of erudition.

The program repeatedly prints lines of asterisks which change colors. The program runs until I stop it. Right now it works as expected, but just by looking at it I can tell there must be a better way to write this recursively, or perhaps using another method.

Please post some answers that demonstrate how to improve this program. You don't have to make use of the termcolor module if you don't want to.

Below is my code:

import random
from termcolor import colored

s = random.choice('*******************',)
colors = ['red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white']
text_color = ""

def set_color(colors):
    global text_color
    text_color = random.choice(colors)

while True:
    for a in s:
        for b in s:
            for c in s:
                for d in s:
                    for e in s:
                        for f in s:
                            for g in s:
                                for h in s:
                                    for i in s:
                                        for j in s:
                                            for k in s:
                                                for l in s:
                                                    for m in s:
                                                        for n in s:
                                                            for o in s:
                                                                for p in s:
                                                                        print(colored(a, text_color)), (colored(b, text_color)), (colored(c, text_color)), (colored(d, text_color)), (colored(e, text_color)), (colored(f, text_color)), (colored(g, text_color)), (colored(h, text_color)), (colored(i, text_color)), (colored(j, text_color)), (colored(k, text_color)), (colored(l, text_color)), (colored(m, text_color)), (colored(n, text_color)), (colored(o, text_color)), (colored(p, text_color)), (colored(a, text_color)), (colored(b, text_color)), (colored(c, text_color)), (colored(d, text_color)), (colored(e, text_color)), (colored(f, text_color)), (colored(g, text_color)), (colored(h, text_color)), (colored(i, text_color)), (colored(j, text_color)), (colored(k, text_color)), (colored(l, text_color)), (colored(m, text_color)), (colored(n, text_color)), (colored(o, text_color)), (colored(p, text_color)); set_color(colors)
3
  • 4
    Stairway to Truth.... This is better fit for Code Review Commented Feb 10, 2017 at 10:16
  • Take your suggestions to the answer box! Commented Feb 10, 2017 at 10:17
  • What is random.choice('*******************',) supposed to achieve? Commented Feb 10, 2017 at 10:30

1 Answer 1

3

So random.choice('*******************',) will choose a random character from the string. Since all characters are '*' you can essentially replace the whole expression by s = '*'.

The nested loops are on the form for x in s. Since s = '*', this is equivalent to for x in '*'. For a one-letter string, this is a loop with only one iteration - so it can be replaced with x = 's'.

The third thing to notice now is that all the variables named a through p are equal and contain an asterisk. They can all be removed, and instead use s wherever they are used.

Finally, the huge print statement is then full of colored(s, text_color). They can be replaced by ' '.join(colored(s, text_color) for _ in range(32))

So you end up with the following program:

import random
from termcolor import colored

s = '*'
colors = ['red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white']
text_color = ''

def set_color(colors):
    global text_color
    text_color = random.choice(colors)

text_color = set_color(colors)
while True:
    print(' '.join(colored(s, text_color) for _ in range(32)))
    set_color(colors)

It can be further simplified:

import random
from termcolor import colored, COLORS
while True:
    color = random.choice(COLORS.keys())
    print(' '.join(colored('*', color) for _ in range(32)))

This is even more fun, it will use both background and foreground colors, and not use any spaces:

import os
from random import choice
from termcolor import colored, COLORS, HIGHLIGHTS
r, c = os.popen('stty size', 'r').read().split()
WIDTH=int(r+c) # actual terminal width under Linux
while True:
    print ''.join(colored('▄', choice(COLORS.keys()), choice(HIGHLIGHTS.keys())) for _ in range(WIDTH)),

Output: random colors everywhere!

Sign up to request clarification or add additional context in comments.

2 Comments

Excellent, this is really insightful.
Nice, you got the terminal size :)

Your Answer

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.