How to return function results in an array? - python-2.7

I have one function where I am calculating the CPU usage of a test case. The function works, but I would like to append the result of the subtraction in a list for the further usage.
For example, first I subtract 10 and 15, which is -5. At this point the list looks like [-5]. Next I subtract 20 and 30, which is -10. Now I want the list to look like [-5, -10]. My current code is (python 2.7):
import psutil
class CPU():
def __init__(self):
self.cpu_start()
def cpu_start(self):
global a
a= psutil.cpu_percent(interval=1, percpu=False)
print a
def cpu_end(self):
global b
b = psutil.cpu_percent(interval=1, percpu=False)
print b
def diff(self):
c= a-b
list = []
list.append(c)
print list
def main():
CPU()
if __name__ == '__main__':
main()

Just make the diff function return a-b, and append that to an array:
import psutil
class CPU:
def __init__(self):
self.cpu_start()
self.list = []
self.a = 0
self.b = 0
self.c = 0
def cpu_start(self):
self.a = psutil.cpu_percent(interval=1, percpu=False)
return self.a
def cpu_end(self):
self.b = psutil.cpu_percent(interval=1, percpu=False)
return self.b
def diff(self):
self.c = self.cpu_start() - self.cpu_start()
return self.c
def main():
cpu = CPU()
results = []
while True:
results.append(cpu.diff())
print results
if __name__ == '__main__':
main()
Remember that when you're using a class function, you need to create an object of that class, such as cpu = CPU() - I'm creating an object called cpu of class CPU, initialised with nothing. Then the __init__ function will create a and b(created as self.a and self.b, because they're local) and store them locally in that class. The diff() function, takes no arguments, but returns the difference of a and b which are stored locally in that class. Then I create a list called results with no elements. I run cpu.diff(), which gets the difference from cpu_start() and cpu_end(), and append the result to the results array. This is run in a loop, constantly appending to the array and printing it.
Hope this helps.

Related

TypeError: 'int' object is not iterable, (list(map))

So here is my code
class Shape(object):
def __init__(self, coords):
super(Shape, self).__init__()
self._coords = list(map(list, coords))
def move(self,distance):
self._coords = distance
def __getitem__(self,key):
return self._coords[key]
class Point(Shape):
def __init__(self,coords):
super(Point, self).__init__(coords)
if __name__ == '__main__':
p = Point((0, 0))
p.move((1, 1))
assert p[0, 0], p[0, 1] == (1, 1)
Basically I want to create a subclass Point from the parent class Shape.
The init part of shape shall stay the same and try to create a new point and pass the test under "main".
This code as it is now gets an error TypeError: 'int' object is not iterable
I am stuck of solutions to this as a beginner in python. What arguments can I pass to _coords to be accepted? How can I connect Point and Shape?
class Shape(object):
def __init__(self, coords):
super(Shape, self).__init__()
self._coords = list(map(list, [coords])) # <--- to have it iterable enclose it in []
def move(self,distance):
self._coords = distance
def __getitem__(self,key):
return self._coords[key]
class Point(Shape):
def __init__(self,coords):
super(Point, self).__init__(coords)
if __name__ == '__main__':
p = Point((0, 0))
p.move((1, 1))
# the self._coords is a list, so fetch them by index like
assert p[0], p[1] == (1, 1)

object returning memory location instead of value

So I have this class:
#!/usr/bin/python3
class MyClass(object):
def __init__(self, length):
self._list = length
def get(self, index):
try:
return self._list[index]
except IndexError:
return None
which takes in a list and returns a value, a list index I think. I am trying to get that value:
def my_function(a_list):
a_list = MyClass
for x in (10**p for p in range(1, 9)):
if a_list:
print(a_list)
def main():
length = my_function(MyClass([i for i in range(0, 543)]))
but I keep getting only the memory location of the list, I think this is supposed to return an int.
I am hoping this is a workable bit of code, but I am struggling, with the concept of passing an "object" to a class, it doesn't make any sense to me.
Here is a test I am supposed to use:
def test_large_list():
s_list = My_Class([i for i in xrange(0, 100000)])
assert len(s_list._list) == list_length(s_list)
Ok, Here is my full function that works, it is done, how od I do this so that the first line takes an argument
#!/usr/bin/python3
#def list_length(single_method_list): This is what I am supposed to work with
from single_method_list import SingleMethodList
def my_function(): # This is how I have done it and it works.
a_list = MyClass([i for i in range(0, 234589)])
for x in (10**p for p in range(1, 8)):
if a_list.get(x):
print("More than", x)
first = x
else:
print("Less than", x)
last = x
break
answer = False
while not answer:
result = (first + last)/2
result = int(round(result))
print(result)
if s_list.get(result):
first = result
print('first', result)
else:
last = result
print('last', result)
if s_list.get(result) and not s_list.get(result + 1):
answer = True
print(result + 1)
my_function()
I don't know what more I can give to explain where I am stuck, it is the OOP part of this that I don't know I need the same results here, just passing it to the function instead of creating it inside the function which I did in order to do the algorithm.
Well your class does something else.MyClass is designed to take a List at initialization, so the naming length is not a good idea.
The get() method of this class takes in a number and returns the element located at that particular index in the initialized self._list.
Your logic should be like:
def my_function(a_list):
a_list = MyClass(a_list)
...
def main():
length = my_function([i for i in range(0, 543)])
Just to clarify some misunderstanding that you might have.
Class does not return anything. It is a blueprint for creating objects.
What can return value is a method (function). For instance, if you want to write a method which returns length of some list:
def my_function(some_list):
return len(some_list)
Or in your case:
def my_function(a_list):
return len(a_list._list)
Note that you should not call your variables list. It's a built-in function in python which creates lists.
And as you can see there is another built-in function len in python which returns length of list, tuple, dictionary etc.
Hope this helps, although it's still a bit unclear what you're trying to achieve.

Object not iterable when assigning to a list

I am coding a 2048 game via pygame. below is the relevant section of my code:
class Data():
def __init__(self):
self.data = getnull()
self.score = 0
def updatesprites(self): # EXP
spritelist = [[],[],[],[]]
for count in range(4): # for row loop
for i in range(4): # per column loop
if self.data[count][i] != 0:
spritelist[count]+= newSprite(str(self.data[count] [i])+".png") # error occurs here
spritelist[count][i].move(15 + i*115, 15 + count*115)
showSprite(spritelist[count][i])
class newSprite(pygame.sprite.Sprite):
def __init__(self,filename):
pygame.sprite.Sprite.__init__(self)
self.images=[]
self.images.append(loadImage(filename))
self.image = pygame.Surface.copy(self.images[0])
self.currentImage = 0
self.rect=self.image.get_rect()
self.rect.topleft=(0,0)
self.mask = pygame.mask.from_surface(self.image)
self.angle = 0
def addImage(self, filename):
self.images.append(loadImage(filename))
def move(self,xpos,ypos,centre=False):
if centre:
self.rect.center = [xpos,ypos]
else:
self.rect.topleft = [xpos,ypos]
----------------Main-------------------
from functions import *
from config import *
from pygame_functions import *
import pygame
screenSize(475,475) # call screen init
gameboard = newSprite("game board.png") # createboard
showSprite(gameboard)
game = Data()
game.updatesprites()
while True:
pass
when game.updatesprites() is called, "newSprite object is not iterable" error is raised in function Data.updatesprites
+ concatenates lists and strings, and adds numbers.
What you are trying to do, is to add an element to a list.
This is done as follows:
li.append(element) # adds the element to the end of the list
Or in your case:
spritelist[count].append(newSprite(str(self.data[count][i]) + ".png"))
Another solution: You could create a new type, that lets you add elements the way you were trying to:
class UglyList(list):
def __iadd__(self, other):
self.append(other)
You'd need to change another line here:
spritelist = [UglyList() for i in range(4)]

ValueError: This solver needs samples of at least 2 classes in the data, but the data contains only one class: 0.0

I have applied Logistic Regression on train set after splitting the data set into test and train sets, but I got the above error. I tried to work it out, and when i tried to print my response vector y_train in the console it prints integer values like 0 or 1. But when i wrote it into a file I found the values were float numbers like 0.0 and 1.0. If thats the problem, how can I over come it.
lenreg = LogisticRegression()
print y_train[0:10]
y_train.to_csv(path='ytard.csv')
lenreg.fit(X_train, y_train)
y_pred = lenreg.predict(X_test)
print metics.accuracy_score(y_test, y_pred)
StrackTrace is as follows,
Traceback (most recent call last):
File "/home/amey/prog/pd.py", line 82, in <module>
lenreg.fit(X_train, y_train)
File "/usr/lib/python2.7/dist-packages/sklearn/linear_model/logistic.py", line 1154, in fit
self.max_iter, self.tol, self.random_state)
File "/usr/lib/python2.7/dist-packages/sklearn/svm/base.py", line 885, in _fit_liblinear
" class: %r" % classes_[0])
ValueError: This solver needs samples of at least 2 classes in the data, but the data contains only one class: 0.0
Meanwhile I've gone across the link which was unanswered. Is there a solution.
The problem here is that your y_train vector, for whatever reason, only has zeros. It is actually not your fault, and its kind of a bug ( I think ). The classifier needs 2 classes or else it throws this error.
It makes sense. If your y_train vector only has zeros, ( ie only 1 class ), then the classifier doesn't really need to do any work, since all predictions should just be the one class.
In my opinion the classifier should still complete and just predict the one class ( all zeros in this case ) and then throw a warning, but it doesn't. It throws the error in stead.
A way to check for this condition is like this:
lenreg = LogisticRegression()
print y_train[0:10]
y_train.to_csv(path='ytard.csv')
if len(np.sum(y_train)) in [len(y_train),0]:
print "all one class"
#do something else
else:
#OK to proceed
lenreg.fit(X_train, y_train)
y_pred = lenreg.predict(X_test)
print metics.accuracy_score(y_test, y_pred)
TO overcome the problem more easily i would recommend just including more samples in you test set, like 100 or 1000 instead of 10.
I had the same problem using learning_curve:
train_sizes, train_scores, test_scores = learning_curve(estimator,
X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes,
scoring="f1", random_state=RANDOM_SEED, shuffle=True)
add the suffle parameter that will randomize the sets.
This doesn't prevent error from happening but it's a way to increase the chances to have both classes in subsets used by the function.
I found it to be because of only 1's or 0's wound up in my y_test since my sample size was really small. Try chaning your test_size value.
# python3
import numpy as np
from sklearn.svm import LinearSVC
def upgrade_to_work_with_single_class(SklearnPredictor):
class UpgradedPredictor(SklearnPredictor):
def __init__(self, *args, **kwargs):
self._single_class_label = None
super().__init__(*args, **kwargs)
#staticmethod
def _has_only_one_class(y):
return len(np.unique(y)) == 1
def _fitted_on_single_class(self):
return self._single_class_label is not None
def fit(self, X, y=None):
if self._has_only_one_class(y):
self._single_class_label = y[0]
else:
super().fit(X, y)
return self
def predict(self, X):
if self._fitted_on_single_class():
return np.full(X.shape[0], self._single_class_label)
else:
return super().predict(X)
return UpgradedPredictor
LinearSVC = upgrade_to_work_with_single_class(LinearSVC)
or hard-way (more right):
import numpy as np
from sklearn.svm import LinearSVC
from copy import deepcopy, copy
from functools import wraps
def copy_class(cls):
copy_cls = type(f'{cls.__name__}', cls.__bases__, dict(cls.__dict__))
for name, attr in cls.__dict__.items():
try:
hash(attr)
except TypeError:
# Assume lack of __hash__ implies mutability. This is NOT
# a bullet proof assumption but good in many cases.
setattr(copy_cls, name, deepcopy(attr))
return copy_cls
def upgrade_to_work_with_single_class(SklearnPredictor):
SklearnPredictor = copy_class(SklearnPredictor)
original_init = deepcopy(SklearnPredictor.__init__)
original_fit = deepcopy(SklearnPredictor.fit)
original_predict = deepcopy(SklearnPredictor.predict)
#staticmethod
def _has_only_one_class(y):
return len(np.unique(y)) == 1
def _fitted_on_single_class(self):
return self._single_class_label is not None
#wraps(SklearnPredictor.__init__)
def new_init(self, *args, **kwargs):
self._single_class_label = None
original_init(self, *args, **kwargs)
#wraps(SklearnPredictor.fit)
def new_fit(self, X, y=None):
if self._has_only_one_class(y):
self._single_class_label = y[0]
else:
original_fit(self, X, y)
return self
#wraps(SklearnPredictor.predict)
def new_predict(self, X):
if self._fitted_on_single_class():
return np.full(X.shape[0], self._single_class_label)
else:
return original_predict(self, X)
setattr(SklearnPredictor, '_has_only_one_class', _has_only_one_class)
setattr(SklearnPredictor, '_fitted_on_single_class', _fitted_on_single_class)
SklearnPredictor.__init__ = new_init
SklearnPredictor.fit = new_fit
SklearnPredictor.predict = new_predict
return SklearnPredictor
LinearSVC = upgrade_to_work_with_single_class(LinearSVC)
You can find the indexes of the first (or any) occurrence of each of the classes and concatenate them on top of the arrays and delete them from their original positions, that way there will be at least one instance of each class in the training set.
This error related to the dataset you are using, the dataset contains a class for example 1/benign, whereas it must contain two classes 1 and 0 or Benign and Attack.

Best approach to create an saturating integer in python?

What would be the best approach to create a type that is a saturated integer in python ?
i.e.:
v = SaturatedInteger(0, 100)
# That should create an integer that will always be in between 0 and 100,
# and have all default operations
v += 68719
print v #Should print '100'.
I can think of inheriting int type, but where should the saturating logic be implemented then ?
If you need a new (quick and dirty) class for it, I would implement it as follows.
class SaturatedInteger:
def __init__(self, val, lo, hi):
self.real, self.lo, self.hi = val, lo, hi
def __add__(self, other):
return min(self.real + other.real, self.hi)
def __sub__(self, other):
return max(self.real - other.real, self.lo)
...
Add as many of the other operators in the docs as you feel you will need (and their 'r' variants).
By storing the value in the instance name real, you can do your arithmetic with regular integers, floats, etc. too:
a = SaturatedInteger(60, 0, 100)
print(a)
60
print(a+30)
90
print(a+40)
100
print(a+50.)
100
print(a-70.)
0
print(a+a)
100
Though, of course you only add the real part if you're adding a complex number to your SaturatedInteger, so watch out. (For a much more complete and robust version, #jonrsharpe's answer is the way to go).
In general, I would implement using a #property to protect an instance's value attribute, then emulate a numeric type, rather than inheriting from int:
class SaturatedInteger(object):
"""Emulates an integer, but with a built-in minimum and maximum."""
def __init__(self, min_, max_, value=None):
self.min = min_
self.max = max_
self.value = min_ if value is None else value
#property
def value(self):
return self._value
#value.setter
def value(self, new_val):
self._value = min(self.max, max(self.min, new_val))
#staticmethod
def _other_val(other):
"""Get the value from the other object."""
if hasattr(other, 'value'):
return other.value
return other
def __add__(self, other):
new_val = self.value + self._other_val(other)
return SaturatedInteger(self.min, self.max, new_val)
__radd__ = __add__
def __eq__(self, other):
return self.value == self._other_val(other)
if __name__ == '__main__':
v = SaturatedInteger(0, 100)
v += 68719
assert v == 100
assert 123 + v == 100
I've only implemented __add__, __radd__ and __eq__, but you can probably see how the rest could be built out as required. You might want to think about what happens when two SaturatedIntegers are used together - should the result have e.g. min(self.min, other.min) as its own min?
I wrote a sample class that has an add function:
class SatInt:
def __init__(self, low, up):
self.lower = low
self.upper = up
self.value = 0
def add(self, n):
if n+self.value > self.upper:
self.value = self.upper
else:
self.value = self.value + n
x = SatInt(0,100)
x.add(32718)
print(x.value)
100