Fuzzy set addition and squaring - python

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}

Related

Trick_winner Funciton

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()

Why does my Morse Code decoding tool not find any subsequent characters?

I am working on a Morse Code encoding/ decoding tool. I have completed the encoder, and I'm working on the decoder. Currently the decoding function "MorseCodeDecoder(MSG)" can decode a single letter at a time. It does this by checking every character in a string one by one and copying them to the variable, "EncodedLetter". The program checks each character to see if it is a space, if it is the program identifies this a gap between letter, for example:
MSG = ".... .." -*the function runs*- EncodedLetter = "....".
Then that value is back searched through a dictionary(using lists) to find what EncodedLetter's key whould be, in this case it's "H", the program also checks for double spaces which represent the space between two words. At this point in time it may sound fully functional; however after finding one encoded letter it can't find another, so earlier ".... .." it can't find ".." even though I reset the variable after it successfully decodes a letter.
MorseCodeDictionary = {' ': ' ', 'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', 'Z': '--..', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----'}
def MorseCodeEncoder(MSG):
EncodedMSG = f"""Encoded Message:
"""
MSG = MSG.upper()
for i in range(0, len(MSG), 1):
Encode = (MSG[i])
EncodedMSG = f"{EncodedMSG} {(MorseCodeDictionary.get(Encode))}"
return EncodedMSG
def MorseCodeDecoder(MSG):
DecodedMSG = f"""Decoded Message:
"""
MSG = MSG.upper()
DecodedWord = ''
DecodedLetter = ''
EncodedLetter = ''
for i in range(0, len(MSG)):
DecodedLetter = ''
Decode = (MSG[i])
try:
if (MSG[i + 1]) == ' ':
EncodedLetter = f"{EncodedLetter + (MSG[i])}"
DecodedLetter = list(MorseCodeDictionary.keys())[list(MorseCodeDictionary.values()).index(EncodedLetter)]
DecodedWord = DecodedWord + DecodedLetter
EncodedLetter = ''
DecodedMSG = f"{DecodedMSG} {DecodedWord}"
elif (MSG[i + 1]) + (MSG[i + 2]) == ' ':
DecodedWord = ''
else:
EncodedLetter = f"{EncodedLetter + (MSG[i])}"
except (ValueError,IndexError):
pass
return DecodedMSG
Loop = 1
while Loop == 1:
Choice = str(input("""[1] Encode, or [2] decode?
"""))
if Choice == '1':
MSG = str(input("""Type the message you would like to encode. Do not use puncuation.
"""))
EncodedMSG = (MorseCodeEncoder(MSG))
print (EncodedMSG)
elif Choice == '2':
MSG = str(input("""Type what you wish to decode.
"""))
DecodedMSG = (MorseCodeDecoder(MSG))
print (DecodedMSG)
else:
print ('1, or 2')
Instead of blundering about with appending to strings and picking out each character from your encoded string to form a morse-code letter, you can just use str.join() and str.split()! Also, I suggest separating your encoded morse code letters by a character that cannot be a part of a correctly encoded string, such as /. This way, you are sure that all spaces in the string are a space and all slashes in the string are letter separators. First, let's define the dictionaries for both encoding and decoding
en_to_morse = {' ': ' ', 'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', 'Z': '--..', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----'}
morse_to_en = {v: k for k, v in en_to_morse.items()} # Reverse lookup for encoder
The morse_to_en dictionary can be created simply by reversing the keys and values in the en_to_morse dictionary. These two could be combined, since they do not have any common keys (except space, which doesn't really matter because it remains the same), but I'm going to keep them separate for this example.
Then, you can write the encoder function like so:
def MorseEncode(msg):
morse_msg = [] # make an empty list to contain all our morse symbols
for char in msg.upper(): # Convert msg to uppercase. Then iterate over each character
morse_char = en_to_morse[char] # Get the translation from the dictionary
morse_msg.append(morse_char) # Append the translation to the list
return '/'.join(morse_msg) # Join symbols with a '/'
The decoder function is just the reverse of the encoder function.
def MorseDecode(msg):
morse_chars = msg.split("/") # Split at '/'
en_msg = "" # Empty message string
for char in morse_chars: # Iterate over each symbol in the split list
en_char = morse_to_en[char] # Translate to English
en_msg += en_char # Append character to decoded message
return en_msg
To run this:
encoded = MorseEncode("Hello World") # gives '...././.-../.-../---/ /.--/---/.-./.-../-..'
decoded = MorseDecode(encoded) # gives 'HELLO WORLD'
You lose case-information because Morse code doesn't separate symbols for have upper/lower case characters.
You could write your functions as one-liners too:
def MorseEncode(msg):
return '/'.join(en_to_morse[char] for char in msg.upper())
def MorseDecode(msg):
return ''.join(morse_to_en[char] for char in msg.split('/'))

How to pass a random key-value-pair to a function/constructor in Python?

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')

invalid literal for int() with base 10: '' error with only numbers

I know what the error is, but why would it display this error if there are no other characters? I know this question has been asked but I can't find a reason for it.
error line code:
Traceback (most recent call last):
File "C:/Users/tudor/Documents/python/custom cypher/cypher.py", line 179, in
<module>
array0, array1, array2 = (int(crypt_array0) // array0_key),
(int(crypt_array1) // array1_key), (int(crypt_array2) // array2_key)
ValueError: invalid literal for int() with base 10: ''
full code:
import random
import itertools
print ('''
READ THIS BEFORE USE
This encryption can ONLY use ASCII
this contains most/all of the
keys on your keyboard, this
includes capital letters
The key supports around 100000 digits.
The hard encoding adds three more
layers of security. You will have to
copy your new key.
''')
hard_encoding_1 = {
'0': '8',
'1': '4',
'2': '3',
'3': '7',
'4': '1',
'5': '9',
'6': '5',
'7': '6',
'8': '2',
'9': '0',
}
hard_encoding_2 = {
'0': '5',
'1': '9',
'2': '0',
'3': '1',
'4': '4',
'5': '3',
'6': '7',
'7': '2',
'8': '6',
'9': '8',
}
hard_encoding_3 = {
'0': '2',
'1': '5',
'2': '7',
'3': '4',
'4': '9',
'5': '8',
'6': '1',
'7': '0',
'8': '3',
'9': '6',
}
hard_encoding_4 = {
'0': '1',
'1': '3',
'2': '5',
'3': '8',
'4': '0',
'5': '7',
'6': '6',
'7': '2',
'8': '9',
'9': '4',
}
def randint_generator(n):
key_generate = ''
for b in range(n):
b = random.randint(0, 9)
key_generate = key_generate + str(b)
return 'copy this key: ' + key_generate
def setnumber(x, y, str_or_int):
n = len(str(x))
z = str(x)
while n != y:
z = '0' + z
n = len(z)
if str_or_int == str:
return str(z)
if str_or_int == int:
return int(z)
while True:
What_operation = int(input('''
Do you want to:
soft:
decrypt(0)
encrypt(1)
hard:
decrypt(3)
encrypt(4)
generate a key:
100-digit(5)
500-digit(6)
1,000-digit(7)
10,000-digit(8)
1,000,000-digit(9)
'''))
if What_operation == 1:
text = input('What is your text you want to convert? ')
New_text = bin(int.from_bytes(text.encode(), 'big'))
key = int(input('What is your key you want to use?'))
cyphered_text = int(New_text[2:]) * key
print ('copy this text: ', cyphered_text)
if What_operation == 0:
numbers = input('What is your string you want to convert? ')
key = int(input('What is your key? '))
New_text = '0b' + str(int(numbers) // key)
encoded = int(New_text,2)
decoded = encoded.to_bytes((encoded.bit_length() + 7) // 8,
'big').decode()
print ('Here is your message: ' + decoded)
if What_operation == 4:
text = input('What is your text you want to convert? ')
New_text = bin(int.from_bytes(text.encode(), 'big'))
key = int(input('What is your key you want to use?'))
key_2 = random.randint(1,4)
cyphered_text = New_text[2:]
hard_cyphered_text = ''
cyphered_text = int(cyphered_text) * key
for i in str(cyphered_text):
if key_2 == 1:
hard_cyphered_text = hard_cyphered_text + hard_encoding_1[i]
if key_2 == 2:
hard_cyphered_text = hard_cyphered_text + hard_encoding_2[i]
if key_2 == 3:
hard_cyphered_text = hard_cyphered_text + hard_encoding_3[i]
if key_2 == 4:
hard_cyphered_text = hard_cyphered_text + hard_encoding_4[i]
x_cyphered_text = str(hard_cyphered_text)
array0 = ''
array1 = ''
array2 = ''
count = 0
for i in x_cyphered_text:
if count % 3 == 0:
array0 += i
count += 1
count = 0
for i in x_cyphered_text:
if count % 3 == 1:
array1 += i
count += 1
count = 0
for i in x_cyphered_text:
if count % 3 == 2:
array2 += i
count += 1
array0_key, array1_key, array2_key = random.randint(1, 99999999),
random.randint(1, 99999999), random.randint(1, 99999999)
final_array0, final_array1, final_array2 = int(array0) * array0_key,
int(array1) * array1_key, int(array2) * array2_key
len_array0, len_array1, len_array2 = str(len(str(final_array0))),
str(len(str(final_array1))), str(len(str(final_array2)))
full_key = str(key) + str(key_2) + setnumber(len_array0, 6, str) +
setnumber(len_array1, 6, str) + setnumber(len_array2, 6, str) +
setnumber(array0_key, 8, str) + setnumber(array1_key, 8, str) +
setnumber(array2_key, 8, str)
complete_cyphered_text = str(final_array0) + str(final_array1) +
str(final_array2)
print('copy this text: ', complete_cyphered_text)
print('Copy your key: ', full_key)
if What_operation == 3:
numbers = input('What is your string you want to convert? ')
key = input('What is your given key? ')
key_2 = int(key[-43:-42])
array2_key, array1_key, array0_key = int(key[-8:]), int(key[-16:-8]),
int(key[-24:-16])
len_array2, len_array1, len_array0 = int(key[-30:-24]),
int(key[-36:-30]), int(key[-42:-36])
n0, n1, n2 = len_array0, len_array1, len_array2
crypt_array0, crypt_array1, crypt_array2 = numbers[:n0], numbers[n0:n1],
numbers[n0 + n1:]
array0, array1, array2 = (int(crypt_array0) // array0_key),
(int(crypt_array1) // array1_key), (int(crypt_array2) // array2_key) ###
numbers_noncrypt = ''.join(''.join(x) for x in
itertools.zip_longest(str(array0), str(array1), str(array2),
fillvalue=''))
key = int(str(key)[:-43])
encoded_text = ''
decoding = {}
if key_2 == 1:
decoding = {a: b for b, a in hard_encoding_1.items()}
if key_2 == 2:
decoding = {a: b for b, a in hard_encoding_2.items()}
if key_2 == 3:
decoding = {a: b for b, a in hard_encoding_3.items()}
if key_2 == 4:
decoding = {a: b for b, a in hard_encoding_4.items()}
for i in str(numbers_noncrypt):
encoded_text = encoded_text + decoding[i]
encoded_text = '0b' + str(int(encoded_text) // key)
encoded = int(encoded_text, 2)
decoded = encoded.to_bytes((encoded.bit_length() + 7) // 8,
'big').decode()
print ('Here is your message: ' + decoded)
if What_operation == 5:
print(randint_generator(100))
if What_operation == 6:
print(randint_generator(500))
if What_operation == 7:
print(randint_generator(1000))
if What_operation == 8:
print(randint_generator(10000))
if What_operation == 9:
print(randint_generator(1000000))
By the way, the // is not a comment, it is division in python to output in integers and not float, also the code looks crowded as there is a limit on how long the lines have to be on this website. I will put ### to the error line refers to.
I tried debugging it and approaching it in a different way but I can't find a reason why it would do this.
Just to get your debugging going, you're trying to convert an empty string into an integer. To see where this is going wrong, you might want to split up:
array0, array1, array2 = (int(crypt_array0) // array0_key),
(int(crypt_array1) // array1_key), (int(crypt_array2) // array2_key) ###
to:
array0 = (int(crypt_array0) // array0_key)
array1 = (int(crypt_array1) // array1_key)
array2 = (int(crypt_array2) // array2_key)
This way it's easier to follow what exactly is going wrong. Also, please only post the appropriate code in the future.

Modifying nested dictionaries

Given this two dicts:
empty = {'151': {'1': 'empty', '0': 'empty', '2': '2.30'}}
full = {'151': {'1': 3.4, '0': 3.6, '2': 2}}
Firstly, I want to check if empty.keys() == full.keys() if it holds, I want to replace the empty values with corresponding value from full dictionary. It ought to result in:
not_empty = {'151': {'1': '3.4', '0': '3.6', '2': '2.30'}}
My solution so far: I thought I would identify all the keys with empty values using regex, but for whatever reason my code so far, produces an empty dict {}.
import re
find_empty = re.findall("'(\d)':\s'empty'", str(empty))[0]
if empty.keys() == full.keys():
k = empty.values()[0].keys()
v = empty.values()[0].values()
print {k:v for k,v in empty.values()[0].iteritems()\
if empty.values()[0][find_empty] != 'empty'}
I hoped it can output {'151': {'2': '2.30'}} for a good starting point. Anyway, I guess there exists more clean solution then regex for this task so any hints are welcomed!
Regex is not the right tool for this job. I would suggest a recursive approach like the following.
empty = {'151': {'1': 'empty', '0': 'empty', '2': '2.30'}}
full = {'151': {'1': 3.4, '0': 3.6, '2': 2}}
def repl(a, b):
clean = {}
for k, v in a.items():
# This is the case where we want to replace what we have in b if we have something. Just in case, use the dict.get method and provide a default.
if v == 'empty':
clean[k] = b.get(k, 'Not there')
# If the value is another dict, then call this function with the value, and put the return as the value for our current key
elif isinstance(v, dict):
v_clean = repl(v, b.get(k, {}))
clean[k] = v_clean
# The value isn't equal to 'empty', and it isn't another dict, so just keep the current value.
else:
clean[k] = v
# Finally, return the cleaned up dictionary.
return clean
print repl(empty, full)
OUTPUT
{'151': {'1': 3.4, '0': 3.6, '2': '2.30'}}
EDIT I am not sure if this takes care of all of your cases, but it probably worth a look anyway.
empty = {'151': {'1': 'empty', '0': 'empty', '2': '2.30', '8': ['empty', 'empty', 5, {"foo2": "bar2", "1": "empty"}]}}
full = {'151': {'1': 3.4, '0': 3.6, '2': 2, '8': ['foo', 'bar', 'baz', {"foo3": "bar3", "1": "2"}]}}
def repl(a, b):
if isinstance(a, dict) and isinstance(b, dict):
clean = {}
for k, v in a.items():
# This is the case where we want to replace what we have in b if we have something. Just in case, use the dict.get method and provide a default.
if v == 'empty':
clean[k] = b.get(k, 'Not there')
# If the value is another dict, then call this function with the value, and put the return as the value for our current key
elif isinstance(v, dict):
v_clean = repl(v, b.get(k, {}))
clean[k] = v_clean
# The value isn't equal to 'empty', and it isn't another dict, so just keep the current value.
elif isinstance(v, list):
v_clean = repl(v, b.get(k, []))
clean[k] = v_clean
else:
clean[k] = v
# Finally, return the cleaned up dictionary.
elif isinstance(a, list) and isinstance(b, list):
clean = []
for item_a, item_b in zip(a, b):
if item_a == 'empty':
clean.append(item_b)
elif isinstance(item_a, dict):
clean_a = repl(item_a, item_b)
clean.append(clean_a)
else:
clean.append(item_a)
return clean
print repl(empty, full)
OUTPUT
{'151': {'1': 3.4, '0': 3.6, '2': '2.30', '8': ['foo', 'bar', 5, {'1': '2', 'foo2': 'bar2'}]}}

Categories

Resources