# Brute Force generator

I just wrote a little Python 3 program to spit out every possible combination of a set of 99 characters.
It gets the job done, but I would be very interested in what you think of it.

I am just a few days into Python, so I would be grateful for even seemingly obvious advice.

``````
import sys

# List of 99 characters and a blank string:

lib=["","0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","°","!","\"","§","\$","%","&","/","(",")","=","ß","´","`","+","#","-",".",",",">","<","@","€","|","^","~","–","{","[","]","}","Ä","Ö","Ü","ä","ö","ü"]

# 10 counters for up to 10-digit-combinations:

counter0=-1
counter1=0
counter2=0
counter3=0
counter4=0
counter5=0
counter6=0
counter7=0
counter8=0
counter9=0

# Repetitive if-statements adding to the counters:

for i in range(sys.maxsize**99999):
counter0+=1

if counter0>99:
counter0=counter0*0
counter1+=1

elif counter1>99:
counter1=counter1*0
counter2+=1

elif counter2>99:
counter2=counter2*0
counter3+=1

elif counter3>99:
counter3=counter3*0
counter4+=1

elif counter4>99:
counter4=counter4*0
counter5+=1

elif counter5>99:
counter5=counter5*0
counter6+=1

elif counter6>99:
counter6=counter6*0
counter7+=1

elif counter7>99:
counter7=counter7*0
counter8+=1

elif counter8>99:
counter8=counter8*0
counter9+=1

elif counter9>99:
print("DONE.")

# Printing the translation from counters to character - and deleting the former output so it stays in one line:

else:
print(lib[counter0]+lib[counter1]+lib[counter2]+lib[counter3]+lib[counter4]+lib[counter5]+lib[counter6]+lib[counter7]+lib[counter8]+lib[counter9], end="\r")
sys.stdout.write("\b"*10+" "*10+"\b"*10)

``````

• We can convert a plain string to a list rather than maintain a list for the characters.

It is far easier to modify and read the following then a list.

``````lib = [''] + list('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz°!"§\$%&/()=ß´`+#-.,><@€|^~–{[]}ÄÖÜäöü')
``````
• When we have `counter0`, `counter1`, …, `countern` it’s a hint that we should use a list.

``````counters = [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
``````

We can then use `counters` as a drop in replacement for `counter0`.

• Now that we have `counters` which is a list we can simplify your print from the following.

``````print(lib[counters] + lib[counters] + lib[counters] + lib[counters] + > lib[counters] + lib[counters] + lib[counters] + lib[counters] + lib[counters] + lib[counters], end="\r")
``````

We can use a for loop to loop through counters, index `lib` and print the character. We’ll use `end=""` to get the same format that you have. Since we’ve changed from `"\r"` to `""` we’ll need to print that afterwards.

``````for counter in counters:
print(lib[counter], end="")
print(end="\r")
``````
• It would be better to use `len(lib)` rather than hard coding `99` in your ifs. If we change the content of `lib` it’s much easier to edit just `lib` rather than `lib` and 10 99’s.

• Rather than `counter0=counter0*0` it would make more sense to remove the multiplication and just set the value to 0.

``````counter0 = 0
``````
• It’s convention in Python to put a space either side of operators. This means `a+b` should instead be `a + b`. This is as it makes it easier to see what is and is not an operator and either side of an operator.

• It’s convention in Python to use `_` as a ‘throw away’ variable. This means it’s normal to use `_` rather than `i` in your for loop.

Together this gets:

``````import sys

lib = [''] + list('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz°!"§\$%&/()=ß´`+#-.,><@€|^~–{[]}ÄÖÜäöü')
counters = [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0]

for _ in range(sys.maxsize**99999):
counters += 1
if counters >= len(lib):
counters = 0
counters += 1
elif counters >= len(lib):
counters = 0
counters += 1
elif counters >= len(lib):
counters = 0
counters += 1
elif counters >= len(lib):
counters = 0
counters += 1
elif counters >= len(lib):
counters = 0
counters += 1
elif counters >= len(lib):
counters = 0
counters += 1
elif counters >= len(lib):
counters = 0
counters += 1
elif counters >= len(lib):
counters = 0
counters += 1
elif counters >= len(lib):
counters = 0
counters += 1
elif counters >= len(lib):
print("DONE.")
else:
for counter in counters:
print(lib[counter], end="")
print(end="\r")
sys.stdout.write("\b"*10 + " "*10 + "\b"*10)
``````

There are still some changes that we can make to your code to make it easier to work with.
These are a bit more advanced so don’t worry if you don’t get them straight away.

• We can change your big `if` `elif` block into a single `for` loop.
Lets see what we have so far:

``````if counters > len(lib):
counters = 0
counters += 1
``````

We know that this section is repeated each time for each index.
So we can make this generic by changing `0` to `index` and `1` to `index + 1`.

``````if counters[index] >= len(lib):
counters[index] = 0
counters[index + 1] += 1
``````

Now we just need to loop over `range(len(counters) - 1)` to duplicate the block 9 times.

``````for index in range(len(counters) - 1):
if counters[index] >= len(lib):
counters[index] = 0
counters[index + 1] += 1
``````
• We can use some Python sugar to make your print for loop ‘cleaner’.
Firstly we can remove all the `print`s by building a list.

``````combination = []
for counter in counters:
combination.append(lib[counter])
``````

From here we can join all the strings together with `"".join` and pass it to `print` like you did before. This will join the list by empty strings so it converts it’s like manually doing `combination + combination + ...`.

``````print("".join(combination), end="\r")
``````

We can then use a list comprehension to build `combination` in one line.
This is just syntaxtic sugar and is the same as the for loop we used before.
It’s just different, cleaner, syntax.

``````combination = [lib[counter] for counter in counters]
``````
• We can use either a `while True` loop or `itertools.count` rather than `range(sys.maxsize**99999)` to loop infinitely.

``````while True:
counters += 1
``````
``````import itertools

for _ in range(itertools.count()):
counters += 1
``````
• We can probably just use `print` rather than `sys.stdout.write`.

To make it so there is no newline we can pass `end=""`.
This however doesn’t flush the stream straight away, and so we need to pass `flush=True`.

``````lib = [''] + list('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz°!"§\$%&/()=ß´`+#-.,><@€|^~–{[]}ÄÖÜäöü')
counters = [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0]

while True:
counters += 1
for index in range(len(counters) - 1):
if counters[index] >= len(lib):
counters[index] = 0
counters[index + 1] += 1

if counters >= len(lib):
print("DONE.")
else:
print("".join([lib[counter] for counter in counters]), end="\r")
print("\b"*10 + " "*10 + "\b"*10, end="", flush=True)
``````