How can I stop my program from generating the same key? - python

I writing a password generator and I ran into this annoying issue, and it is the repeating a a number or letter on the same line. The user gives the program a format on how they want their password to be generated ex "C##d%%%"
where # is only letters and where % is only numbers, and the user also inputs the numbers and letters to generate the password, then the program is suppose to print out something like cold123, but instead it prints out cood111 or clld111, I will post a snippet of my code below, but please don't bad mouth it, I'm fairly new to python, self-taught and just about couple of months into the python experience.
class G()
.
.
.
# self.forms is the format the user input they can input things such as C##d%%%
# where # is only letters and where % is only numbers
# self.Bank is a list where generated things go
AlphaB = [] #list Of All Of The Positions That have The # sign in The self.forms
NumB = [] #list of All of the positions that have a % sign
for char in self.forms:
if char == '#':
EOL=(self.Position) # Positions End Of Line
Loc = self.forms[EOL] # Letter
AlphaB.append(EOL)
if char == '%':
EOL=(self.Position)
Loc = self.forms[EOL]
NumB.append(EOL)
self.Position+=1 # Move right a position
for pos in AlphaB:
for letter in self.alphas: #letters in The User Inputs
GenPass=(self.forms.replace(self.forms[pos],letter))
#Not Fully Formatted yet, because Only The letter been formatted
if GenPass.find('%'):
for Pos in NumB:
for number in self.ints:
GenPass=(GenPass.replace(GenPass[Pos],number))
if GenPass not in self.Bank:
#Cood111
print (GenPass)
self.Bank.append(GenPass)
else:
if GenPass not in self.Bank:
print (GenPass)
self.Bank.append(GenPass)

GenPass.replace(GenPass[Pos],number) will replace every occurrence of the character at GenPass[Pos] with the value of number. You need to make sure you replace one character at a time.

Create a list of all chars and a list with all nums, then just pick one by using list.pop(randint(0, len(list) - 1), you will always pick a different letter / number like this but you will also be limited to 10 digits (0-9) and 20-something letters.

Related

No duplicate characters in string output - Python

What im making
Hi!
Im making a password generator script in Python ( Script below ). and i was wondering what the best way would be to make sure the passwords dont have two of the same character/symbol right after eachother.
as an example:
kjhd8!3JJp-#huwwg
i would like a way within my script to make sure the duplicates arent "touching". if that makes sense (my english isnt very good).
the same password can have the same character, thats fine. but i would like it not to have them "touching"
like:
kjwhd8!3Jp-#huwJg
if that makes sense.
The script
import random
import string
import sys
#amount of passwords to make
amount = 10
# Characters and symbols to use for the password
# ive split it up to make sure it takes from all of the lists
chars ="abcdefghjkmnpqrstuvwxyzABCDEFGHJK"
specials="#####!-----"
digits="2346789"
characters = list(chars + digits + specials)
def generate_random_password():
# length of the passwords
length = 18
# mixes and shuffles the characters
random.shuffle(characters)
# Puts the sections together at random
password = []
for i in range(length):
password.append(random.choice(characters) )
# another shuffle to make sure (probably noy needed but meh)
random.shuffle(password)
# converts to a string
print("".join(password))
# Prints out as many passswords as stated in the "amount" variable
for index in range(amount):
generate_random_password()
You can just check if the generated char is the same that the previous one, if it is: pick another char, else continue.
prev_char=None
for i in range(length):
random_char = random.choice(characters)
while prev_char == random_char:
random_char = random.choice(characters)
password.append(random_char)
prev_char = random_char
You can use a regex for this!
The expression:
(.)\1
What it does:
(.) - group that matches one character
\1 - reference to group 1 (the group above)
What this essentially does is that it looks for a character repeating right after itself.
How to use it?
import re
any(re.findall(r"(.)\1", "kjwhd8!3Jp-#huwJg"))
findall will find any ocurrences of this; any will give you True or False if there are any cases.
Note: You could also extend this so that the same character doesn't repeat within the next let's say 4 characters: (.).{0,4}\1

Is there a way to append a list with the same item, if the same item appears twice?

I am trying to build a complex hangman game in Python for a school assignment (first post on here btw, so sorry if I don't use the correct etiquette). My code so far is operating on a basic, but functional level; I have a generated file filled with random word variation. I import the file, put it into a list, clean the data and use random to randomly select a word. The program repeatedly asks the user to input a letter or word until they guess correctly or run out of lives. I have ran into an issue where if the same letter appears multiple times in a word, it won't register the fact that it needs to scan and append the list twice for each time the word appears. This might be a really simple problem, but I appreciate any help. Thanks in advance!
(P.S. underscores is the list that displays underscores in place of unidentified letters for the output)
elif guess in correctLetters:
print("\nYou got a letter! Here is where it appears in the word:\n")
index = word.index(guess)
underscores[index] = guess
for i in underscores:
print(i, end="")
In terms of an example, I want the code to use the user's input ('guess') and see if it appears in the list 'correctLetters'. If it does, I want the code to append 'guess' into the correct index in the list. E.g. if the unknown word is 'hangman' and ('guess') is 'h', the code will append 'h' into the correct position in the list and then just make the list look more pleasing to the eye. My current problem is (following the example outlined above) if I were to enter 'a' I want the code to return '_ a _ _ _ a ' where as now it will only return ' a _ _ _ _ _'. I need the code to see that the same item appears twice in the list and so it appends it twice as well in the list that will be shown to the user. Hope this makes my issue clearer.
You might think about going through your hidden word letter for letter and construct a display version of it revealing guessed letters or hiding unguessed letters. Maybe like:
guesses = set()
word = "hello"
## each round make a guess...
guess = "l"
guesses.add(guess)
letters_underscored = [
letter if letter in guesses else "_"
for letter in word
]
word_underscored = "".join(letters_underscored)
print(word_underscored)
This will give you:
__ll_
The code in your question:
index = word.index(guess)
underscores[index] = guess
...finds the first occurrence of the letter in the word and replaces the underscore with the guess. A simple way to replace all occurrences would be to loop until word.index(guess) raises an exception, ignoring indices that have already been replaced by using the second argument of the index method, which specifies a starting point for the search. E.g.:
index = -1
done = False
while not done:
try:
index = word.index(guess, index + 1) # find the index of guess in word that occurs after `index + 1`
underscores[index] = guess
except ValueError:
# if all occurrences have been replaced, stop
done = True

How do you set the value of a variable based on user input in Python?

In my program, the user can input a list of words or the letter n. What I want to do is when they input n, it want it to set the value of the variable where the user input is saved to a question mark (?).
Also in my program, the user inputs a different list, if they input n, I want the program to generate a word frequency table.
The problem I'm having is that when I write out the if statements for if the user input is n, I don't think that it's changing the value or creating the frequency table.
I've shifted where the code is in the program. I'm not getting the response from either if statement no matter where I put it in the code. Originally I thought the program was that I had put it near the end of the program and since it was reading it top to bottom, nothing was happening. Now, I'm not sure.
I've included the pieces of the code that would work together so I'm not pasting the entire program.
# Ask user for needed keywords or symbols
user_keywords = input("What keywords or special symbols would you like to search the provided file for?\n"
"Please separate each entry with a comma.\n If you would like to just search for question marks"
"please just type n.")
# Holding list, using comma as a way to separate the given words and symbols
list1 = list(user_keywords.split(','))
# Print list for user to see
print("You have entered the following keywords and/or special symbols: ", list1)
# Ask user for needed repeating words
user_repeating = input("What repeating words would you like to search the provided file for?\n"
"Please separate each entry with a comma. \n If you would like a frequency table for all words"
"two letters or more, please type n.")
# Holding list, using comma as a way to separate the given words and symbols
list2 = list(user_repeating.split(','))
# Print list for user to see
print("You have entered the following words: ", list2)
frequency = {}
# Check to see if list1 has no parameters and sets to ?
if list1 == 'n':
list1 = '?'
print("We will search for any question marks.")
# Check to see if list2 has no parameters and creates a frequency array
if list2 == 'n':
document_text = open (path1, 'r')
text_string = document_text.read().lower()
match_pattern = re.findall(r'\b[a-z]{2-20}\b', text_string)
print("We will look for all word frequencies.")
for word in match_pattern:
count = frequency.get(word,0)
frequency[word] = count + 1
frequency_list = frequency.keys()
for words in frequency_list:
print(words, frequency[words])
I expect list1 to be set to ? when n is entered by the user. I expect list2 to generate a word frequency table when n is entered by the user.
I'm not getting any errors. At this point is just goes straight to the end of the program and returns the final print line I have in it, so I know it isn't calling the if statements.
Surely the way to do this is to replace:
list1 = list(user_keywords.split(','))
with
list1 = '?' if user_input == 'n' else list(user_keywords.split(','))
no?

Hangman game project

I'm trying to a hangman game. I already achieved to set the basics of the game (list, interaction with user) but I don't know how to do the lines for the game, keep asking and printing what the user correct answers are and ilustrate the hangman.
I used index in order to search the exact location of the letter in the word, but I dont know to print it, depending on the number and also I don't how to code that the program keeps track of the correct words.
I would be totally glad for your help. Also thanks for your patience.
The first part of the code is well coded but stackoverflow doesn't display it right.
------------------------------------------------------------------------
import random
def hangman():
words = ['house','car','women', 'university','mother', 'school', 'computer','pants'] #list of words
computer = words[random.randint(0,6)] #computerchoice
word = list(computer) #Make a list with each letter of the word.
welcome = (input ('Welcome, type ok to continue: '))
if welcome == 'ok':
length = len(word)
print(f'help? the word has {length} letters')
option = (input('Start guessing, letter by letter'))
count= 0 #count takes the count of how many tries.
chances = length+3 #You are able to make 3 mistakes.
while count<=chances:
if option in word: #if the choice is there
place = word.index(option) #search for the place.
print() #dont know how to print it in 'that' place.
#place the correct letter over that line.
print('_ '*length) #Trying to do the under lines.
count+=1
else:
break
#Dont know to ilustrate the hangman depending on the length of the word.
hangman()
First let's analyse your code:
import random
def hangman():
words = ['house','car','women', 'university','mother', 'school','computer','pants'] #list of words
computer = words[random.randint(0,6)] #computerchoice
word = list(computer) #Make a list with each letter of the word.
Everything is fine up to here , although str can be used the same way as a list , so no need to transform it.
welcome = (input ('Welcome, type ok to continue: '))
if welcome == 'ok':
length = len(word)
print(f'help? the word has {length} letters')
Yes but those are not unique letters. You can use set() to have the number of unique letters.
option = (input('Start guessing, letter by letter'))
If your input starts here, you will only ask once for a letter , you need to include this part in the while loop
count= 0 #count takes the count of how many tries.
chances = length+3 #You are able to make 3 mistakes.
This would then probably be changed to the length of the set.
while count<=chances:
if option in word: #if the choice is there
place = word.index(option) #search for the place.
This will only give you the index of the first occurence.
We should keep in mind to use regex for this type of search : Find all occurrences of a substring in Python
print() #dont know how to print it in 'that' place.
Let's remember to use the print formating f'stufff{value}stuffff'
#place the correct letter over that line.
To do it , you need to create a str only with _and then fill it in with the indexes using list comprehension .
print('_ '*length) #Trying to do the under lines.
count+=1
Maybe we should handle what happens if option is not in words ?
else:
break
#Dont know to ilustrate the hangman depending on the length of the word.
Also there is no need for break : count increments and therefore while will terminate. And if it was for the outer if/else , break doesn't work outside a loop.
hangman()
Question for OP:
What point would you like to sort out yourself ? What do you need help for next ?

How do I make it where the code ignores every symbol within a string except for those in a list?

I was trying to make a program that could be used for one-time pad encryption by counting the number of characters and having a random number for each one. I started making a line that would let the program ignore spaces, but then I realized I would also need to ignore other symbols. I had looked at How to count the number of letters in a string without the spaces? for the spaces,
and it proved very helpful. However, the answers only show how to remove one symbol at a time. To do what I would like by using that answer, I would have to have a long line of - how_long.count('character')'s, and symbols that I may not even know of may still be copied in. Thus, I am asking for a way where it will only count all the alphabetic characters I write down in a list. Is this possible, and if so, how would it be done?
My code:
import random
import sys
num = 0
how_long = input("Message (The punctuation will not be counted)\n Message: ")
charNum = len(how_long) - how_long.count(' ')
print("\n")
print("Shift the letters individually by their respective numbers.")
for num in range(0, charNum-1):
sys.stdout.write(str(random.randint(1, 25))+", ")
print(random.randint(1, 25))
If your desired outcome is to clean a string so it only contains a desired subset of characters the following will work but, I'm not sure I totally understand what your question is so you will probably have to modify somewhat.
desired_letters = 'ABCDOSTRY'
test_input = 'an apple a day keeps the doctor away'
cleaned = ''.join(l for l in test_input if l.upper() in desired_letters)
# cleaned == 'aaadaystdoctoraay'
Use Regex to find the number of letters in the input:
import re, sys, random
how_long = input("Message (The punctuation will not be counted)\n Message: ")
regex_for_letters = "[A-Za-z]"
letter_count = 0
for char in how_long:
check_letter = re.match(regex_for_letters, char)
if check_letter:
letter_count += 1
print(letter_count)
for num in range(0, letter_count-1):
sys.stdout.write(str(random.randint(1, 25))+", ")
print(random.randint(1, 25))
Filter the string:
source_string='My String'
allow_chars=['a','e','i','o','u'] #whatever characters you want to accept
source_string_list=list(source_string)
source_string_filtered=list(filter(lambda x: x in allow_chars,source_string_list))
the count would be: len(source_string_filtered)

Categories

Resources