Apologies for this newbie question. I'm not sure if I even phrased it correctly.
I have a class inside a function that lists a bunch of variables, and I want to be able to choose which variables are printed and returned at the final function call. However, I clearly don't understand enough about objects to accomplish this, because it raises errors when I try to attempt something.
def gpscall(call):
#Write GPSinput
out = ''
ser.write(com.GPSstatus.encode())
time.sleep(1)
#Read output
while ser.inWaiting() > 0:
decoded = (ser.read(1).decode)
out += decoded()
strlen = len(str(out))
substr = out[0:strlen-9]
#GPS? information list
variables = substr.splitlines()
#Storing each output in a variable
class GPS:
PULSE_SAWTOOTH = [int(s) for s in variables[1] if s.isdigit()]
TRACKED_SATELLITES = [int(s) for s in variables[2] if s.isdigit()]
VISIBLE_SATELLITES = [int(s) for s in variables[3] if s.isdigit()]
LONGITUDE = variables[5]
longlen = len(LONGITUDE)
LONGDEG = LONGITUDE[0:longlen-7]
LONGMIN = LONGITUDE[longlen-7:]
LATITUDE = variables[6]
latlen = len(LATITUDE)
LATDEG = LATITUDE[0:latlen-7]
LATMIN = LATITUDE[latlen-7:]
HEIGHT = variables[7]
KNOTS = variables[8]
DEGREES = [9]
GPS_STATUS = variables[10]
TIMING_MODE = variables[17]
FIRMWARE_VERSION = variables[20]
print (call)
return (call)
if __name__ == "__main__":
#Call the functions
gpscall(gpscall.GPS.LATITUDE)
This raises the error,
Function 'gpscall' has no 'GPS' member.
I don't understand why it cannot see the class, I think I'm using the function parameters incorrectly.
Any help with my poorly written code would be greatly appreciated.
Perhaps something like so is your intention? __init__ will initialize the object, and the self. will "save variables to the object."
class GPS:
def __init__(self):
#Write GPSinput
ser.write(com.GPSstatus.encode())
#Read output
out = ''
while ser.inWaiting() > 0:
decoded = (ser.read(1).decode)
out += decoded()
#GPS information list
substr = out[0:len(str(out))-9]
variables = substr.splitlines()
self.PULSE_SAWTOOTH = [int(s) for s in variables[1] if s.isdigit()]
self.TRACKED_SATELLITES = [int(s) for s in variables[2] if s.isdigit()]
self.VISIBLE_SATELLITES = [int(s) for s in variables[3] if s.isdigit()]
self.LONGITUDE = variables[5]
self.LONGDEG = LONGITUDE[0:len(LONGITUDE)-7]
self.LONGMIN = LONGITUDE[len(LONGITUDE)-7:]
self.LATITUDE = variables[6]
self.LATDEG = LATITUDE[0:len(LATITUDE)-7]
self.LATMIN = LATITUDE[len(LATITUDE)-7:]
self.HEIGHT = variables[7]
self.KNOTS = variables[8]
self.DEGREES = variables[9]
self.GPS_STATUS = variables[10]
self.TIMING_MODE = variables[17]
self.FIRMWARE_VERSION = variables[20]
gps = GPS()
print(gps.GPS_STATUS)
Yor cls inside the function is perfect and there is nothing wrong there. You are just trying to call the function and the cls objects in a wrong way.
if __name__ == "__main__":
#Call the functions
gpscall(gpscall.GPS.LATITUDE) <---- ERROR HERE
gpscall is a function, so when you are trying to access GPS.LATITUDE, it won't find any objects. You would have to do either this
gpscall(gpscall("").GPS.LATITUDE)
But I think the best way to do this is to write the func inside the cls. You will still be able to access all the variables of the cls, and it won't create much hassle.
PS: That's a good question, not a noob one. Good luck (y)
Related
When I attempted to write a recursive nested function within a python class, every time the recursive function completed and returned back to the first function my class property reverted back to the original state.
def main():
input = [
[1,3,1],
[1,5,1],
[4,2,1]
]
sln = Solution()
sln.findPath(input)
print("Output: " + str(sln.minPathSum))
print(*sln.minPath, sep = "->")
class Solution():
minPath = []
minPathSum = None
grid = []
def findPath(self, grid):
self.minPath = []
self.minPathSum = None
self.grid = grid
self.recurse(0,0,[])
def recurse(self, xCoord, yCoord, currentPath):
if(len(self.grid) <= yCoord):
return
if(len(self.grid[yCoord]) <= xCoord):
return
currentValue = self.grid[yCoord][xCoord]
currentPath.append(currentValue)
if(len(self.grid) - 1 == yCoord and len(self.grid[yCoord]) - 1 == xCoord):
currentPathSum = sum(currentPath)
if(self.minPathSum == None or currentPathSum < self.minPathSum):
self.minPathSum = currentPathSum
self.minPath = currentPath
else:
#right
self.recurse(xCoord + 1, yCoord, currentPath)
#down
self.recurse(xCoord, yCoord + 1, currentPath)
currentPath.pop()
return
if __name__ == "__main__":
main()
Running this results in:
Output: 7
Debugging the code within VSCode does indicate that self.minPath is getting set within the recurse function; however, it appears to be losing scope to the original class instance.
In addition I attempted to recreate the same nested situation with separate code and ended up with the following.
def main():
tst = ScopeTest()
tst.run()
print(*tst.tstArray)
print(tst.tstNumber)
class ScopeTest():
tstArray = []
tstNumber = 0
def run(self):
self.otherFunc()
def otherFunc(self):
self.tstArray = [1,2,3,4,5]
self.tstNumber = 7
if __name__ == "__main__":
main()
The above did return the expected outcome which leads me to think this has something to do with the recursion.
Just a heads up, I'm fairly new to python so I may be making a rookie mistake, but I can't seem to figure out why this is happening.
Your recurse() method is generating a currentPath parameter and when this is deemed to be correct you execute: self.minPath = currentPath. Unfortunately, you just reference the same object as currentPath which is later mutated.
Your line should be: self.minPath = currentPath[:]
You then see some contents in self.minPath
Mandatory link to Ned Batchelder
Also you can remove these lines:
minPath = []
minPathSum = None
grid = []
from just below class Solution():
I'm wanting to be able to print and update values retrieved from a small GPS in real time. For whatever reason, the code will not update the GPS value, and only prints the same value until I restart the code. My guess is the variable is not able to update, but I wouldn't know how to fix that.
while ser.inWaiting() > 0:
decoded = (ser.read(1).decode)
echo += decoded()
class GPS:
def __init__(self):
#Write GPSinput
out = ''
ser.write(com.GPSstatus.encode())
time.sleep(1)
#Read output
while ser.inWaiting() > 0:
decoded = (ser.read(1).decode)
out += decoded()
strlen = len(str(out))
substr = out[0:strlen-9]
#GPS? information list
variables = substr.splitlines()
#Storing each output in a variable
self.PULSE_SAWTOOTH = [int(s) for s in variables[1] if s.isdigit()]
self.TRACKED_SATELLITES = [int(s) for s in variables[2] if s.isdigit()]
self.VISIBLE_SATELLITES = [int(s) for s in variables[3] if s.isdigit()]
self.LONGITUDE = variables[5]
self.longlen = len(self.LONGITUDE)
self.LONGDEG = self.LONGITUDE[0:self.longlen-7]
self.LONGMIN = self.LONGITUDE[self.longlen-7:]
self.LATITUDE = variables[6]
self.latlen = len(self.LATITUDE)
self.LATDEG = self.LATITUDE[0:self.latlen-7]
self.LATMIN = self.LATITUDE[self.latlen-7:]
self.HEIGHT = variables[7]
self.KNOTS = variables[8]
self.DEGREES = [9]
self.GPS_STATUS = variables[10]
self.TIMING_MODE = variables[17]
self.FIRMWARE_VERSION = variables[20]
if __name__ == "__main__":
#Call the functions
gps = GPS()
for i in range(100):
print(gps.LATITUDE)
#Enterable Parameters
# PULSE_SAWTOOTH
# TRACKED_SATELLITES
# VISIBLE_SATELLITES
# LONGITUDE
# longlen
# LONGDEG
# LONGMIN
# LATITUDE
# latlen
# LATDEG
# LATMIN
# HEIGHT
# KNOTS
# DEGREES
# GPS_STATUS
# TIMING_MODE
# FIRMWARE_VERSION
I'm guessing this is a pretty simple solution, but I'm a beginner and I don't fully understand whats happening enough to fix it. If anyone could shed some knowledge and help with my problem it would be greatly appreciated.
Aside from the while loop indent error and possible decode error. You're getting the same output for print(gps.LATITUDE) every time because you never update it, either by the gps object, or a call to a member function of class GPS. Your initial gps object always has LATITUDE equal to the value variables[6] and if that variable isn't changing, neither will your LATITUDE variable. You have options, you can either update LATITUDE directly:
class GPS:
def __init__(self , latitudeValue = 0):
self.LATITUDE = latitudeValue
if __name__ == "__main__":
gps = GPS()
print(gps.LATITUDE) # Prints 0, default value of latitudeValue
gps.LATITUDE = 5
print(gps.LATITUDE) # Now prints 5, changed value of LATITUDE in gps object
Or you can make it part of a function call:
class GPS:
def __init__(self , latitudeValue = 0):
self.LATITUDE = latitudeValue
def updateLatitude(self , newValue):
self.LATITUDE = newValue
if __name__ == "__main__":
gps = GPS()
print(gps.LATITUDE) # Prints 0
gps.updateLatitude(10) # Updates LATITUDE VALUE
print(gps.LATITUDE) # Prints 10
You can use either method with whatever the value of variables[6] is. Likewise, you can use this with all member variables of your class.
For real-time updating you need to use a event handling function, this scenario possibly calls for a listener. Without knowing more about the device passing data through the bus. If the manufacturer of your device doesn't supply an API to work with, then while you can use a loop to constantly reinitialize an object, another approach is module reloading.
I passed codeclimate to my code, and I obtained the following:
Similar code found in 1 other location
This is my code:
stradd = 'iterable_item_added'
if stradd in ddiff:
added = ddiff[stradd]
npos_added = parseRoots(added)
dics_added = makeAddDicts(localTable, pk, npos_added)
else:
dics_added = []
strchanged = 'values_changed'
if strchanged in ddiff:
updated = ddiff[strchanged]
npos_updated = parseRoots(updated)
dics_updated = makeUpdatedDicts(localTable, pk, npos_updated)
else:
dics_updated = []
Where iterable_item_added and values_changed are repeated. How to change it?
just abstract the parameters and create an helper method:
def testmethod(name,localTable,m,ddiff,pk):
if name in ddiff:
npos = parseRoots(ddiff[name])
rval = m(localTable, pk, npos)
else:
rval = []
return rval
the call it:
dics_added = testmethod('iterable_item_added',localTable,makeAddDicts,ddiff,pk)
dics_updated = testmethod('values_changed',localTable,makeUpdatedDicts,ddiff,pk)
note: be careful when factorizing code, you can introduce bugs (and make code better readable :)).
Also: that helper method forces to pass a lot of local variables. Maybe creating an object and member variables would simplify even more.
In that case, it appears to be a bit "overkill" to do that in order to make your review tool shut up.
I have been messing around with some code, trying to create a function for work planning. However I am stuck and wondered if someone could help? Thanks
class Work_plan(object):
def __init__(self,hours_work,work_len, work_des):
self.hours_work = hours_work
self.work_len = work_len
self.work_des = work_des
work_load = []
hours_worked = []
if hours_worked > hours_work:
print "Too much work!"
else:
work_load.append(work_des)
hours_worked.append(work_len)
print "The work has been added to your work planning!"
work_request = Work_plan(8, 2, "task1")
Work_plan
print work_load
it comes up with the error:
NameError: name 'work_load' is not defined
You defined the variable work_load inside the __init__ of the class, so you can't access it outside this scope.
If you want to have access to work_load, make it an attribute for objects of Work_plan class, and the access it by doing object.work_plan
For example:
class Work_plan(object):
def __init__(self,hours_work,work_len, work_des):
self.hours_work = hours_work
self.work_len = work_len
self.work_des = work_des
self.work_load = []
self.hours_worked = []
if hours_worked > hours_work:
print "Too much work!"
else:
self.work_load.append(work_des)
self.hours_worked.append(work_len)
print "The work has been added to your work planning!"
work_request = Work_plan(8, 2, "task1")
Work_plan
print work_request.work_load
I have a class which takes a array and calculates an answer. The Class is as follows :
class Delish:
ing = []
rmax = []
rmin = []
lmax = []
lmin = []
answer = 0
def rightmax(self):
# sets rmax
def rightmin(self):
# sets rmin
def leftmax(self):
# sets lmax
def leftmin(self):
# sets lmin
def calculate(self):
#calulates answer
def __init__(self,array):
self.ing = list(array)
self.rightmax()
self.rightmin()
self.leftmax()
self.leftmin()
self.calculate()
Now this gives output 4 13 (which is correct)
b = Delish([1,1,-1,-1])
a = Delish([1,2,3,4,5])
print a.answer,b.answer
And this gives output 7 13 (which is wrong)
a = Delish([1,2,3,4,5])
b = Delish([1,1,-1,-1])
print a.answer,b.answer
I cannot put the full code as it is a part of a live programming contest. But I want to know what is causing this weird behaviour. All of the methods are working on self. variables only. Therefore all the objects should be independent from each other right?
I can add details if it doesn't gives much of the algorithm away. Thank you.
In Python, declare instance variables within the constructor
What you're actually doing is declaring class variables. If you want instance variables in Python, you will need to declare them them in your constructor:
class Delish:
# This is a class variable.
# All instances can refer to this as self.foo
foo = 42
def __init__(self,array):
self.ing = [] # This is an instance variable
self.rmax = []
self.rmin = []
self.lmax = []
self.lmin = []
self.answer = 0
self.ing = list(array)
self.rightmax()
self.rightmin()
self.leftmax()
self.leftmin()
self.calculate()
You are probably a C++/Java programmer.
All your fields, except for ing which is assigned and thus overwritten in __init__, are class fields, that is, they are shared between all the instances of yor class. Move your instance initialisation to __init__:
class Delish:
# Nothing here
def __init__(self, array):
self.ing = list(array)
rmax = []
rmin = []
lmax = []
lmin = []
answer = 0
self.rightmax()
self.rightmin()
self.leftmax()
self.leftmin()
self.calculate()