I made a python random sequence generator, I can tell it the max the length of the sequence can be but I want it to stop at a specific sequence... I have spent a couple days searching for a way to do this.
I made the generator do what I want, make a random letter (uppercase and lowercase) and number sequence(I am able to manually change the max it can be) and I made it so It will run forever using a while loop. searched for a couple days to get it the way I want but wont work.
import string, random
while True :
def id_generator(size=2, chars=string.ascii_uppercase +
string.ascii_lowercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
if id_generator() == "2g":
break
print("found your code")
else :
print(id_generator())
The "size" makes the max the sequence can be. I wanted the the if statement to say if it creates "2g" to stop and say "found your code" else just keep generating... I think it has something to do with the if statement
First of all, don't define the function in the while loop. Define it elsewhere and then call it inside the while.
Next, after calling the function assign its value to a variable and let that be used by the conditionals.
I finally got it...
import string, random
num = input("Pick your num: ")
while True :
def id_generator(size=2, chars=string.ascii_uppercase + string.ascii_lowercase +
string.digits):
return ''.join(random.choice(chars) for _ in range(size))
if id_generator() == num:
print("found your code")
print(num)
break
else :
print(id_generator())
Related
I'm currently working on this problem that ask me to generate an arrow pattern using loops function that looks something like this:
"How many columns? 3"
*
*
*
*
*
I know I can do this with for loop(probably more efficient too), but that is not what I aimed for. I wanted to achieve this only using while loop.
I have some ideas:
1. I set up a control variable and an accumulator to control the loop
2. I then write 2 separate loops to generate the upper and lower part of the pattern. I was thinking about inserting the space before the asterisks using method like this:
(accumulator - (accumulator - integer)) * spaces.
#Ask the user how many column and direction of column
#they want to generate
Keep_going = True
Go = 0
while keep_going:
Column_num = int(input("How many columns? "))
if Column_num <= 0:
print("Invalid entry, try again!")
else:
print()
Go = 1
#Upper part
while Keep_going == True and Go == 1:
print("*")
print(""*(Column_num - (Column_num - 1) + "*")
...but I soon realized it wouldn't work because I don't know the user input and thus cannot manually calculate how many spaces to insert before asterisks. Now everything on the internet tells me to use for loop and range function, I could do that, but I think that is not helpful for me to learn python since I couldn't utilize loops very well yet and brute force it with some other method just not going to improve my skills.
I assume this is achievable only using while loop.
#Take your input in MyNumber
MyNumber = 5
i = 1
MyText = '\t*'
while i <=MyNumber:
print(MyText.expandtabs(i-1))
i = i+1
i = i-1
while i >=1:
print(MyText.expandtabs(i-1))
i = i-1
Python - While Loop
Well first you have to understand that a while loop loops until a requirement is met.
And looking at your situation, to determine the number of spaces before the * you should have an ongoing counter, a variable that counts how many spaces are needed before you continue. For example:
###Getting the number of columns###
while True:
number=int(input('Enter number of rows: '))
if number<=0:
print('Invalid')
else:
###Ending the loop###
break
#This will determine the number of spaces before a '*'
counter=0
#Loops until counter equals number
while counter!=number:
print(" "*counter + "*")
#Each time it loops the counter variable increases by 1
counter=counter+1
counter=counter-1
#Getting the second half of the arrow done
while counter!=0:
counter=counter-1
print(" "*counter + "*")
Please reply if this did not help you so that i can give a more detailed response
I have the Basic of the code laid out the problem is I do not know how to use the length of the keyword correctly.
When I run the problem I just get a bunch of S's as my output cause the code is not going to the next letter of the keyword.
I need help in the Def Encrypt part (the second def)
Keyword is SECRET // This is input
def encrypt_letter(text_letter , code_letter):
alphabet = string.ascii_uppercase
index = alphabet.find(code_letter)
cypher = alphabet[index:]+alphabet[:index]
index2 = alphabet.find(text_letter.upper())
result = cypher[index2]
if text_letter.islower():
result = result.lower()
return result
def encrypt(text, code):
cypher_text = ''
for letter in text:
if letter.isalpha():
cypher_text += code_word[0:1:6]
# code_letter = ?
# encrypt_letter(letter, )
else:
cypher_text += letter
return cypher_text
code_word = input('Please enter the code word: ')
code_word = code_word.upper()
cypher_text = encrypt(plain_text, code_word)
print(cypher_text)
Since this is clearly a student problem set, work on it a little longer and come back to ask a specific question, but a few hints:
Initialize a counter to count how many letters .isalpha() you've encountered
Use counter % len(secret_code) to keep track of your current position in the secret code
Use ASCII integer arithmetic and some if/else logic to modify characters in the cypher_text by counter % len(secret_code)
ord() and chr() will help you
If you're really stuck and need to peek at a solution, mine's here: https://github.com/bennett39/learning-exercises/blob/master/cs50/pset6/vigenere/vigenere.py
Spend a little more time on your solution before clicking that link, though.
I am creating a cipher script in python without any modules but I have come accross a problem that i cant solve. When I am comparing msg[3] which has the value (space) it should be equal to bet[26] which is also a space. If i compare msg[3] with bet[26] in the shell...
>>>msg[3] == bet[26]
True
The output is True. However when i run the program and output the value of enmsg there is no value 26 where the value 26 should be.
enmsg = []
msg = "try harder"
bet = "abcdefghijklmnopqrstuvwxyz "
for x in range(0, len(msg)):
for i in range(0, 26):
if msg[x] == bet[i]:
print(msg[x])
enmsg.append(i)
You should get out of the habit of iterating over a range of indices and then looking up the value at the index. Instead iterate directly over your iterables, using enumerate when necessary.
enmsg = []
msg = "try harder"
bet = "abcdefghijklmnopqrstuvwxyz "
for msg_char in msg:
for index, bet_char in enumerate(bet):
if msg_char == bet_char:
print(msg_char)
enmsg.append(index)
Your second loop iterations are too short so it is not reaching the space symbol.
Try with this:
enmsg = []
msg = "try harder"
bet = "abcdefghijklmnopqrstuvwxyz "
for x in range(0, len(msg)):
for i in range(len(bet)):
if msg[x] == bet[i]:
print(msg[x])
enmsg.append(i)
The upper bound of range is not inclusive; you'll need to extend this by one to actually check the 26th index of the string. Better yet, iterate up through len(bet) as you did for len(msg) for the outer loop.
this might seem very basic to you, and I think I know what is wrong with my code, I just can't seem to figure out how to fix. Basically, I am building a very simple hangman game, and I want to make the user lose a life every time he guesses a letter wrong. Here is the code:
import random
word_choice = ["list", "microsoft", "cars", "philosophy", "mother", "powder", "star", "baby", "elephant"]
guessed_letters = []
right_guessed_letters = []
def user_turn(c):
lives = 10
while True:
guess = input("\nGuess a letter or a word: ")
guessed_letters.append(guess)
print ("\n")
if lives != 0 and guess != comp_choice:
if guess in comp_choice:
right_guessed_letters.append(guess)
for i in comp_choice:
if i in right_guessed_letters:
print (i, end= ' ')
else:
print ('-', end = ' ')
else:
lose_life(lives)
continue
elif guess == comp_choice:
print ("Good job, you guessed the word correctly!")
break
elif lives == 0:
print ("You lost, your lives are all depleated...")
break
def lose_life(l):
l -= 1
print (f'Wrong letter, you have {l} lives remaining')
print (f"The letters you already guessed are {guessed_letters}")
comp_choice = random.choice(word_choice)
word = '-' * len(comp_choice)
print (f"Your word is : {word} long.")
user_turn(comp_choice)
Basically, my problem is that the user can only lose one life. In fact, I would like that every time lose_life is called, the user loses a life so his lives decrease by one every time, however the variable lives gets it's original value right after the function is done rolling. So every time the function is called, the user is at nine lives. Here is the output:
microsoft
Your word is : --------- long.
Guess a letter or a word: d
Wrong letter, you have 9 lives remaining
The letters you already guessed are ['d']
Guess a letter or a word: e
Wrong letter, you have 9 lives remaining
The letters you already guessed are ['d', 'e']
Guess a letter or a word:
Anyways, If you could help, it would be very appreciated!
Your lose_life function is not returning anything, so all it effectively does is printing the two statements.
if you added a return l at the end of lose_life function, and change your lose_life(lives) in the else statement to lives = lose_life(lives), it should now work.
If this seems cumbersome and you're feeling adventurous, you may consider using Classes instead:
class Live(object):
def __init__(self, value=10):
self.value = value
def __str__(self):
return str(self.value)
def __repr__(self):
return self.__str__()
def lose(self):
self.value -= 1
print(f'Wrong letter, you have {self.value} lives remaining')
print(f"The letters you already guessed are {guessed_letters}")
def gain(self):
self.value += 1
# insert your own print messages if you wish.
Mind you I wouldn't recommend doing it for this use case (KISS principal applies), but for more complex projects where you have objects that need their own attributes and functions, Classes are great for that purpose.
I'm working on a hobby project. I'm attempting to make a hangman game in Python. So far everything works nice. There's just one problem. If I type a letter that appears in the word two times, I can't get the second letter to appear. I've been toying around with string.find and string.count methods but to no avail. Does anyone have an idea how I would go about doing this? I'm stumped.
#!bin/bash/python
import os
import time
word = 'megalopolis'
l = len(word)
list = []
n=0
while n!=l:
list.append('-')
n+=1
os.system('cls' if os.name=='nt' else 'clear')
print list
i=3
while i!=0:
x = raw_input('Enter a letter: ')
if x in word and x!='':
print 'Good choice!'
count=word.count(x)
loc=word.find(x)
print count
print loc
list[loc]=x
os.system('cls' if os.name=='nt' else 'clear')
if '-' not in list:
break
print list
else:
print 'Sorry...'
i-=1
if i==2:
print 'You have '+`i`+' more chances.'
if i==1:
print 'You have '+`i`+' more chance!'
time.sleep(1)
os.system('cls' if os.name=='nt' else 'clear')
print list
if '-' not in list:
print 'YOU WIN!!'
else:
print 'GAME OVER!!'
x = raw_input('press enter')
If you just need the index of every character occurence:
indexes = [idx for idx, ch in enumerate(word) if ch == x]
Perhaps you should use Unidecode to keep the accents in words, it might be useful depending on the language (if not English). Also, you can use str.lower() or str.upper() methods to ensure every word and trial is in the same case.
The string module has useful constants for you (e.g. ascii_uppercase).
However, in this game you don't need to worry about any index. I've made another version for you:
#!/usr/bin/env python
from string import ascii_uppercase
word = "megalopolis".upper() # Top-secret!
trial = 3 # Total trials available (number of mistakes to lose the game)
typed = set() # Typed characters
word_letters = set(word)
while trial:
print
print "".join(ch if ch in typed else "-" for ch in word)
# Winning condition
if typed.issuperset(word_letters):
break
# Data input
x = raw_input("Enter a letter: ").upper()
# Error cases
if len(x) != 1:
print "Invalid input."
continue
if x in typed:
print "Already typed."
continue
if x not in ascii_uppercase:
print "What you typed isn't a letter."
continue
# Valid data cases
typed.add(x)
if x in word:
print "Good choice!"
else:
print "{} not found!".format(x),
trial -= 1
if trial == 1:
print "You have one more chance!"
elif trial > 1:
print "You have {} more chances.".format(trial)
else:
print 'Sorry...'
# Ending message
print
if trial:
print "YOU WIN!!"
else:
print "GAME OVER!!"
Hashbang: Your shebang should usually start with "#!/". You're probably using Windows, so the "bin" as a relative directory wasn't used by you.
"l" / l as a variable name should be avoided! It might be seen as one or lower "L" (PEP8), or even a pipe "|". PS: At the beginning of this item, I typed the same letter here twice.
There's no need to use "list" as a variable name here, and you shouldn't do, as that's a built-in name.
Multiplication like "txt" * 3 returns "txttxttxt" (it repeats the data) for both strings and lists
Neither "cls" nor "clear" worked here, showing
"TERM environment variable not set."
instead of clearing the console screen. I replaced these with an empty
"print", and removed the time sleep. Look for subprocess if you want to call something from console (although I'd also look for curses if there's a need to do some CLI visualization).
Suppose x is a string. When x == "", bool(x) is False, else bool(x) is True.
Suppose x is an integer. When x == 0, bool(x) is False, else bool(x) is True.
Avoid backticks (`). No one uses them today in Python, they doesn't exist in Python 3 and you can use the repr built-in instead. However, you probably wanted something like str(trial), "%d" % trial or "{}".format(trial).
The last "press enter" probably has to do with an operating system "auto-close-after-finish" behaviour, but you [at least] didn't need to store it in x.
I've used a generator expression. You should read here about list comprehensions if the "for" in the middle of one line is confusing for you. Python developers use generator expressions and list comprehensions all the time, you shouldn't avoid learning about them.
I replaced the original winning evaluation to a comparison between the set of characters the word originally has and the set of typed characters (both uppercase).
If there's something here you didn't understand, please ask a new question.
This SO question ought to cover it for you:
Finding multiple occurrences of a string within a string in Python
It should work just as well for individual characters as strings, considering how easy it is to form the second from the first.
So in the end, I wound up doing it this way:
if x in word and x!='':
count=word.count(x)
loc=0
while count==1 or count>1:
loc=word.find(x,loc)
list[loc]=x
loc+=1
count-=1
print 'Good choice!'
Thanks for your help everyone. I definitely learned something.