Gremlins

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
Post Reply
iceelon
Posts: 30
Joined: Tue Jul 12, 2022 11:42 am

Gremlins

Post by iceelon » Thu Jul 14, 2022 12:10 pm

hi !!!

I try to make a gist code work to later adapt it but I run into the problem of

Code: Select all

TypeError: 'dict_view' object isn't subscriptable
this code example is ...

Code: Select all

from  rr1 import *


income = Antecedent(frange(0, 3, 1))
debt = Antecedent(frange(0, 100, 1))
qualification = Consequent(frange(0, 100, 1))

	# Defining membership functions 
income_mf = {
	'poor': [0, 0, 0.3, 1.0],
	'average': [0.25, 0.5, 1.5, 1.5],
	'good': [1.3, 1.6, 2, 2]
}
income.set_mf(income_mf)

debt_mf = {
	'low': [0, 0, 10, 30],
	'average': [0, 30, 50, 80],
	'high': [50, 75, 100, 100]
}
debt.set_mf(debt_mf)

qualification_mf = {
	'not_decent': [0, 0, 20, 50],
	'decent': [0, 40, 60, 80],
	'very_decent': [50, 80, 100, 100]
}
qualification.set_mf(qualification_mf)

	# Defining rules for inference engine
expert_rules = {
	('poor', 'low'): 'very_decent',
	('average', 'low'): 'decent',
	('good', 'low'): 'not_decent',
	('poor', 'average'): 'very_decent',
	('average', 'average'): 'decent',
	('good', 'average'): 'not_decent',
	('poor', 'high'): 'very_decent',
	('average', 'high'): 'very_decent',
	('good', 'high'): 'not_decent',
	('poor'): 'very_decent',
	('average'): 'decent',
	('good'): 'not_decent',
	('low'): 'not_decent',
	('average'): 'decent',
	('high'): 'very_decent'
	}

	# List for storing prediction and final result
prediction, result = [],[]

	# Read csv file

			# Fuzzify process: crisp set -> fuzzy set input
fuzzy_income = fuzzify(float(1.632), income.get_mf())
fuzzy_debt = fuzzify(float(39.375), debt.get_mf())

			# Inference process (clipping)
fuzzy_qualification = inference((fuzzy_income, fuzzy_debt), expert_rules)

			# Deffuzify: fuzzy set value -> crisp value
result_area = qualification.get_area(fuzzy_qualification)
calculate_result = defuzzify(result_area, fuzzy_qualification)
		
print (calculate_rerult)

this class rr1 is ;

Code: Select all

import math


# Classes of fuzzy system components, 
# Antecedent for input/sensor, Consequent for output

def reduce(function, iterable, initializer=None):
    it = iter(iterable)
    if initializer is None:
        value = next(it)
    else:
        value = initializer
    for element in it:
        value = function(value, element)
    return value


class Antecedent:
	def __init__(self, universe):
		self.__universe = universe

	def get_mf(self):
		return self.__membership

	def set_mf(self, mf):
		self.__membership = mf

class Consequent:
	def __init__(self, universe):
		self.__universe = universe

	def get_mf(self):
		return self.__membership

	def set_mf(self, mf):
		self.__membership = mf

	def get_area(self, labels):
		result = []

		for i in labels:
			for key, value in self.__membership.items():
				if i == key:
					result.append([min(value), max(value)])

		return result

# Utilities
def frange(x, y, jump):
	assert x < y

	while x < y:
		yield x
		x += jump

# Fuzzy membership function
def trapmf(x, point):
	# a <= b <= c <= d is required
	assert point[0] <= point[1] <= point[2] <= point[3]

	if x <= point[0] and x >= point[3]:
		return 0
	elif point[0] < x < point[1]:
		return round((x - point[0]) / (point[1] - point[0]), 3)
	elif point[1] <= x <= point[2]:
		return 1
	elif point[2] < x <= point[3]:
		return round(-(x - point[3]) / (point[3] - point[2]), 3)

# Fuzzify return a dictionary containing membership value of x, can be more than one
def fuzzify(x, mfx):
	membership_value = {}

	for key, value in mfx.items():
		membership = trapmf(x, value)

		# assign membership value with 0 if x it is not in the area (None)
		membership_value[key] = trapmf(x, value) if membership != None else 0
	
	return membership_value

# Clipping process, producing an result area of trapezoidal

def inference(antecedents, rules):
	area = {}
	p, q = antecedents[0], antecedents[1]

	for i in p.items():
		if i[1] > 0:	
			# Get rules with single key (income) -> qualification
			label1 = rules.get((i[0]), None)
			area[label1] = i[1]
			
			for j in q.items():	
				if j[1] > 0:
					# Get rules with single key (debt) -> qualification
					label2 = rules.get((j[0]), None)
					area[label2] = j[1]

					# Get rules with double key (income, debt) -> qualification
					label3 = rules.get((i[0], j[0]), None)
					area[label3] = min(i[1], j[1])

	return area		

def defuzzify(x, mf):
	result, divider = 0, 0
	rand_point, sum_rand_point = [], []

	for i in range(0, len(x)):
		rand_point.append(list(frange(min(x[i]), max(x[i]), 4)))
		sum_rand_point.append(reduce(lambda x, y: x + y, rand_point[i]))

		divider += len(rand_point[i]) * mf.values()[i]
		result += sum_rand_point[i] * mf.values()[i]

	return result / divider
help please

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Gremlins

Post by pythoncoder » Thu Jul 14, 2022 12:23 pm

It's a big ask wanting us to trawl through all that code. I suggest you read https://www.tutorialspoint.com/What-are ... ew-objects.

These objects are not subscriptable, but you can cast them to lists or tuples:

Code: Select all

>>> d = {1:'one', 2:'two'}
>>> dv = d.values()
>>> dv[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'dict_view' object isn't subscriptable
>>> l = tuple(dv)
>>> l[0]
'two'
>>> 
Accessing such object by subscript is not usually very useful as they are not sorted. A more normal way to use a dict_view is to iterate over them:

Code: Select all

d = {1:'one', 2:'two'}
for v in d.values():
    print(v)
Peter Hinch
Index to my micropython libraries.

iceelon
Posts: 30
Joined: Tue Jul 12, 2022 11:42 am

Re: Gremlins

Post by iceelon » Thu Jul 14, 2022 12:32 pm

tanks :)
It's a big ask wanting us to trawl through all that code
Yes , it is too much code but ... the other day I was urged to upload more code because it was difficult to identify a problem with a single line of code

Besides, I think, from my humble opinion, it is easier to see "the whole bread, even if it is raw" than to see the wheat before it is processed.

Post Reply