Checking if a list has something in it - python

I'm currently making a "match stick" game in CLI and It's Player vs AI. Almost everything works properly except that the "AI" chooses a stick that has been previously removed.
Here is the code:
class CPyramide(object):
def __init__(self, lines):
self.pir = []
for i in range(lines):
sticks = ["|" for j in range(i+1)]
self.pir.append(sticks)
def __str__(self):
o = ""
for i, L in enumerate(self.pir):
spaces = (len(self.pir) - i) * " "
o += spaces
o += " ".join(L)
o += "\n"
return o
def stickDelete(self, line, n):
self.pir[line] = self.pir[line][n:]
try:
lines = int(sys.argv[1])
sticks = int(sys.argv[2])
cpir = CPyramide(lines)
print(cpir)
while True:
print("Your turn:")
inputLine = input("Line: ")
inputSticks = input("Matches: ")
if int(inputSticks) > sticks:
print("Error: you cannot remove more than",sticks,"matches per turn")
continue
else:
print("Player removed",inputSticks,"match(es) from line",inputLine)
cpir.stickDelete(int(inputLine) - 1,int(inputSticks))
print(cpir)
print("AI's turn...")
aiSticks = randint(1,sticks)
aiLines = randint(1,lines)
print("AI removed",aiSticks,"match(es) from line",aiLines)
cpir.stickDelete(aiLines - 1,aiSticks)
print(cpir)
I've been trying to make it so it checks every array that contains a [|] and possibly remove it but I don't know how I can make it.
Is there a way I can make the function cpir.stickDelete checks if an array has a [|] in it and possibly remove it but randomly? Because everytime I'm playing with the AI it just chooses something that has already been previously removed.
Is there a way to check through every array and possibly check if it contains a [|] and remove it but randomly?
Thanks for reading.

Try this :
if "|" in my_list:
my_list.remove("|")

Related

I would like to know a way to find a word from a mix of known letters, from a known list

For context, it is for a pokemon trivia bot every once in a while on a discord server I'm on, and just wanted to try my skills at making one, although my code only works for the first word in my list (simply a list of all pokemon from Bulbasaur onward by number). I have it so that the user enters the known letters in the format of underscores for blanks, and the letters for the known letters. (ex. Bulbasaur could be '_ _ l _ a s a _ _' (NO spaces between) The user also inputs the number of known letters, for use later in the program. It reads in the list, puts it in an array, and then pulls out all names that match the length of the inputted word. It then begins to compare each letter to each inputted letter to find a match, if the letters matched (amount) equals the inputted numbers given, it shows that 'the pokemon is: ' and the pokemon. the issue is that it only works for one pokemon, and the others do not seem to work. I am going to post the code below, and any help would be greatly appreciated :)
also, if the list is needed, I can add that as well somehow (over 500 lines)
poke = input("Letters and spaces given: ")
pokelen = input("Number of Letters given:")
print(pokelen)
pokelen = int(pokelen)
############################################
fid = open('pokemon.txt','r')
f = fid.readlines()
g = []
for i in f:
i = i.replace('\n', '')
g.append(i)
fid.close()
candidates = []
ticker = 0
while ticker != len(g):
if len(g[ticker]) == len(poke):
candidates.append(g[ticker])
ticker +=1
print(candidates)
############################################
start = []
end = []
ticker1 = 0
ticker2 = 0
done = 0
while done == 0:
while ticker1 != len(candidates):
if done == 1:
break
word = candidates[ticker1]
tick = 0
length = len(word)
a = 0
for i in word:
start.append(i)
tick += 1
tick = 0
for i in poke:
end.append(i)
tick += 1
while length != ticker2:
if start[ticker2] == end[ticker2]:
a += 1
ticker2 += 1
if a == pokelen:
print("The Pokemon is:",word)
break
ticker1 += 1
done = 1
print(done)
print(a)
############################################
If you don't want to use regular expressions, you could do it by comparing strings too!
First, let's define a function that does this:
def is_match(pokemon: str, pattern: str) -> bool :
return len(pokemon) == len(pattern) and \
all(x == y for x, y in zip(pokemon, pattern) if y != "_")
This function performs the and operation on two conditions:
Checks if the lengths of both strings are the same
zips the pokemon and pattern strings, and iterates over them character-by-character, checking to see if all pairs of letters are equal. This is potentially an expensive operation if the strings are large.
The return value is the and of these two conditions. Python's short-circuiting logic ensures that the potentially expensive operation is only performed if necessary (if lengths of the two strings are unequal, there's no point even trying to match the pattern).
Assuming we have the list of pokemon and pattern string already:
all_pokemon = ["Bulbasaur", "Ivysaur", "Venusaur", "Charmander", "Charmeleon", "Charizard", "Squirtle", "Wartortle", "Blastoise", "Caterpie", "Metapod", "Butterfree"] # and so on...
pattern = "__l_asa__".lower()
We just need to loop through our list of pokemon, run the is_match function on each one, and select only those for which is_match is true.
pokemon = []
for p in all_pokemon:
if is_match(p.lower(), pattern):
pokemon.append(p)
print(pokemon) # Output: ['Bulbasaur']
Or, as a list-comprehension,
pokemon = [p for p in all_pokemon if is_match(p.lower(), pattern)]
print(pokemon) # Output: ['Bulbasaur']
If you tried to match a pattern that works for multiple pokemon, that's cool too!
pattern = "ch_rm_____"
pokemon = [p for p in all_pokemon if is_match(p.lower(), pattern)]
print(pokemon) # Output: ['Charmander', 'Charmeleon']
I'm not exactly sure what the code inside the while loop is attempting to do. I think you are looking to match the input with the potential pokemon. As #RufusVS and #Barmar suggest, there might be a way to do what you are looking to do without the details in your while loop.
In the end are you going to try to make a "hangman game"?
import re
############################################
## load names of all pokemon
############################################
#with open('pokemon.txt','r') as fid:
# all_pokemon = [p_name.strip() for p_name in fid.readlines()]
all_pokemon = ["bulbasaur", "charmander", "eevee", "pikachu", "squirtle"]
############################################
############################################
# ask for a name to try to match
############################################
your_pokemon = input("Letters and spaces given (e.g. pik_chu): ").lower()
your_pokemon_re = re.compile("^%s$" % your_pokemon.replace("_", "."))
############################################
############################################
# from all_pokemon find potential matches
############################################
matches = [pokemon for pokemon in all_pokemon if re.match(your_pokemon_re, pokemon)]
############################################
############################################
# See if we can guess
############################################
for match in matches:
if input("Is your pokemon %s? " % match).lower() in ("y", "yes"):
print(":-)")
break
else:
print("I give up. I don't seem to know your pokemon")
############################################
In the event that you would like to compare stings character by character (as I think was your intent) then here is a modification to do it that way:
############################################
## load names of all pokemon
############################################
#with open('pokemon.txt','r') as fid:
# all_pokemon = [p_name.strip() for p_name in fid.readlines()]
all_pokemon = ["bulbasaur", "charmander", "eevee", "pikachu", "squirtle"]
############################################
############################################
# ask for a name to try to match
############################################
your_pokemon = input("Letters and spaces given (e.g. pik_chu): ").lower()
############################################
############################################
# Alternate (slight more traditional) way to find matches
# this compares character by character similar to what you did
############################################
# will ensure same length strings later
candidates = [pokemon for pokemon in all_pokemon if len(your_pokemon) == len(pokemon)]
matches = []
for pokemon in candidates:
for index, character in enumerate(pokemon):
if your_pokemon[index] not in (character, "_"):
## this character is not a match not a "_" so break
## if there is no break, a for loop does it's "else"
break
else:
matches.append(pokemon)
############################################
############################################
# See if we can guess
############################################
for match in matches:
if input("Is your pokemon %s? " % match).lower() in ("y", "yes"):
print(":-)")
break
else:
print("I give up. I don't seem to know your pokemon")
############################################
we accomplished something like this with our "fishing" (hangman style) cog in our discord bot.
I might be wrong on what you are wanting here but i think its close at least.
we defined a function to scatter the names.
def scatter(iterable):
new_list = []
for i in iterable:
if random.randint(1, 2) == 1 and new_list.count("_") <= len(iterable) // 2:
new_list.append("_")
else:
new_list.append(i)
return "".join(new_list)
and use it later to call it and wait for their response.
pkid = (await ctx.bot.db[1].forms.find_one({"identifier": poke.lower()}))[
"pokemon_id"
]
name = poke
threshold = 5000
inventory = details["cast_inv"]
threshold = round(
threshold - threshold * (inventory.get("shiny-multiplier", 0) / 100)
)
shiny = random.choice([False for i in range(threshold)] + [True])
exp_gain = [
t["price"] for t in SHOP if t["item"] == rod.lower().replace(" ", "-")
][0] / 1000
exp_gain += exp_gain * level / 2
base_time = random.randint(3, 7)
if rod.lower() == "good-rod":
rod_bonus = random.randint(1, 1)
final_time = base_time + rod_bonus
await asyncio.sleep(final_time)
elif rod.lower() == "great-rod":
rod_bonus = random.randint(1, 2)
final_time = base_time + rod_bonus
await asyncio.sleep(final_time)
elif rod.lower() == "super-rod":
rod_bonus = random.randint(1, 3)
final_time = base_time + rod_bonus
await asyncio.sleep(final_time)
elif rod.lower() == "ultra-rod":
rod_bonus = random.randint(2, 5)
final_time = base_time + rod_bonus
await asyncio.sleep(final_time)
else:
rod_bonus = random.randint(0, 1)
final_time = base_time + rod_bonus
await asyncio.sleep(final_time)
scattered_name = scatter(name)
e = discord.Embed(title=f"You fished up a... ```{scattered_name}```")
e.set_footer(text=f"You have 10 Seconds to guess the Pokemon's name to catch it!\n")
try:
await embed.edit(embed=e)
except discord.NotFound:
await ctx.send(embed=e)
def check(m):
return (
m.author == ctx.author
and poke.lower() in m.content.lower().replace(" ", "-")
)
try:
await ctx.bot.wait_for("message", check=check, timeout=15)
except asyncio.TimeoutError:
await ctx.send(f"TIME'S UP!\nUnfortunately the {poke} got away...")
return
pokedata = await ctx.bot.commondb.create_poke(
ctx.bot, ctx.author.id, poke, shiny=shiny
)
ivpercent = round((pokedata.iv_sum / 186) * 100, 2)
you can find our fishing cog on our open source repo for the full "idea" of what we did and hopefully it can help. on github /skylarr1227/dittobot-open

Is using a main() function to get rid of global variables best practice?

I just started learning python recently. I was having issues with having global variables that I didn't want. Below is a small portion of my code that shows two variables phrase and picture that are global variables being used in my functions.
# Lets the user input a phrase for the players to guess
def choose_phrase():
phrase = input("Type a phrase: ")
valid_response = False
while not valid_response:
for character in phrase:
valid_response = True
if not character.isalpha() and character != ' ':
valid_response = False
phrase = input("Type a phrase with only letters and spaces: ")
break
return phrase
# This declares the ascii art in list: 'picture'. It will also add the blank letter spaces showing
# the players how many letters and words the phrase is. It also has a mechanism for wrapping the
# output for easier viewing.When wrapping, this code will produce more items in 'picture' to support
# more lines.
def create_initial_picture():
picture = [...]
count = 1
line = 19
for character in phrase:
if (character == ' ') & (count > 25):
additional_lines = ["", "", ""]
picture.extend(additional_lines)
line += 3
count = 1
elif character == ' ':
picture[line] = picture[line] + " "
else:
picture[line] = picture[line] + "___ "
count += 1
return picture
phrase = choose_phrase()
picture = create_initial_picture()
I did not like having the global variables so I tried to emulate the main function from other languages to fix this problem and my code then looked like this:
def main():
phrase = choose_phrase()
picture = create_initial_picture(phrase)
# Lets the user input a phrase for the players to guess
def choose_phrase():
phrase = input("Type a phrase: ")
valid_response = False
while not valid_response:
for character in phrase:
valid_response = True
if not character.isalpha() and character != ' ':
valid_response = False
phrase = input("Type a phrase with only letters and spaces: ")
break
return phrase
# This declares the ascii art in list: 'picture'. It will also add the blank letter spaces showing
# the players how many letters and words the phrase is. It also has a mechanism for wrapping the
# output for easier viewing. When wrapping, this code will produce more items in 'picture' to support
# more lines.
def create_initial_picture(phrase):
picture = [...]
count = 1
line = 19
for character in phrase:
if (character == ' ') & (count > 25):
additional_lines = ["", "", ""]
picture.extend(additional_lines)
line += 3
count = 1
elif character == ' ':
picture[line] = picture[line] + " "
else:
picture[line] = picture[line] + "___ "
count += 1
return picture
main()
This accomplishes getting rid of the global variables, but I am not sure if this is orthodox or considered best practice. I am big about trying to make good habits early on and do not want to continue this method if it will lead me into bigger problems down the line. Any feedback on this would be very helpful. Thanks

How to Access a list of titles(elements) from an array by inputting a single word?

I wrote a program that reads in a file. The name of the file was passed into my program as a command-line parameter. Each line of the file contained 3 fields, separated by a vertical bar, or pipe ("|").
The file contained information about books so each line contains a title(ex. Les Miserables), an author, and a genre which I put into three arrays:
title = []
author = []
genre = []
I am trying to input a word like "Les" and get the specific elements from the arrays and print it like "(Fiction), Les Miserables by Victor Hugo".
This is my code so far:
for word in myArray:
fields = word.split(|)
title.append(fields[0])
author.append(fields[1])
genre.append(fields[2])
entry = raw_input()
if entry == T or t:
titlEntry = raw_input("Please enter title:")
n = len(title)
for i in range(0,n):
if titlEntry == i:
print "(" + genre[i] + ") " + title[i] + " by " + author[i]
Please help
First of all, this is not the way to do it; a dictionary would be better and I would ask you look into other structures as well. Also, think about sanitizing the input you read from the command line. However, to get you going, you are close. Try:
titlEntry = raw_input("Please enter title:")
n = len(title)
for i in range(0,n):
if titlEntry == title[i]:
print "(" + genre[i] + ") " + title[i] + " by " + author[i]

Nested If Expression with user validation - repeating the prompt for user input

Thank you #Idor I am making some progress but I am not 100% there yet. Right now my code looks as following:
def easy_game(easy_text, parts_of_speech1):
replaced = []
easy_text = easy_text.split()
i = 0
for word in easy_text:
replacement = word_in_pos_easy(word, parts_of_speech1)
if replacement != None:
user_input = raw_input("Type in: " + replacement + " ")
word = word.replace(replacement, user_input)
while word != solutions[i]:
print "Sorry, you are wrong"
user_input = raw_input("Type in: " + replacement + " ")
print i
i = i + 1
print i
replaced.append(word)
else:
replaced.append(word)
replaced = " ".join(replaced)
print
#time.sleep(1)
print "Ok, lets see your results. Does it make sense?"
print
#time.sleep(1)
return replaced
print
#time.sleep(1)
print easy_game(easy_text, parts_of_speech1)
You can see I added the while loop. I also added an index and for troubleshooting I added print i to see what the program is doing. It still confuses me a bit or doesn't work as I would expect it. But being a newbie to programming my expectations are probably wrong. Here's what's happening:
When you enter the correct answer the program continues to question 2 and also increases i by 1
This works from beginning to end if you enter everything correctly
When you enter the wrong answer you are prompted to enter it again. Good!
However the user then gets stuck in this very question although i has been increased to the right value.
I don't really understand why the user would be stuck at this point when i has been increased, i.e. we would check at the right position in the list for the correct answer.
This is the full code of the game. I can successfully run it on my Mac but see the above behavior. Any thoughts on this by any chance? thanks in advance!
parts_of_speech1 = ["Word1", "Word2", "Word3", "Word4"]
# The following is the text for the easy text..
easy_text = "Python is a Word1 language that provides constructs intended to enable clear programs on both small and large scale. Python implementation was started in December Word2 by Guido von Rossum. The most simple Word3 in Python is Word4 and normally used at the beginning to tell Python to write 'Hello World' on the screen."
solutions = ["programming", "1989", "function", "print"]
# Checks if a word in parts_of_speech is a substring of the word passed in.
def word_in_pos_easy(word, parts_of_speech1):
for pos in parts_of_speech1:
if pos in word:
return pos
return None
# Plays a full game of mad_libs. A player is prompted to replace words in the easy text,
# which appear in parts_of_speech with their own words.
def easy_game(easy_text, parts_of_speech1):
replaced = []
easy_text = easy_text.split()
i = 0
for word in easy_text:
replacement = word_in_pos_easy(word, parts_of_speech1)
if replacement != None:
user_input = raw_input("Type in: " + replacement + " ")
word = word.replace(replacement, user_input)
while word != solutions[i]:
print "Sorry, you are wrong"
user_input = raw_input("Type in: " + replacement + " ")
print i
i = i + 1
print i
replaced.append(word)
else:
replaced.append(word)
replaced = " ".join(replaced)
print
#time.sleep(1)
print "Ok, lets see your results. Does it make sense?"
print
#time.sleep(1)
return replaced
print
#time.sleep(1)
print easy_game(easy_text, parts_of_speech1)
I am building out a quiz based on raw_input using several different list operations. I also want to validate the user input against a list before moving on to the next question in the quiz.
The function currently looks like this:
def play_game(ml_string, parts_of_speech):
replaced = []
ml_string = ml_string.split()
for word in ml_string:
replacement = word_in_pos(word, parts_of_speech)
if replacement != None:
user_input = raw_input("Type in a: " + replacement + " ")
word = word.replace(replacement, user_input)
if word != solution_list1[0]:
print "Sorry, you are wrong. Try again!"
replaced.append(word)
else:
replaced.append(word)
replaced = " ".join(replaced)
return replaced
In Line 9 I am checking against the List containing the solution words. Whereas the validation itself works the function just continues to the next question but I need it to repeat the question until getting the correct answer. I tried to reposition the different lines but simply can't get my head around it at this point in time. Where or how do I need to place the validation of the user input correctly to prompt the user for the same question again?
It seems to me that what you are looking for is a while loop.
Instead of:
if word != solution_list1[0]:
print "Sorry, you are wrong. Try again!"
Try:
while word != solution_list1[0]:
print "Sorry, you are wrong. Try again!"
user_input = raw_input("Type in a: " + replacement + " ") # ask the user again
word = word.replace(replacement, user_input)
This way the user will have to answer the question again (raw_input) until he gets it right.

How can I modify this code so it doesn't go back to the beginning of the function, but a little bit after the beginning?

I'm working on a school project and I have a problem. I have to write code for apothecary where clients can buy medicine. So, I need to make restrictions, which one doesn't go with others and etc. Here is the code:
def prodajLek():
lekovi = Fajl1.UcitavanjeLekova()
lekoviRed = []
brojacZaForPetlju = 1
n = 0
cena = 0
kolicina = []
korpa = []
rednibrojevilekova = []
ukupnacena = 0
print(" Fabricki naziv Genericki naziv Serijski broj Kolicina Cena \n")
for i in lekovi:
x = i.strip().split("|")
lekoviRed.append(x)
if lekoviRed[n][5] == "False":
print(brojacZaForPetlju,"\t {:10} \t {:10} \t\t\t {:3} \t\t\t {:4} \t\t {:5}".format(x[0],x[1],x[2],x[3],x[4]))
brojacZaForPetlju = brojacZaForPetlju + 1
n = n + 1
print("\n\n\n\n")
rednibrleka = input("Izaberite redni broj leka koji zelite da prodate:\n>>\t")
rednibrleka = int(rednibrleka)
rednibrleka = rednibrleka - 1
rednibrojevilekova.append(rednibrleka)
kolicinaZahteva = input("Koju kolicinu zelite da prodate?\n>>\t")
kolicinaZahteva = int(kolicinaZahteva)
if kolicinaZahteva > int(lekoviRed[rednibrleka][3]):
print("Nema toliko na lageru!\n")
Fajl1.LekarMenu()
kolicina.append(kolicinaZahteva)
cena = int(lekoviRed[rednibrleka][4])
korpa.append(cena)
print("Da li zelite da kupite jos lekova?\n1.Da\n2.Ne\n")
nastavakKupovine = input(">>")
if nastavakKupovine == "1":
prodajLek()
elif nastavakKupovine == "2":
Fajl1.LekarMenu()
So, when I get to the nastavakKupovine input, when I press 1, I need to continue shopping and store my row numbers, my price and quantity in arrays rednibrojlekova = [] , korpa = [] and kolicina = []. But I have a problem, because I dont know how to continue this without reseting these arrays to empty.
The standard idiom for what you want to do is a while True loop. Rather than show how to change your (rather long) function, here's a very simple one which hopefully shows the principle in a straightforward way:
def ask():
answers = []
while True:
response = input("What do you have to say? ")
answers.append(response)
check = input("Type 'q' to quit, anything else to repeat: ")
if check == "q":
break
else:
continue
return answers
For this simple function, the else: continue part isn't necessary, because the loop will continue anyway, but I've included it so you can see how to use it.
Here's an example of the function in action:
>>> ask()
What do you have to say? Something
Type 'q' to quit, anything else to repeat:
What do you have to say? Another thing
Type 'q' to quit, anything else to repeat:
What do you have to say? Ok, done
Type 'q' to quit, anything else to repeat: q
['Something', 'Another thing', 'Ok, done']
>>>
You can find out more about while, break and continue by reading the More Control Flow Tools chapter of the official Python tutorial.

Categories