Task on inner functions in Python - python

I just created my 3 functions for a business problem : wether invest or not in my company.
These are the function i created.
The order should be:
Outer function = def is_investable
inner functions = def sanityChekc, def grahamNumberCalculator
In the end, the result should be "True" for the function is_investable if we decide to invest and false if we decide not.
def grahamNumberCalculator(EarningsPerShare, BookValuePerShare):
ConstInt = 22.5
IntermediateValue = ConstInt * EarningsPerShare * BookValuePerShare
HighestPrice = math.sqrt(IntermediateValue)
return HighestPrice
def is_investable(MarketPrice, HighestPrice, sanityCheck):
if MarketPrice <= HighestPrice and sanityCheck == True:
return True
else:
return False
def sanityCheck(CurrAssets, Liabilities, Debt, EarningOverTime):
First_subcheck = []
Second_subcheck = []
Forth_subcheck = []
if CurrAssets >= 1.5 * Liabilities:
First_subcheck.append('True')
if (Debt / CurrAssets) < 1.1:
Second_subcheck.append('True')
for i in EarningOverTime:
if i > 0:
Forth_subcheck.append('True')
if First_subcheck == ['True'] and Second_subcheck == ['True'] and len(Forth_subcheck) == len(EarningOverTime):
return (True)
else:
return (False)
This is my first time i try the inner functions, I saw some tutorials and with simple tasks I think i can menage it, but with this i can't figure it out. Would someone help meto understand how it works? Thank you very much
Sorry about the probable confusion of the request

Related

Pyomo error in formulating the constraint

I am trying to formulate a battery optimization problem to charge/discharge the battery optimally. The formulation is the following:
model = pyo.ConcreteModel()
#Set time period
model.timesteps = pyo.Set(initialize=pyo.RangeSet(len(pv)),ordered=True)
#Parameters
model.b_efficiency = pyo.Param(initialize=etta)
model.b_cap = pyo.Param(initialize=battery_capacity)
model.b_min_soc = pyo.Param(initialize=battery_soc_min)
model.b_max_soc = pyo.Param(initialize=battery_soc_max)
model.b_charging_rate = pyo.Param(initialize=battery_charge_rate)
model.Ppv = pyo.Param(model.timesteps,initialize=dict(enumerate(pv,1)),within=pyo.Any)
model.Pdemand = pyo.Param(model.timesteps, initialize=dict(enumerate(demand,1)),within=pyo.Any)
#Variables
model.Pbat_ch = pyo.Var(model.timesteps, within = pyo.NonNegativeReals)
model.Pbat_dis = pyo.Var(model.timesteps, within = pyo.NonNegativeReals)
model.Ebat = pyo.Var(model.timesteps, within = pyo.NonNegativeReals)
model.Pgrid = pyo.Var(model.timesteps, within = pyo.NonNegativeReals)
# Define the constraints of the model
def BatEnergyBounds(model, t):
return model.b_min_soc * model.b_cap <= model.Ebat[t] <= model.b_max_soc * model.b_cap
model.cons1 = pyo.Constraint(model.timesteps, rule = BatEnergyBounds)
def BatChargingBounds(model, t):
return 0 <= model.Pbat_ch[t] <= model.b_charging_rate
model.cons2 = pyo.Constraint(model.timesteps, rule = BatChargingBounds)
def BatDischargingBounds(model, t):
return 0 <= model.Pbat_dis[t] <= model.b_charging_rate
model.cons3 = pyo.Constraint(model.timesteps, rule = BatDischargingBounds)
def BatEnergyRule(model, t):
if t == model.timesteps.first():
return model.Ebat[t] == model.b_cap/2
else:
return model.Ebat[t] == model.Ebat[t-1] + (model.b_efficiency * model.Pbat_ch[t] - model.Pbat_dis[t]/model.b_efficiency)
model.cons4 = pyo.Constraint(model.timesteps, rule = BatEnergyRule)
def PowerBalanceRule(model, t):
return model.Pgrid[t] == model.Ppv[t] - model.Pdemand[t] + model.Pbat_dis[t] - model.Pbat_ch[t]
model.cons5 = pyo.Constraint(model.timesteps, rule = PowerBalanceRule)
# Define the objective function
def ObjRule(model):
return sum(model.Pgrid[t] for t in model.timesteps)
model.obj = pyo.Objective(rule = ObjRule, sense = pyo.minimize)
However, I am getting the following error:
PyomoException: Cannot convert non-constant Pyomo expression (1.0 <= Ebat[1]) to bool.
This error is usually caused by using a Var, unit, or mutable Param in a
Boolean context such as an "if" statement, or when checking container
membership or equality. For example,
>>> m.x = Var()
>>> if m.x >= 1:
... pass
and
>>> m.y = Var()
>>> if m.y in [m.x, m.y]:
... pass
would both cause this exception.
It seems like the error is caused by the IF statement that I used in cons4. Any idea of what is causing the error?
It isn't clear what is causing the error. If you are looking for help with an error, it is best to provide an example that produces the error by itself with the exact stack trace, etc.
Your "example" code produces the error because you are using a conditional if statement that depends on the value of a variable, which isn't allowed. Your code in the main program does not do that, so it looks fine.
If you are stuck, edit your post with a completely reproducible example.

Using Python and Open CV to match images and execute commands in another code

So fair warning, I am new to Python. Basically This is a script that communicates to another script. The py script compares stored images to a live feed for a reasonable match to a specific location in the live feed. While the other just interprets the results and sends them to a device.
Most of the time the images are pretty consistent and it will only print once. But some on the other hand, cause it to "flood" the output as it is matching a different similarity in the same defined location. I am trying to figure out the best way to suppress multiple print notifications from that.
This is all there is to the Python side of the code, removing print statements from the Python code remedies the print flood issue, but takes away the only means to know what the state is.
import os
import cv2
import time
class GCVWorker:
def __init__(self, width, height):
os.chdir(os.path.dirname(__file__))
self.gcvdata = bytearray(255)
self.User_defined_event_1 = cv2.imread('Images/Event_Data/xy.png')
self.User_defined_event_1_b = cv2.imread('Images/Event_Data_b/xy.png')
self.User_defined_event_2 = cv2.imread('Images/Event_Data/xy.pmg')
self.User_defined_event_2_b = cv2.imread('Images/Event_Data_b/xy.png')
self.Found_User_defined_event_1 = True
self.Found_User_defined_event_1_b = True
self.Found_User_defined_event_2 = True
self.Found_User_defined_event_2_b = True
def __del__(self):
del self.gcvdata
del self.User_defined_event_1
del self.User_defined_event_1_b
del self.User_defined_event_2
del self.User_defined_event_2_b
def process(self, frame):
self.gcvdata[0] = False
self.gcvdata[1] = False
User_defined_event_1 = frame[y1:y2, x1:x2]
similar = cv2.norm(self.User_defined_event_1, User_defined_event_1)
if similar <= 3000.0 and self.User_defined_event_1:
print('User defined event 1 Detected')
self.Found_User_defined_event_1 = False
self.gcvdata[0] = True
elif similar <= 3000.0 and self.User_defined_event_1_b:
print('User defined event 1 Detected')
self.Found_User_defined_event_1_b = False
self.gcvdata[0] = True
elif similar <= 3000.0:
pass
else:
self.Found_User_defined_event_1 = True
User_defined_event_2 = frame[y1:y2, x1:x2]
similar = cv2.norm(self.User_defined_event_2, User_defined_event_2)
if similar <= 3000.0 and self.User_defined_event_2:
print('User defined event 2 Detected')
self.gcvdata[1] = True
self.User_defined_event_2_a = False
elif similar <= 3000.0 and self.User_defined_event_2_b:
print('User defined event 2 Detected')
self.gcvdata[1] = True
self.User_defined_event_2_b = False
elif similar <= 3000.0:
pass
else:
self.Found_User_defined_event_2 = True
return frame, self.gcvdata

Efficient Way Doing Same function for different variables

I'm trying to make my code more efficient. Currently, I do have two functions doing basically the same inside a while loop. Only the subject (a and b) is different. These two subjects are taking turns with every loop.
This is my framework so far:
#run engine
engine_running = True
#set first subject
a = True
b = False
# while engine is running rotate between a and b
while engine_running == True:
if (a == True):
Function_a()
a = False
b = True
elif (b == True):
Function_b()
a = True
b = False
else:
print('Error')
This is the framework of both functions. It's noteworthy that each function reads the same set of Data, which has Data for a and b.
def Function_a():
import Data
import random
# Get Data and the weights
List = [Data.a_person1, Data.a_person2, Data.a_person3]
Weight = [List[0]['attribute'],List[1]['attribute'], List[2]['attribute']
# Choosing a random person based on its attribute
Selection = random.choices(List,Weight)
print(Selection[0]['name'], 'has been chosen')
def Function_b():
import Data
import random
# Get Data and the weights
List = [Data.b_person1, Data.b_person2, Data.b_person3]
Weight = [List[0]['attribute'],List[1]['attribute'], List[2]['attribute']
# Choosing a random person based on its attribute
Selection = random.choices(List,Weight)
print(Selection[0]['name'], 'has been chosen')
I'm new to python, so I understand this may look ugly and there is probably a nicer and more efficient way of doing this. Currently, it works for me. But maybe you have some input for me?
You could simply pass the lists that you wish to work on to the function
def Function(data):
import random
# Get Data and the weights
Weight = [data[0]['attribute'], data[1]['attribute'], data[2]['attribute']
# Choosing a random person based on its attribute
Selection = random.choices(data,Weight)
print(Selection[0]['name'], 'has been chosen')
Function([Data.a_person1, Data.a_person2, Data.a_person3])
Function([Data.b_person1, Data.b_person2, Data.b_person3])
def a():
print("a")
def b():
print("b")
switch = True
while True:
if switch:
a()
switch = False
elif not swith:
b()
switch = True
else:
print('Error')

Looping a function until another function is called

I am making a menu that runs on an LCD screen powered by a Raspberry Pi. I am trying to use the threading module to make the text, on the LCD, update until the menu position changes.
The menu is made up of a list of functions that are called when the menu position is changed. The switch_menu() function is called from outside the class, using an event handler, and is used to call the correct menu function. With some of these functions(item2); I want them to loop, and with others(item1); just display static text. The important thing is that they stop looping when switch_menu() is called again. How can I do this?
(here is a simplified version of my code)
class Menu:
def __init__(self):
self.LCD = Adafruit_CharLCD()
self.m_pos = 0
self.items = [self.item1,self.item2]
self.switch_menu(0)
def switch_menu(self,operation):
# 2. And here I want to stop it.
m_pos = self.m_pos
pos = m_pos
max_pos = len(self.items) - 1
m_pos = self.loop_selection(pos,max_pos,operation)
# 1. Here I want to start looping the function below.
self.items[m_pos]()
self.m_pos = m_pos
def loop_selection(self,pos,max_pos,operation):
if pos >= max_pos and operation == 1:
pos = 0
elif pos <= 0 and operation == -1:
pos = max_pos
else:
pos += operation
return pos
def item1(self):
self.LCD.clear()
text = "item1"
self.LCD.message(text)
def item2(self):
while True:
self.LCD.clear()
text = "item2"
self.LCD.message(text)
time.sleep(10)
There are many ways to achieve this, one simple way is to make the while loop in a variable and then set it to False outside the loop (for example, when calling switch_menu) once you want to stop it. Just beware of any race conditions that may be caused, of which I can't talk much more about since I don't know the rest of your code.
Typical, I have been trying to get this to work for days and as soon as I post a question; I find the answer.
Here is where I found my answer:
Stopping a thread after a certain amount of time
And this is what I did to make it work:
class Menu:
def __init__(self):
self.LCD = Adafruit_CharLCD()
self.m_pos = 0
self.items = [self.item1,self.item2]
self.switch_menu(0)
def switch_menu(self,operation):
try:
self.t_stop.set()
except:
pass
m_pos = self.m_pos
pos = m_pos
max_pos = len(self.items) - 1
m_pos = self.loop_selection(pos,max_pos,operation)
item = self.items[m_pos][0]
self.t_stop = threading.Event()
self.t = threading.Thread(target=item,args=(1,self.t_stop))
self.t.start()
self.m_pos = m_pos
def loop_selection(self,pos,max_pos,operation):
if pos >= max_pos and operation == 1:
pos = 0
elif pos <= 0 and operation == -1:
pos = max_pos
else:
pos += operation
return pos
def item1(self,arg):
while not stop_event.is_set():
text = "item1"
self.LCD.clear()
if not stop_event.is_set(): self.LCD.message(text)
stop_event.wait(10)
def item2(self,arg):
while not stop_event.is_set():
text = "item2"
self.LCD.clear()
if not stop_event.is_set(): self.LCD.message(text)
stop_event.wait(10)
I used a try/except to bypass the initial execution of switch_menu():
try:
self.t_stop.set()
except:
pass
I check the condition a second time as a workaround, to prevent race conditions:
if not stop_event.is_set(): self.LCD.message(text)
And I don't know why I had to pass in an argument when creating a thread, but it gave me errors when I didn't:
self.t = threading.Thread(target=item,args=(1,self.t_stop))
I know it needs some tidying up, but it works. If anyone has a more elegant solution feel free to post it.

Undertanding OOP and static methods

I haven't coded in OOP ever before. I've some functions to handle and verify VAT numbers and I want to enclose them in a class (more later, with other classes for handle IBAN account numbers make a module or a package, I'm not sure yet what's the difference of both).
I take a VAT number (CIF in spanish terms) and, at first, I need to clean it from any other characters than digits and letters. Then validate the number.
Input:
h55/586-75 4
Desired Output:
H55586754
True
Real Output:
h55/586-75 4
False
My Code:
import re
class CheckingCIF:
_letras = "ABCDEFGHIJKLMNPQRSVW" # Not used yet.
def __init__(self, un_cif):
self.cif = un_cif
self._limpiarCIF()
def _limpiarCIF(self):
self.cif = re.sub('\W', "", self.cif.upper())
return self
def validarCodigoCIF(self):
if len(self.cif) != 9:
return False
numero = self.cif[1:10]
pares = int(numero[1]) + int(numero[3]) + int(numero[5])
impares = 0
for i in range(0, 8, 2):
j = int(numero[i]) * 2
if j < 10:
impares += j
else:
impares += j - 9
digito = str(pares+impares)[-1]
if int(digito) == 0:
checkCIF = 0
else:
checkCIF = 10 - int(digito)
if str(checkCIF) == self.cif[-1]:
return True
else:
return False
if __name__ == "__main__":
entradaCodigoCIF = input('Enter the VAT number: ')
mi_cif = CheckingCIF(entradaCodigoCIF)
print(mi_cif.cif)
print(CheckingCIF.validarCodigoCIF(mi_cif))
The problem isn't in the validarCodigoCIF(self) method, since I've test before and it works fine.
The issue probably is in the _limpiarCIF(self) method because my incomprehension of the Object Oriented Programming and the use of the self word and the static methods.
You don't have static methods, you have regular methods, but are not calling them on the instance:
entradaCodigoCIF = input('Enter the VAT number: ')
mi_cif = CheckingCIF(entradaCodigoCIF)
print(mi_cif.cif)
print(mi_cif.validarCodigoCIF())
Referencing the method on an instance gives you a bound method, an object that knows how to call the underlying function and pass in the instance as a first argument.

Categories

Resources