I have created a class function called trick_winner(self) within the class Cards which take the value within self.trick1 for example self.trick1 = ('AH' 'JH' 'KH' '2H') and returns the pairs in order from great to least, being that 'A' is the highest value followed by '7', 'J', 'K', 'Q', '6', '5', '4', '3', '2'. But when I use the built in sort function sorted is returns the value in but they are not pairs, they are treating each value as its own seperate value.
I have tried to used the built in sort function, but it does not come out the way I want it to show. I am expecting if I type in a = Cards('AH' '4H' 'KH' '2H') and when I run the class function is it will return the pairs in order from greatest to least 'A' 'KH' '4H' '2H'.
I have created the function
class Cards:
def __init__(self, trick)
self.trick1 = trick
def trick_winner(self):
R = {'2': 0, '3': 0, '4': 0, '5': 0, '6': 0,
'J': 4, 'Q': 3, 'K': 5, '7': 10, 'A': 11}
self.trick1 = self.trick1.upper()
a = sorted(self.trick1)
print(a)
and running the funcntion:
c = cards('7H' ' JH' ' KH' ' 2H')
c.trick_winner()
the outcome was:
[' ', ' ', ' ', '2', '7', 'H', 'H', 'H', 'H', 'J', 'K']
You should create a class for a single card and implement the order. Look here:
R = {"2": 0, "3": 0, "4": 0, "5": 0, "6": 0, "J": 4, "Q": 3, "K": 5, "7": 10, "A": 11}
class Card:
def __init__(self, color, value):
self.color = color
self.value = value
def __lt__(self, other):
return R[self.value] < R[other.value]
# Only for printing purposes, you shouldn't use that in production
def __repr__(self):
return str(self.value)
c1 = Card("H", "A")
c2 = Card("H", "K")
c3 = Card("H", "7")
c4 = Card("H", "4")
print(sorted([c1, c2, c3, c4], reverse=True))
For a bit more structured answer, I created card and cards class which makes sense.
#Define R at the beginning of the script so it would be globally accesible
R = {'2': 0, '3': 0, '4': 0, '5': 0, '6': 0,
'J': 4, 'Q': 3, 'K': 5, '7': 10, 'A': 11}
class Card:
def __init__(self,card):
self.card = card
#this function used when checking greater than symbol
#so that sorted method will work properly
def __gt__(self,other):
if(isinstance(other,Card)):
return R[other.card] > R[self.card]
#these two are for printing results.
def __str__(self):
return self.card
def __repr__(self):
return str(self.card)
class Cards:
#you can add many card into cards class
def __init__(self, *cards):
self.cards = cards
def trick_winner(self):
a = sorted(self.cards)
print(a)
Here create many card and send them into cards class. Now you can easily manipulate or use them with Cards class
c = Cards(Card('A'),Card('4'),Card('K'),Card('2'))
c.trick_winner()
Related
problem: create a recursive function that given an input key, would return the amount of basic components to build the given input key.
EX 1) input = "Engine"
output = Engine ==> metal: 3, rubber: 2
EX 2) input = "metal"
output = metal ==> metal: 1
EX 3) input = "piston"
output = piston ==> metal: 1, rubber: 1
car= {
"Engine" : ["pistons", "timing belt", "metal" ,"metal"],
"Pistons" : ["Metal", "rubber"],
"timing belt" : ["rubber"],
"metal" : [],
"rubber" : []
}
my code has different variable names and key name, but it's the same idea
parts = {
'A': ['B', 'B', 'C'],
'B': [],
'C': ['D','E','F'],
'D': [],
'E': ['B','D'],
'F': []
}
#above here its user input
counter_dictio = {
'A': [],
'B': [],
'C': [],
'D': [],
'E': [],
'F': []
}
def desamble(key, dictionary):
#check if array is empty
#ccounter +=1
if (len(dictionary[key])) == 0:
counter_dictio[key].append(key)
#if array is populated
#enter to this array
#desample(i, dictionary)
else:
for i in dictionary[key]:
desamble(i, dictionary)
key = "A"
desamble(key, parts)
One way to go is:
from collections import Counter
car= {
"engine": ["pistons", "timing belt", "metal", "metal"],
"pistons": ["metal", "rubber"],
"timing belt": ["rubber"],
"metal": [],
"rubber": []
}
def ingredients(key, dct):
if dct[key] == []:
yield key
else:
for sub_part in dct[key]:
yield from ingredients(sub_part, dct)
print(*ingredients('engine', car)) # metal rubber rubber metal metal
print(Counter(ingredients('engine', car))) # Counter({'metal': 3, 'rubber': 2})
ingredients makes a generator of ingredients, so you can use Counter to count them.
Here is code that will group by your components
from collections import defaultdict
parts = {
'A': ['B', 'B', 'C'],
'B': [],
'C': ['D', 'E', 'F'],
'D': [],
'E': ['B', 'D'],
'F': []
}
result = defaultdict(dict)
for k, v in parts.items():
row = result[k] # used to create empty dict on initial empty list
for item in v:
if row.get(item) is None:
row[item] = 1
else:
row[item] += 1
This will result in following dict
{'A': {'B': 2, 'C': 1}, 'B': {}, 'C': {'D': 1, 'E': 1, 'F': 1}, 'D': {}, 'E': {'B': 1, 'D': 1}, 'F': {}}
another solution without using recursively, and for a predetermined list would be:
#==== user input====
key = "E"
parts = {
'A': ['B', 'B', 'C'],
'B': [],
'C': ['D','E','F'],
'D': [],
'E': ['B','D'],
'F': []
}
#====end user input=====
#Function for the predetermined dictionary
def desamble(key, dictionary):
if key == "B" or key == "D" or key == "F":
print(key + "==> " + key + ": 1")
elif key == "E":
print(key + "==> " + "B: 1, D: 1" )
elif key == "C":
print(key + "==> " + "B: 1, D: 2, F: 1" )
elif key == "A":
print(key + "==> " + "B: 3, D: 2, F: 1" )
else:
print("Key " + key + " is not defined in dictionary")
#====end====
desamble(key, parts)
Another recursive way to solve this problem, adding a solution for the problem of circularity, meaning that in case that the parts call to eachother.
EX)
dictionary = {
"A": "B",
"B": "A"
}
from typing iport Counter
def func(key, dictionary, current=None):
if not current:
current = set() # could also be a list
if key in current:
raise ValueError # or whichever
if not dictionary.get(key):
return [key]
ret = []
for subkey in dictionary[key]:
ret.extend(func(subkey, dictionary, current.union({key})))
return ret
Print(Counter(func("A"), parts))
#by officerthegeeks
This year, our school is holding a tug of war competition between classes, me and my classmates are eager to join, but we're not sure who to join the race, so I decided to code a program about it.
Here is my attempt with recursion, but it can only handle integer inputs, but the weight that my teacher gave us are float numbers. Is there any way to find the biggest weight combination but no more than the weight class (target)? Also, there is a participant limit, the number participants should be exactly the same as participants_needed.
def allPossibleCombinations(target: int, using: dict[str: int], stack = None):
# initialize
if stack is None:
stack = []
using = dict(sorted(using.items(), key = lambda x: x[1])) # sort the dict using the values
this_layer = []
previous_layer = []
if (using != {}) and (target - min(using.values()) >= 0):
index = 0
for name, number in using.items():
if target - number == 0:
this_layer.append(stack + [name])
elif target - number < 0:
break
else:
previous_layer.extend(allPossibleCombinations(target - number, dict(list(using.items())[index + 1:]), stack + [name]))
index += 1
return previous_layer + this_layer
def findCloset(target: int, participants_needed: int, participants: dict[str: int]): # if the target is impossible to form, try target - 1, target - 2 ...
for i in range(target, min(participants.values()), -1):
temp = allPossibleCombinations(i, participants)
if temp != []:
result = []
for item in temp:
if len(item) == participants_needed:
result.append(item)
if result != []:
print(f"{i}:", *result)
break
else:
print("Impossible")
For example, ("A", "B", "C"... are placeholder names)
findCloset(460, 8, {"A": 53, "B": 71, "C": 42, "D": 58, "E": 49, "F": 75, "G": 56, "H": 46, "I": 49, "J": 51}) -> 459: ['H', 'E', 'J', 'A', 'G', 'D', 'B', 'F'], ['H', 'I', 'J', 'A', 'G', 'D', 'B', 'F']
The thing that I want: (Handle floats)
findCloset(460, 8, {"A": 53.4, "B": 71.0, "C": 42.3, "D": 57.6, "E": 48.9, "F": 75.1, "G": 56.2, "H": 46.1, "I": 48.7, "J": 51.3}) -> ???
Here's an example using combinations that works with float also:
from itertools import combinations
def find_closest(target, participants_needed, participants):
players = [x for x in participants.keys()]
player_combinations = combinations(players, participants_needed)
allowed_combinations = []
for comb in player_combinations:
total_weight = sum(participants[x] for x in comb)
if total_weight <= target:
allowed_combinations.append([total_weight, comb])
return sorted(allowed_combinations, key=lambda x: x[0], reverse=True)
When:
result = find_closest(t, pn, p)
You can get, for example, top 3:
for i in result[:3]:
print(f"Weight: {i[0]}; Players: {i[1]}")
Or just the highest:
print(f"Weight: {result[0][0]}; Players: {result[0][1]}")
Result for your example:
Weight: 459.6; Players: ('A', 'B', 'D', 'E', 'F', 'G', 'H', 'J')
The range function does not accept floats as arguments. You can cast the float value to the closest smaller/bigger integer using math.floor()/math.ceil() respectively. You have to import the math module using import math at the top of the file then change the first line in findClosest to:
for i in range(target, math.floor(min(participants.values())), -1):
I have this dict
cards = {
'A': 1,
'2': 2,
'3': 3,
'4': 4,
'5': 5,
'6': 6,
'7': 7,
'8': 8,
'9': 9,
'10': 10,
'J': 10,
'Q': 10,
'K': 10
}
And this class
class Dealer:
def __init__(self, hand1, hand2):
self.hand1 = hand1
self.hand2 = hand2
And I want to pass a random key-value pair to the constructor.
I have no idea how...
I tried this
dealer = Dealer(cards, cards) but it will pass the whole dict.
I also tried this
dealer = Dealer(cards[random.choice(list(cards.keys()))], cards[random.choice(list(cards.keys()))])
and could get a random Value but I want a key-value pair or at least just pass they key?
You are on the right track. Get a key from your dictionary and then use it to look up it's corresponding value. Like this:
import random
adict = {"1":"4","2":"5"}
k = random.choice(list(adict.keys()))
pair = (k, adict[k])
print(pair)
# output: ('1','4')
Previously I asked a question as to how to separate characters in a string according to capital letters, or spaces. It was immediately answered. Working on the same piece of code and now I was wondering if it is possible to read an input and ignore integers, and later use it.
For example if the string is H2O, times the value of H twice and then add the value of O.
How to read two characters from an input string?
^^That's the link to my previous question I asked on same code, if useful.
import re
atomMass_Table = {'H': 1.00797, 'He': 4.00260, 'B': 10.81,'C': 12.011, 'N': 14.067, 'O': 15.9994,'F':
18.998403,'P': 30.97376, 'S': 32.06, 'K':39.0983, ' ': 0, None: 0}
TotalMass=0
elements=[ ]
mol=input("Enter a molecule:")
elements = re.findall('[A-Z][^A-Z]*', mol)
for a in elements:
if a == int:
element=None
atomicMass=atomMass_Table.get(a)
TotalMass=TotalMass+atomicMass
print (TotalMass)
Hope I'm not being too confusing :)
There are two solutions for you. I don't understand the solution of Thomas, but alec's solution is acceptable. However, it can't work if you have something like "C12H22O11". I give a solution which can fix it, take a look.
atomMass_Table = {'H': 1.00797, 'He': 4.00260, 'B': 10.81,'C': 12.011, 'N': 14.067,
'O': 15.9994,'F': 18.998403,'P': 30.97376, 'S': 32.06, 'K':39.0983, ' ': 0, None: 0, 'd': 0}
TotalMass=0
elements=[ ]
mol=input("Enter a molecule:")
if not mol[-1].isdigit():
mol += '1'
mol += 'd'
number = []
for a in mol:
if a.isdigit():
number.append(a)
else:
if not number:
value = atomMass_Table.get(a)
else:
TotalMass += value * int(''.join(number))
value = atomMass_Table.get(a)
number = []
print (TotalMass)
The solution for H2O is 18.01534 and C12H22O11 is 342.30074.
Hope this help!
What about this?
import re
atom_masses = {'H': 1.00797, 'He': 4.00260, 'B': 10.81, 'C': 12.011, 'N': 14.067, 'O': 15.9994, 'F':
18.998403, 'P': 30.97376, 'S': 32.06, 'K': 39.0983, ' ': 0, None: 0}
total_mass = 0
elements = []
mol = input("Enter a molecule:")
parts = re.findall('([A-Z][a-z]?)(\d)*', mol)
print(parts)
for element, count in parts:
if count == '':
count = 0
atomic_mass = atom_masses.get(element)
total_mass = total_mass + atomic_mass * float(count)
print (total_mass)
I changed the regex to divide the string into separate atoms and their count. It has to be a capital letter followed by an optional small letter and an optional number.
Additionally, i changed the variable name because they should be in small letter.
Use isalpha() to check if the element only contains letters. If not, you can use string slicing to get the value of the first character from the dictionary, and multiply by the second character.
atomMass_Table = {'H': 1.00797, 'He': 4.00260, 'B': 10.81,'C': 12.011, 'N': 14.067, 'O': 15.9994,'F':
18.998403,'P': 30.97376, 'S': 32.06, 'K':39.0983, ' ': 0, None: 0}
TotalMass = 0
mol = input("Enter a molecule: ")
elements = re.findall('[A-Z][^A-Z]*', mol)
for a in elements:
if a.isalpha():
TotalMass += atomMass_Table.get(a)
else:
TotalMass += atomMass_Table.get(a[0]) * int(a[1])
print(TotalMass)
Example:
Enter a molecule: H2O
18.01534
>>>
I extended a bit your Request and added a Class for each molecule.
A Class contains of three attributes:
raw_element
molecule structure
molecule mass
the class could be extended with a drawing of the molecule or other features.
The Class:
class molecule:
def __init__(self, raw_element, atom_mass_table):
self.amt = atom_mass_table
self.raw_element = raw_element
self.molecule_structur = self.get_struc()
self.molecule_mass = self.cal_mass()
def get_struc(self):
return [self._split_nodes(e) for e in self._split_in_nodes()]
def cal_mass(self):
sum = 0
for i in self.molecule_structur:
sum += self.amt[i[0]] * i[1]
return sum
def _split_nodes(self, node):
s = ""
n = ""
for l in node:
if l.isalpha():
s += l
elif l.isdigit():
n += l
if n is None:
n = 1
return (s, int(n))
def _split_in_nodes(self):
new_el = [e.isupper() for e in self.raw_element]
el_str = []
pos = 0
for _ in range(sum(new_el)):
if True in new_el[pos+1:]:
end = pos + new_el[pos+1:].index(True)+1
else:
end = len(new_el)
el_str.append(self.raw_element[pos:end])
pos = end
return el_str
The Class only needs:
raw element description - C12H22O11
your provided atom_mass_table - I didn't include it in the class, for easier expansion later on.
So to test the code:
if __name__ == "__main__":
element = input("Please enter your Molecule: ")
molecule = Molecule(element, atom_mass_table)
print(molecule.molecule_structur)
print(molecule.molecule_mass)
Input:
Please enter you Molecule: C32H128O64
Output:
[('C', 32), ('H', 128), ('O', 64)]
1537.33376
Hope it helps and when you further improve this Application, you can invite me to you GitHub Project.
I'm working with fuzzy sets. I was wondering if there are any libraries available for Python? Namely, I'm having trouble adding 2 fuzzy sets and also squaring them. I am storing the fuzzy set in a Python dictionary, the key being the member element and the value is the membership value.
My sets are:
set_A = {'3':0.1, '4': 0.8, '5': 0.5}
set_B = {'6':0.6, '7': 0.2, '8': 0.7}
I want to find out set_A + set_B
and also set_A^2 + set_B^2
I don't know for certain if there's not already a library for this, but here's quick and simple class that I think does what you expect:
class Fuzzy_Set:
def __init__(self, set):
self.set = set
def __add__(self, other):
retset = {}
for item in set(self.set.keys()).union(set(other.set.keys())):
retset[item] = self.set.get(item, 0) + other.set.get(item, 0)
return retset
def __pow__(self, power, modulo=None):
if modulo:
return {k:v**power%modulo for k, v in self.set.items()}
else:
return {k:v**power for k, v in self.set.items()}
def __mod__(self, other):
return pow(Fuzzy_Set(self.set), 1, other)
if __name__ == '__main__':
s1 = Fuzzy_Set({'3':0.1, '4': 0.8, '5': 0.5})
s2 = Fuzzy_Set({'5': .5, '6':0.6, '7': 0.2, '8': 0.7})
print(s1 + s2)
print(s1**2)
print(Fuzzy_Set({'1': 1, '2': 2, '3': 3})%2)
This implements adding and exponentiation and modulo. The output of main is:
{'3': 0.1, '6': 0.6, '5': 1.0, '7': 0.2, '8': 0.7, '4': 0.8}
{'3': 0.010000000000000002, '4': 0.6400000000000001, '5': 0.25}
{'1': 1, '2': 0, '3': 1}