code
I am trying to remove cards with the same color and number from total cards but I am having trouble making conditions for my for loop
total_Cards=['Ace_of_clubs', '2_of_clubs', '3_of_clubs', '4_of_clubs', '5_of_clubs', '6_of_clubs', '7_of_clubs', '8_of_clubs', '9_of_clubs', '10_of_clubs', 'King_of_clubs', 'Queen_of_clubs', 'Jack_of_clubs', 'Ace_of_diamonds', '2_of_diamonds', '3_of_diamonds', '4_of_diamonds', '5_of_diamonds', '6_of_diamonds', '7_of_diamonds', '8_of_diamonds', '9_of_diamonds', '10_of_diamonds', 'King_of_diamonds', 'Queen_of_diamonds', 'Jack_of_diamonds', 'Ace_of_spades', '2_of_spades', '3_of_spades', '4_of_spades', '5_of_spades', '6_of_spades', '7_of_spades', '8_of_spades', '9_of_spades', '10_of_spades', 'King_of_spades', 'Queen_of_spades', 'Jack_of_spades', 'Jocker', 'Ace_of_hearts', '2_of_hearts', '3_of_hearts', '4_of_hearts', '5_of_hearts', '6_of_hearts', '7_of_hearts', '8_of_hearts', '9_of_hearts', '10_of_hearts', 'King_of_hearts', 'Queen_of_hearts', 'Jack_of_hearts']
for i in range(len(total_Cards)):
first=total_Cards[i].split("_")
for y in range(len(total_Cards)-1):
y+=1
second=total_Cards[y].split("_")
if second[0]==['jocker']:
pass
elif first[0]==["jocker"]:
pass
elif ((first[0]==second[0])and((first[2]==("spades")or(first[2]=="clubs"))and (second[2]==("spades")or(second[2]=="clubs")))):
total_Cards.pop(i)
total_Cards.pop(y)
elif ((first[0]==second[0])and((first[2]==("diamonds")or(first[2]=="hearts"))and (second[2]==("diamonds")or(second[2]=="hearts")))):
total_Cards.pop(i)
total_Cards.pop(y)
Okay, since there are some things about your question that are not very clear, I am going to assume what seems reasonable and answer with that in mind. My assumptions are:
When there is a match of number and color, both cards should be removed;
If there are repeated cards (same color and number), all of their instances should be removed.
So, first, I believe in order to make the comparisons easier to understand and more efficient, we can make a specific function to tell us the color of the card based on its suit. This will make your conditions much cleaner:
def get_suit_color(suit: str) -> str:
if suit.lower() == "clubs" or suit.lower() == "spades":
return "black"
elif suit.lower() == "diamonds" or suit.lower() == "hearts":
return "red"
else:
raise ValueError("Suit is not a supported type (clubs, spades, diamonds, hearts)")
This function simplifies the color comparison, as we can see from an example:
foo = 'Clubs'
bar = 'sPADES'
baz = 'diAmOnDs'
qux = 'HEARTS'
print(get_suit_color(foo))
print(get_suit_color(bar))
print(get_suit_color(baz))
print(get_suit_color(qux))
That will output:
>>> black
>>> black
>>> red
>>> red
So, now, let's get into removing 'color duplicates'. The function, basically, gets the number and suit of a card and compares to the pair of number and suit of each other card. If the numbers match, we check color, if the color then matches, we remove the card from the list we will return. This will work:
def deduplicate(cards_list: list[str]) -> list:
return_list = cards_list.copy()
for card in cards_list:
new_list = cards_list.copy()
try:
number, _, suit = card.split("_")
except ValueError:
# Happens when Joker is found
continue
else:
new_list.remove(card)
for other_card in new_list:
try:
other_number, _, other_suit = other_card.split("_")
# print(f"Comparing {number} of {suit} with {other_number} of {other_suit}")
except ValueError:
# Happens when Joker is found
continue
else:
if not number == other_number:
continue
else:
if get_suit_color(suit) == get_suit_color(other_suit):
try:
return_list.remove(other_card)
except ValueError:
# Happens when there are repeated cards (same number and suit)
continue
# print(f"Updated list:\n{return_list}")
return return_list
Note that the get_suit_color function is used to compare the two cards (card and other_card). I left two commented print statements because I believe they might aid in the understanding of the function, though they pollute the output.
Another important thing is copying the original list, not to change it. The return_list starts off just like cards_list, and at each match of color and number, cards are removed. The new_list is just an object created by removing the current card of the list, in order to avoid comparing it with itself.
With both these functions, you can expect this to go well:
all_cards = ['Ace_of_clubs', '2_of_clubs', '3_of_clubs', '4_of_clubs', '5_of_clubs', '6_of_clubs', '7_of_clubs', '8_of_clubs', '9_of_clubs', '10_of_clubs', 'King_of_clubs', 'Queen_of_clubs', 'Jack_of_clubs', 'Ace_of_diamonds', '2_of_diamonds', '3_of_diamonds', '4_of_diamonds', '5_of_diamonds', '6_of_diamonds', '7_of_diamonds', '8_of_diamonds', '9_of_diamonds', '10_of_diamonds', 'King_of_diamonds', 'Queen_of_diamonds', 'Jack_of_diamonds', 'Ace_of_spades', '2_of_spades', '3_of_spades', '4_of_spades', '5_of_spades', '6_of_spades', '7_of_spades', '8_of_spades', '9_of_spades', '10_of_spades', 'King_of_spades', 'Queen_of_spades', 'Jack_of_spades', 'Joker', 'Ace_of_hearts', '2_of_hearts', '4_of_hearts', '5_of_hearts', '6_of_hearts', '7_of_hearts', '8_of_hearts', '9_of_hearts', '10_of_hearts', 'King_of_hearts', 'Queen_of_hearts', 'Jack_of_hearts']
new_deck = deduplicate(all_cards)
print(new_deck)
The output should be:
>>> ['3_of_diamonds', 'Joker']
Since I removed the 3 of Hearts from all_cards, and there is only one Joker.
Note: if you have older Python, remove the type annotations from the functions. Also, I believe "Joker" is the correct spelling, so I used that.
Okay so I'm very new to the programming world and have written a few really basic programs, hence why my code is a bit messy. So the problem i have been given is a teacher needs help with asigning tasks to her students. She randomly gives the students their numbers. Students then enter their number into the program and then the program tells them if they have drawn the short straw or not. The program must be able to be run depending on how many students are in the class and this is where i am stuck, I can't find a way to run the program depending on how many students are in the class. Here is my code
import random
print("Welcome to the Short Straw Game")
print("This first part is for teachers only")
print("")
numstudents = int(input("How many students are in your class: "))
task = input("What is the task: ")
num1 = random.randint(0, numstudents)
count = numstudents
print("The part is for students") #Trying to get this part to run again depending on number of students in the class
studentname = input("What is your name:")
studentnumber = int(input("What is the number your teacher gave to you: "))
if studentnumber == num1:
print("Sorry", studentname, "but you drew the short straw and you have to", task,)
else:
print("Congratulations", studentname, "You didn't draw the short straw")
count -= 1
print("There is {0} starws left to go, good luck next student".format(count))
Read up on for loops.
Simply put, wrap the rest of your code in one:
# ...
print("The part is for students")
for i in range(numstudents):
studentname = input("What is your name:")
#...
Also, welcome to the world of programming! :) Good luck and have fun!
Here is my code:
def collectData():
print ("Please use correct spelling\n")
print("Choose what game type this is")
getGameType = input(" FFA: 1\n 1v1: 2\n 2v2: 3\n 3v3: 4\n 4v4: 5\n")
if getGameType == "1":
FFAPlayerList = []
getFFAMaxLen = (int)(input("How Many players were in this FFA?: "))
print("Please enter playername as well as placing, seperated by a comma\n(playerName,placing) One player per entry. \n")
while len(FFAPlayerList) < getFFAMaxLen:
getFFAPlayers = input("format: playerName,Placing::: ").split(',')
FFAPlayerList.append(getFFAPlayers)
with open("C:\\Users\\Twinklenugget\\Documents\\NQGroup\\Databases\\NQMasterDatabase.csv", 'r') as ffaDatabaseExtract:
reader = csv.reader(ffaDatabaseExtract)
ffaDatabaseList = list(reader)
FFAPlayerList.append(ffaDatabaseList)
print (FFAPlayerList)
collectData()
Forgive the formatting, it's actually all correct. I am relativly new to python and coding in general. My goal is to be able to take the values stored in FFAPlayerList (the player names) and use those strings to look for the same strings in ffaDatabaseList. After it finds the same strings from ffaDatabaseList I then need to take values from the second column from ffaDatabaseList and append them into FFAPlayerList. How exactly would I go about doing that? Even a pointer in the right direction would be great.
I am attempting to create a program that has 4 functions, getStocks, searchStocks, printStocks, and then the main function that uses the other three.
My issue is that I want to make it so that if the stock you searched for is the highest stock, I want the message "There are no higher stocks" to appear as the output instead of empty space, but I am unsure what and where I would need to add to do that. I have the "noHigherStocks" variable as the message I want displayed, but where am I to implement it? I feel as though I should use an else statement in the main function, but I can't think of where it would make sense to put it. Thanks for reading! any help or tips would be greatly appreciated :-)
def getStocks():
stockNames = []
stockPrices = []
name = str(input("What is the name of the stock?"))
price = int(input("what is the price of that stock?"))
while name != 'done':
stockNames.append(name)
stockPrices.append(price)
name = str(input("What is the name of the stock?"))
if name != 'done':
price = int(input("what is the price of that stock?"))
return (stockNames, stockPrices)
# returns a single value pertaining to the found price
def searchStocks(stockNames, stockPrices, s):
for i in range (len(stockNames)):
if stockNames[i] == s:
return stockPrices[i]
return -1
# print the names of stocks whose price is higher than p.
def printStock(stockNames, stockPrices, p):
i = 0
while i <len(stockPrices):
if p < stockPrices[i]:
print(stockNames[i])
i = i + 1
return
def main():
n,p = getStocks()
stock = str(input("what stock are you searching for?"))
price = searchStocks(n,p,stock)
printStock(n,p,price)
noStocksHigher = str('There are no stocks higher than',stock)
main()
This might be solved using the max() builtin. Since you already know the price of the stock for which you searched, you could just compare that price against the highest price in p, and if equal, print your message, otherwise search the list.
Starting where you call searchStocks:
price = searchStocks(n,p,stock)
if max(p) == price:
print('There are no stocks higher than',stock)
else:
printStock(n,p,price)
This should do the trick.
I am trying to create a function, getStocks, that gets from the user two lists, one containing the list of stock names and the second containing the list of stock prices. This should be done in a loop such that it keeps on getting a stock name and price until the user enters the string 'done' as a stock name. The function should return both lists. My main issues are figuring out what my parameters are, how to continuously take in the name and price, and what type of loop I should be using. I am very new to programming so any help would be appreciated. I believe I'm close but I am unsure where my errors are.
def getStocks(name,price):
stockNames = []
stockPrices = []
i = 0
name = str(input("What is the name of the stock?"))
price = int(input("what is the price of that stock?"))
while i < len(stockNames):
stockNames.append(name)
stockPrices.append(price)
i += 1
else:
if name = done
return stockNames
return stockPrices
Your question is a bit unclear but some things off the bat, you cant have two return lines, once you hit the first, it leaves the function. Instead you'do write something like
return (stockNames, stockPrices)
Secondly while loops dont have an else, so you'd actually set up your while loop, then setup an if statement at the beginning to check if the string is 'done', then act accordingly. Break will get you out of your last while loop, even though it looks like it's associated with the if. So something like this:
while i < len(stockNames):
if name.upper() == 'DONE':
break
else:
stockNames.append(name)
stockPrices.append(price)
i += 1
Also you have to use == (comparison) instead of = (assignment) when you check your name = done. And dont forget done is a string, so it needs to be in quotations, and I used .upper() to make the input all caps to cover if its lower case or uppercase.
If you can clear up your question a little bit, I can update this answer to include everything put together. I'm not quite understanding why you want to input a list and then also take user input, unless you're appending to that list, at which point you'd want to put the whole thing in a while loop maybe.
Update:
Based on your comment, you could do something like this and enclose the whole thing in a while loop. This takes the incoming two lists (assuming you made a master list somewhere) and sends them both into the getStocks function, where someone can keep appending to the pre-existing list, and then when they type done or DONE or DoNe (doesn't matter since you use .upper() to make the input capitalized) you break out of your while loop and return the updated lists:
def getStocks(name, price):
stockNames = name
stockPrices = price
while 1:
inputName = str(input("What is the name of the stock?"))
inputPrice = int(input("what is the price of that stock?"))
if name.upper() != 'DONE':
stockNames.append(inputName)
stockPrices.append(inputPrice)
else:
break
return (stockNames, stockPrices)
But really, depending on the rest of the structure, you might want to make a dictionary instead of having 2 separate lists, that way everything stays in key:value pairs, so instead of having to check index 0 on both and hoping they didn't get shifted by some rogue function, you'd have the key:value pair of "stock_x":48 always together.