Efficient Way Doing Same function for different variables - python

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

Related

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

Update text in real time by calling two functions Pygame

I have program that takes input from the user and displays multiple variations of the input using the Population() function. The store_fit function adds these different variations to a list then deletes them so that the list is only populated with one variation at a time.
I want to be able to get the variation from the list and use it to update my text. However, my program only updates the text after the Population function is completed. How could I run the Population function and update my text simultaneously?
code:
fit = []
...
def store_fit(fittest): # fittest is each variation from Population
clear.fit()
fit.append(fittest)
...
pg.init()
...
done = False
while not done:
...
if event.key == pg.K_RETURN:
print(text)
target = text
Population(1000) #1000 variations
store_fit(value)
# I want this to run at the same time as Population
fittest = fit[0]
...
top_sentence = font.render(("test: " + fittest), 1, pg.Color('lightskyblue3'))
screen.blit(top_sentence, (400, 400))
I recommend to make Population a generator function. See The Python yield keyword explained:
def Populate(text, c):
for i in range(c):
# compute variation
# [...]
yield variation
Create an iterator and use next() to retrieve the next variation in the loop, so you can print every single variation:
populate_iter = Populate(text, 1000)
final_variation = None
while not done:
next_variation = next(populate_iter, None)
if next_variation :
final_variation = next_variation
# print current variation
# [...]
else:
done = True
Edit according to the comment:
In order to keep my question simple, I didn't mention that Population, was a class [...]
Of course Populate can be a class, too. I this case you've to implement the object.__iter__(self) method. e.g.:
class Populate:
def __init__(self, text, c):
self.text = text
self.c = c
def __iter__(self):
for i in range(self.c):
# compute variation
# [...]
yield variation
Create an iterator by iter(). e.g.:
populate_iter = iter(Populate(text, 1000))
final_variation = None
while not done:
next_variation = next(populate_iter, None)
if next_variation :
final_variation = next_variation
# print current variation
# [...]
else:
done = True

Python Class Method not returning imported class method?

I have a class which takes in a user choice (below)
from MiniProject1.interfaces.s_selection import SecondarySelection as SS #
imports the secondary_selection function from selections
import MiniProject1.interfaces.newcastle_cm as IT
from MiniProject1.Newcastle.newcastle_cc import ColumnCalculation as CC
class Newcastle:
def __init__(self):
self.key_typed = input(str("Select what you want to do: "))
#staticmethod
def column_or_graph():
if SS.get_input(SS.display_input()) is True:
IT.column_manipulation()
return True
IT.graph_plotting()
return False
def column_selection(self):
if self.key_typed == 1:
CC.total_electricity() # Calls the total_electricity method
elif self.key_typed == 2:
pass
elif self.key_typed == 3:
pass
elif self.key_typed == 4:
pass
elif self.key_typed == 5:
pass
def main():
if Newcastle.column_or_graph() is True:
Newcastle.column_selection(Newcastle())
elif Newcastle.column_or_graph() is False:
Newcastle.graph_plotting(Newcastle())
if __name__ == "__main__":
main()
The first part seems to run without issue, as the imported functions SS.get_input(SS.display_input()) from a class work without any issues and return either True or False, and when they do Newcastle.column_selection(Newcastle()) works as well, as it displays the interface and takes the user input.
So, all that seems to work. But when the user selects 1 it should return the CC.total_electricity() method, but instead it just ends the program.
I've tried return CC.total_electricity() as well, but that just does the same thing as well, and doesn't work. Is there any idea to why this may be? I've been working on it all day.
The CC.total_electricity class method looks like this:
import pandas as pd
class ColumnCalculation:
"""This houses the functions for all the column manipulation calculations"""
#staticmethod
def total_electricity():
"""Calculates the total amount of electricity used per year"""
df = pd.read_csv("2011-onwards-city-elec-consumption.csv", thousands=',')
df.set_index('Date', inplace=True) # Sets index to months
df.loc['Total'] = df.sum() # Creates a new row for the totals of each year
return print(df) # Prints the dataframe
And that has been tried, and tested to work, it's just when I import it it doesn't return anything and ends the program.
You compare the user input to an integer:
if self.key_typed == 1:
Therefore, you need to convert your input into an integer too.
So instead:
self.key_typed = input(str("Select what you want to do: "))
do:
self.key_typed = int(input("Select what you want to do: "))

Python Classes: Appending a list & Incorporating a Method

I just started learning about Python classes today and I had a quick question. I'm pretty amazed how much more succinct it has made my code, but I'm trying to figure out if the following is possible for a chess problem I'm working on.
(1) Can I append a list somehow from within a class method? I'm trying to figure out if there's a way to accumulate the pieces in a list each time capture is called.
(2) How can I call a method from within the class to be used in another method? I would like to be able to check if a move is valid before even proceeding if the piece should try to capture another or move.
class Piece(Board):
def __init__(self, piece, r, c):
self.piece = piece
self.r = r
self.c = c
This is the function I would like to incorporate into the functions below to avoid the redundancy (Question 2)
def valid_move(self,r,c,r_offset,c_offset):
#r, c are integers for the coordinates on the board
#r_offset,c_offset are the cells the piece might move to
self.tgt_r, self.tgt_c = r+r_offset, c+c_offset
if self.tgt_r <= 7 or self.tgt_c >= 0:
return True
return False
These functions are the same for now. I'm trying to see how I can use the capture function to accumulate a list of pieces once they're taken. (Question 1)
def capture(self,r,c, r_offset, c_offset):
piece = self.piece
self.tgt_r, self.tgt_c = r+r_offset, c+c_offset
if self.tgt_r > 7 or self.tgt_c < 0:
return None
else:
nb = Board(curr).copy_board() #this board is just 8x8 np.array
nb[self.tgt_r,self.tgt_c], nb[r,c] = piece,'-'
return nb
def move(self,r,c, r_offset, c_offset):
piece = self.piece
self.tgt_r, self.tgt_c = r+r_offset, c+c_offset
if self.tgt_r > 7 or self.tgt_c < 0:
return None
else:
nb = Board(curr).copy_board()
nb[self.tgt_r,self.tgt_c], nb[r,c] = piece,'-'
return nb
Thanks as always.
1. Can I append a list somehow from within a class method?
create a list -piecesList in your class for storing the pieces:
class Piece(Board):
def __init__(self, piece, r, c):
self.piece = piece
self.r = r
self.c = c
self.piecesList = [] #or init using some argument if you want to use some list from outside of the class
and whenever your capture method is called, simply append the piece in the piecesList :
def capture(self,r,c, r_offset, c_offset):
self.piecesList.append(self.piece)
piece = self.piece
2. How can I call a method from within the class to be used in another method?
you can simply call it using self.method(arg1, arg2...) :
def capture(self,r,c, r_offset, c_offset):
piece = self.piece
if self.valid_move(r,c,r_offset,c_offset) == False:
return None
else:
nb = Board(curr).copy_board() #this board is just 8x8 np.array
nb[self.tgt_r,self.tgt_c], nb[r,c] = piece,'-'
return nb

How to define global variable with different values in python

I would like to know how to call one global variable with two different values in a class and call them in the other class (within which behave such as flags).
in SerialP.py
Class SerialP(object):
def ReceiveFrame (self, data, length):
global myvariable
if x:
myvariable = 1:
elif y:
myvariable = 2
in fmMain.py
Class fmMain:
def OnReadConfig(self, event):
if SerialP.myvariable = 1:
#do this task
if SerialP.myvariable = 2:
#do another task
There are a few issues with your code.
First, comparison is done with == and not with = which is used for assignment. Also, you have not included the import statement which might be misleading.
In fmMain.py
import SerialP # and not from SerialP import SerialP
Class fmMain:
def OnReadConfig(self, event):
if SerialP.myvariable == 1: # changed to ==
#do this task
if SerialP.myvariable == 2: # changed to ==
#do another task

Categories

Resources