Docstrings
Python documentation strings (or docstrings) provide a convenient way of associating documentation with Python modules, functions, classes, and methods. An object's docstring is defined by including a string constant as the first statement in the object's definition.
def guess_word():
"""Do calculations and return correct guessed word."""
Style
check pep0008 https://www.python.org/dev/peps/pep-0008/ the official Python style guide and here are some comments:
import string
def main(word):
Surround top-level function and class definitions with two blank lines.
ntries = 0
if b==word:
- Use descriptive variable names, improves readability and general
understanding of the code.
- Always surround these binary operators with a single space on either
side: assignment (=), augmented assignment (+=, -= etc.), comparisons
(==, <, >, !=, <>, <=, >=, in, not in, is, is not), Booleans (and,
or, not). Except when = is used to set a function parameter.
The code
len_word
len_word = len(word)
ntries = 0
while True:
letters = []
for i in range(len_word):
the variable len_word is unnecessary, can be expressed:
while True:
letters = []
for i in range(len(word)):
Random brute forcing:
a sample size of 6 out of 26 alphabets has 230230 possible combinations (where order is unimportant and each combination has n! re-orderings where n = combination length (letters in the word) what is very obvious is that with such algorithms, it is very likely that zombie dinosaurs start showing up before the code guesses the correct word (10 years to be able to guess a 10 letter word for 500,000 secret words/passwords examined per second). So if what you are trying to build is a password cracker, the algorithms that are better than brute forcing are beyond the scope of this review.
What your mini-program does is trying n digit random choices and comparing them to the secret word which number of trials is variable
input a word: red
Mission accomplished. It took 8428 tries.
input a word: red
Mission accomplished. It took 16894 tries.
and since it's a random choice(not entirely random because it's based on a so-called 'pseudo-random' algorithm, you might generate the same number of trials for a random.seed(n)) this is not the case however, it tries different possibilities, so with some bad luck, that with some word lengths might keep running until aliens start making documentaries about us.
Assuming we can check each character separately:
(** This is not the case of password crackers in the real world which must guess the exact word).
# Note: I have tried making the program guess the letters one by one, and then
# check if said letter was right, but it seemed to make the problem even worse.
and since you asked about separate letter comparison:
import string
def guess_word():
"""Match characters with user input and return number of iterations, correct guess."""
possible = string.ascii_lowercase + string.ascii_uppercase + string.digits + string.punctuation + ' '
secret_word = input('Enter word: ')
yield len(possible) * len(secret_word)
for index in range(len(secret_word)):
for char in possible:
if secret_word[index] == char:
yield char
if __name__ == '__main__':
word = list(guess_word())
print(f"Total: {word[0]} iterations.\nWord: {''.join(word[1:])}")