Dynamic variable from function in Python - python

var 1 is constantly changing with every new line that is written in the csv file. Any suggestion how can I get the value outside of the function. This example does not work for me.
I updated my code and added second function which is exactly the same but is reading another file. Now I only get print from the first function only. If I disable the first function I can get the print from the second function. Is there a way to print both of them or maybe three or four if I add later new functions ?
import sys
import time
import datetime
import os
class Application():
def loop_one(self):
filename = 'Test.csv'
mycsv = open(filename, 'r')
mycsv.seek(0, os.SEEK_END)
while 1:
time.sleep(1)
where = mycsv.tell()
line = mycsv.readline()
if not line:
mycsv.seek(where)
else:
arr_line = line.split(',')
var1 = arr_line[5]
mydate = datetime.datetime.now()
print var1, mydate.strftime("%H:%M:%S:%f")
return var1
def loop_two(self):
filename2 = 'Test2.csv'
mycsv2 = open(filename2, 'r')
mycsv2.seek(0, os.SEEK_END)
while 1:
time2.sleep(1)
where2 = mycsv2.tell()
line2 = mycsv2.readline()
if not line2:
mycsv2.seek(where2)
else:
arr_line2 = line2.split(',')
var2 = arr_line2[5]
mydate2 = datetime.datetime.now()
print var2, mydate.strftime("%H:%M:%S:%f")
return var2
s = Application()
var1 = s.loop_one()
var2 = s.loop_two()

You can declare a variable inside the init function so you can use that anywhere
class A(object):
def __init__(self):
self.x = 'Hello'
def method_a(self, foo):
print self.x + ' ' + foo
In your case you can do something like this (not tested)
class Application():
def __init__(self):
self.filename = 'Test.csv'
self.mycsv = open(self.filename, 'r')
self.mycsv.seek(0, os.SEEK_END)
self.var1 = ''
def loop_one(self):
while 1:
time.sleep(1)
where = self.mycsv.tell()
line = self.mycsv.readline()
if not line:
self.mycsv.seek(where)
# you need a break here or somewhere :D
else:
arr_line = line.split(',')
self.var1 = arr_line[5]
mydate = datetime.datetime.now()
print self.var1, mydate.strftime("%H:%M:%S:%f")
return self.var1
s = Application()
s.loop_one()

You have move your if else block inside the for loop otherwise your code will stuck in infinite loop.
import sys
import time
import datetime
import os
class Application():
def loop_one(self):
filename = 'Test.csv'
mycsv = open(filename, 'r')
mycsv.seek(0, os.SEEK_END)
while 1:
time.sleep(1)
where = mycsv.tell()
line = mycsv.readline()
if not line:
mycsv.seek(where)
else:
arr_line = line.split(',')
var1 = arr_line[5]
mydate = datetime.datetime.now()
print var1, mydate.strftime("%H:%M:%S:%f")
return var1
s = Application()
s.loop_one()

Accessing var1 outside the function
class Application:
var1 = None
def loop_one(self):
# Code
while True:
# Your code
if not line:
# Code
else:
global var1
# Code
var1 = arr_line[5]
# Then you can access it via
def show():
print(var1)

Related

Python: Error in assigning a method result to a instance variable on a constructor

When I run this code I get a message saying that name 'readFile' is not defined. How can I write this so that I don't have this error? I want to assign a list of lists to self.cities. Thank you.
class TSP:
def __init__(self, filename):
self.filename = filename
self.cities = readFile()
def readFile(self):
f = open(self.filename, 'r')
citieslist = []
res = f.readlines()
for line in res:
aList = list(line.split(';'))
for i in range(0,len(aList)):
aList[i] = aList[i].rstrip('\n')
citieslist.append(aList)
return readFile (self.cities)
f.close()
You have not used self in init. You have a recursive function at readFile. You closed the file after returning from function readFile. You only have to strip the whole line to cut the \n off. Also returning is unnecessary since you can work with references inside Class.
class TSP:
def __init__(self, filename):
self.filename = filename
self.cities = self.readFile()
def readFile(self):
f = open(self.filename, 'r')
citieslist = []
res = f.readlines()
for city in res:
city = city.strip().split(';')
citieslist.append(city)
f.close()
return citieslist
SInce you have basically negated any future use of readFile by omitting an argument for filename in it's interface, you could just do the below.
We simply use a with statement to process the file, and a list comprehension to concoct the results.
class TSP:
def __init__(self, filename):
with open(filename, 'r') as f:
self.cities = [line.strip().split(';') for line in f.readlines()]
#do something with self.cities here
tsp = TSP('somefile.ext')

Changing global variables and read them

I have properties file props.properties
[collect_data]
collect = True
And 2 files test2.py
import test1 as c
class Test:
def __init__(self):
pass
def printer(self):
print 'in test2 value is' c.COLLECT_DATA
And test1.py file with main function
from ConfigParser import ConfigParser
import test2 as t
DEFAULT_PROPS = '..//etc//props.properties'
COLLECT_DATA = False
class Initializer:
def __init__(self):
pass
def init_const(self, properties=DEFAULT_PROPS):
cfg = ConfigParser()
print 'Start'
cfg.read(properties)
global COLLECT_DATA = False
COLLECT_DATA = eval(cfg.get('collect_data', 'collect'))
print 'Now it is', COLLECT_DATA
if __name__ == '__main__':
i = Initializer()
i.init_const()
test = t.Test()
test.printer()
print COLLECT_DATA
I want to read properties from props file, assing it and read them in another file, but actually I have such logs:
Start
Now it True
in test2 value is False
True
How to solve it?

Python : how to use another method's returning value in another method?

what i am trying to do is get a returning value from abcd method, and use this value to as a the substitue of fname and the error is continues to occur.
how can i fix this error?
ICB164000395.txt has four lines.
and i want line_count print out 4(The number of lines in the text file)
class Test():
def abcd(self):
self.a = a
a = 'ICB164000395.txt'
return a
def line_count(self, fname):
with open(fname) as f:
for i, l in enumerate(f):
pass
return i + 1
print(i + 1)
t = Test()
t.line_count(abcd())
and the error appears like this
Traceback (most recent call last):
File "C:\Users\mg\Desktop\Tubuc\openAPI\test9.py", line 16, in
t.line_count(abcd(fname))
NameError: name 'abcd' is not defined
Just looking at the function:
def abcd(self):
self.a = a
a = 'ICB164000395.txt'
return a
I'm guessign you're getting an error at self.a = a .. Because a is not defined yet. It's not passed in either.
I think what you want is:
class Test():
def abcd(self):
a = 'ICB164000395.txt' # you'll need to correct the path to this file
return a
def line_count(self, fname):
with open(fname) as f:
for i, l in enumerate(f):
pass
return i + 1
print(i + 1)
t = Test()
t.line_count(t.abcd())
abcd is an instance method so you have to call it from an instance of your class
t = Test()
t.line_cont(t.abcd())
Your abcd method also uses the variable a before it is ever defined, so you could change it to
def abcd(self):
self.a = 'ICB164000395.txt'
return self.a
It appears what you want from your abcd method is typically handled in an init. You can set the file name when you instantiate a Test object. Then you can call the line count. Your line_count method should also specify how you are opening the file 'r' for read mode.
class Test():
def __init__(self, file_name):
self._file_name = file_name
def line_count(self):
with open(self._file_name, 'r') as f:
for i, l in enumerate(f):
pass
return i + 1
print(i + 1)
t = Test('ICB164000395.txt')
t.line_count()

global name NAME is not defined PYTHON

I have problems with the following code, it says "NameError: global name 'Teater' is not defined" I can not solve it by myself...
teaterLista = []
lista = []
class Teater:
def __init__(self, teaterNamn, plats, pensionar,vuxen,barn):
self.teaterNamn = teaterNamn
self.plats = plats
self.pensionar = pensionar
self.vuxen = vuxen
self.barn = barn
def readData():
#x = Teater(x,teaterNamn, plats,pensionar,vuxen,barn)
dataFile = open('c:/Teater.txt','r')
for line in dataFile:
if(line != '\n'):
temp = line.split('=',1)[1]
lista.append(temp.strip()) #strip tar bort radavslut
x = Teater(x,lista[0],lista[1],lista[2],lista[3],lista[4])
#teaterLista[0] = x
#print(teaterLista[0])
readData()
You call readData() during class definition. In Python a class body is executed during its definition in the contex of the class definition just as normal code would be. As the class is not completely defined at that moment, you cannot create a new instance, yet, thus get the error.
Dedent the whole definition for readData and the following line so all this is executed after the definition of the class has completed. This makes readLine a module-level function, not a class method. This is typical for a factory function.
teaterLista = []
lista = []
class Teater:
def __init__(self, teaterNamn, plats, pensionar,vuxen,barn):
self.teaterNamn = teaterNamn
self.plats = plats
self.pensionar = pensionar
self.vuxen = vuxen
self.barn = barn
def readData():
#x = Teater(x,teaterNamn, plats,pensionar,vuxen,barn)
dataFile = open('c:/Teater.txt','r')
for line in dataFile:
if(line != '\n'):
temp = line.split('=',1)[1]
lista.append(temp.strip()) #strip tar bort radavslut
x = Teater(lista[0],lista[1],lista[2],lista[3],lista[4])
#teaterLista[0] = x
#print(teaterLista[0])
readData()
Note: x = Teater(x, ... will not work, as x is not defined for the first invocation. If you think about specifying this for the self argument: no need; this is done implicitly. You should read how classes work in the documentation/tutorial.
You have to be careful in Python to correctly indent your code, as that defines the block scope.

Error accessing class objects in python

I am having some problem accessing class instances. I am calling the class from a procedure, name of instance is defined in some variable. I want the instance name to be created of that value and then want to access it, but when i access it is giving error. Can some one please help to resolve this issue.
class myclass:
def __init__(self,object):
self.name = object
def mydef():
global a1
b = "a1"
b = myclass(b)
mydef()
print a1.name
Second Problem:
In my actual script, I have to create a large number of such instances from this function (around 100). So defining their name as global would be painful, is there a way i could access those instances outside function without having to declare them as global.
Modification:
class myclass:
def __init__(self,object,typename):
self.name = object
self.typeid = typename
def mydef():
file_han = open(file,"r")
while True:
line = file_han.readline()
if not line:
break
start = line.find('"')
end = line.find('"',start+1)
string_f = line[start+1:end]
myclass(string_f,'a11')
mydef(file)
print def.name
print def.typeid
File Contents are :
a11 "def"
a11 "ghi"
a11 "eff"
Here's how I'd do it. I don't know why you're messing around with globals, if you'd care to explain, I'll update my answer.
class Myclass(object):
def __init__(self, name):
self.name = name
def mydef():
return Myclass("a1")
a1 = mydef()
print a1.name
Gather your instances in a list:
instances = []
for x in range(1000):
instances.append(Myclass("Instance {0}".format(x)))
print instance[42].name
Note the changes:
Class names should be capitalized
Use object as the base class of your classes (since python 2.2, but no longer necessary in 3.x)
Don't shadow the built-in object with your parameter name
Just use the string "a1" directly as a parameter instead of assigning it to a variable
Return something from the function instead of passing the result by global variable
RE: Comment
You haven't said anything about the format of these files, so I'll just give an example where the file to be read contains one class name per line, and nothing else:
def mydef(filename):
ret = []
with open(filename) as f:
for line in f:
# Call `strip` on line to remove newline and surrounding whitespace
ret.append(Myclass(line.strip()))
return ret
So if you have several files and wish to add all your instances from all your files to a large list, do it like this:
instances = []
for filename in ["myfile1", "myfile2", "myfile3"]:
instances.extend(mydef(filename))
RE: OP Edit
def mydef(filename):
ret = []
with open(filename, "r") as file_han:
for line in file_han:
string_f = line.split('"')[1]
ret.append(Myclass(string_f))
return ret
i = mydef("name_of_file")
RE: Comment
Oh, you want to access them by name. Then return a dict instead:
def mydef(filename):
ret = {}
with open(filename, "r") as file_han:
for line in file_han:
string_f = line.split('"')[1]
ret[string_f] = Myclass(string_f)
return ret
i = mydef("name_of_file")
print i["ghi"].name # should print "ghi"
RE: Comment
If I understand you correctly, you want to have it both ways -- index by both line number and name. Well then why don't you return both a list and a dictionary?
def mydef(filename):
d = {}
L = []
with open(filename, "r") as file_han:
for line in file_han:
string_f = line.split('"')[1]
instance = Myclass(string_f)
d[string_f] = instance
L.append(instance)
return L, d
L, d = mydef("name_of_file")
print d["ghi"].name
print L[3]
print L.index(d["ghi"])
You could use class as repository for your instances, for example
class Named(object):
def __init__(self,name):
self.name = name
def __new__(cls,name):
instance = super(type,cls).__new__(cls,name)
setattr(cls,name,instance)
return instance
def __repr__(self):
return 'Named[%s]'%self.name
Named('hello')
Named('x123')
Named('this is not valid attribute name, but also working')
print(Named.hello,Named.x123,getattr(Named,'this is not valid attribute name, but also working'))

Categories

Resources