Python: How to use methods from another file - python

I am kind of a beginner in python and stuck with the part where I have to access methods from a class which reside in a different file.
Here, in File1 i am trying to access find_method from file2 to and do some operation and return values. But somehow its not accessing "find_method" from file2.
id_1.py (File1):
from base_file import base_file
class id_1:
def condition():
day_part_response = ...some response...
current_time = ...some value...
abc = basefile.find_method(x=day_part_response, y=current_time)
base_file.py (File2)
class basefile:
def find_method(self, x, y):
for day in day_response:
start = day["start_time"]
end = day["end_time"]
if (condition): -->(consider this condition is satisfied)
self.start_time = start
self.end_time = end
day_id = day["_id"]
self.entity_ID = day["entity_id"]
self.restore = True
self.create_entity()
return self.start_time, self.end_time, day_id, self.day_part_entity_ID, self.restore

You will need to import using from base_file import basefile. Make sure to use above import statement, your both files 1 & 2 are in same directory.
In base_file.py, check if for your given input satisfies the condition -
if start < end and start < store_time < end or \
end < start and not (end < store_time < start):
otherwise it won't return any result and None will get returned as default.
In id_1.py, check if you are creating instance of the class id_1 like -
id_1_instance = id_1()
and then call the condition method on the instance
id_1_instance.condition()
Since above call receives a returned value, make sure to print it so you can see the output.

You should be doing: from base_file import basefile
If 'base_file.py' is in the same directory as id_1.py
then the import will work. If you put the class in a
different directory, you need to add a line of code
before the import, something like:
sys.path.append("/home/username/python/classes")
You should also take a look at https://peps.python.org/pep-0008/#class-names
which gives you the recommended naming conventions such as:
methods should be in the 'snake' format: def my_method().
Class names should follow the 'camelcase'.
The class MyNewClass() should be saved in a file named: myNewClass.py
So, you would do the import as: from myNewClass import MyNewClass.
I save all my classes in a single 'class' directory.
Of course if you are using Windows, you would have to specify
"C:\whatever".
Hope this helps!

Related

python structs for dict of files

This may be a newb question, but I'm a bit of newb with python, so here's what I'm trying to do...
I am using python2.7
I would like to assign a file path as a string into a dict in functionA, and then call this dict in functionB.
I looked at C-like structures in Python to try and use structs with no luck, possibly from a lack of understanding... The below sample is an excerpt from the link.
I also took a look at What are metaclasses in Python?, but I'm not sure if I understand metaclasses either.
So, how would I call assigned parameters in functionaA, within frunctionB such as:
class cstruct:
path1 = ""
path2 = ""
path3 = ""
def functionA():
path_to_a_file1 = os.path.join("/some/path/", "filename1.txt")
path_to_a_file2 = os.path.join("/some/path/", "filename2.txt")
path_to_a_file3 = os.path.join("/some/path/", "filename3.txt")
obj = cstruct()
obj.path1 = path_to_a_file1
obj.path2 = path_to_a_file2
obj.path3 = path_to_a_file3
print("testing string here: ", obj.path1)
# returns the path correctly here
# this is where things fall apart and the print doesn't return the string that I've tested with print(type(obj.path))
def functionB():
obj = cstructs()
print(obj.path1)
print(obj.path2)
print(obj.path3)
print(type(obj.path))
# returns <type 'str'>, which is what i want, but no path
Am I passing the parameters properly for the paths? If not, could someone please let me know what would be the right way to pass the string to be consumed?
Thanks!
You need to do something like this:
class Paths:
def __init__(self, path1, path2, path3):
self.path1 = path1
self.path2 = path2
self.path3 = path3
def functionA():
path_to_a_file1 = os.path.join("/some/path/", "filename1.txt")
path_to_a_file2 = os.path.join("/some/path/", "filename2.txt")
path_to_a_file3 = os.path.join("/some/path/", "filename3.txt")
obj = Paths(path_to_a_file1, path_to_a_file2, path_to_a_file3)
return obj
def functionB(paths): # should take a parameter
# obj = cstructs() don't do this! This would create a *new empty object*
print(paths.path1)
print(paths.path2)
print(paths.path3)
print(type(paths.path))
paths = functionA()
functionB(paths) # pass the argument
In any case, you really should take the time to read the official tutorial on classes. And you really should be using Python 3, Python 2 is passed its end of life.

How do I run two or more methods in a class like a chain?

I'm trying to learn OOP but I'm getting very confused with how I'm supposed to run the methods or return values. In the following code I want to run read_chapters() first, then sendData() with some string content that comes from read_chapters(). Some of the solutions I found did not use __init__ but I want to use it (just to see/learn how i can use them).
How do I run them? Without using __init__, why do you only return 'self'?
import datetime
class PrinceMail:
def __init__(self):
self.date2 = datetime.date(2020, 2, 6)
self.date1 = datetime.date.today()
self.days = (self.date1 - self.date2).days
self.file = 'The_Name.txt'
self.chapter = '' # Not sure if it would be better if i initialize chapter here-
# or if i can just use a normal variable later
def read_chapters(self):
with open(self.file, 'r') as book:
content = book.readlines()
indexes = [x for x in range(len(content)) if 'CHAPTER' in content[x]]
indexes = indexes[self.days:]
heading = content[indexes[0]]
try:
for i in (content[indexes[0]:indexes[1]]):
self.chapter += i # can i use normal var and return that instead?
print(self.chapter)
except IndexError:
for i in (content[indexes[0]:]):
self.chapter += i
print(self.chapter)
return self????? # what am i supposed to return? i want to return chapter
# The print works here but returns nothing.
# sendData has to run after readChapters automatically
def sendData(self):
pass
#i want to get the chapter into this and do something with it
def run(self):
self.read_chapters().sendData()
# I tried this method but it doesn't work for sendData
# Is there anyother way to run the two methods?
obj = PrinceMail()
print(obj.run())
#This is kinda confusing as well
Chaining methods is just a way to shorten this code:
temp = self.read_chapters()
temp.sendData()
So, whatever is returned by read_chapters has to have the method sendData. You should put whatever you want to return in read_chapters in a field of the object itself (aka self) in order to use it after chaining.
First of all, __init__ has nothing to do with what you want to achieve here. You can consider it as a constructor for other languages, this is the first function that is called when you create an object of the class.
Now to answer your question, if I am correct you just want to use the output of read_chapters in sendData. One of the way you can do that is by making the read_chapters a private method (that is if you don't want it to use through the object) using __ in the starting of the name like __read_chapters then make a call to the function inside the sendData function.
Another point to consider here is, when you are using self and don't intend to use the function through the object you don't need to return anything. self assigns the value to the attribute of the current instance. So, you can leave the function read_chapters at self.chapter = i and access the same in sendData.
Ex -
def sendData(self):
print(self.chapter)
I'm not an expert but, the reason to return self is because it is the instance of the class you're working with and that's what allows you to chain methods.
For what you're trying to do, method chaining doesn't seem to be the best approach. You want to sendData() for each iteration of the loop in read_chapters()? (you have self.chapter = i which is always overwritten)
Instead, you can store the chapters in a list and send it after all the processing.
Also, and I don't know if this is a good practice but, you can have a getter to return the data if you want to do something different with (return self.chapter instead of self)
I'd change your code for:
import datetime
class PrinceMail:
def __init__(self):
self.date2 = datetime.date(2020, 2, 6)
self.date1 = datetime.date.today()
self.days = (self.date1 - self.date2).days
self.file = 'The_Name.txt'
self.chapter = []
def read_chapters(self):
with open(self.file, 'r') as book:
content = book.readlines()
indexes = [x for x in range(len(content)) if 'CHAPTER' in content[x]]
indexes = indexes[self.days:]
heading = content[indexes[0]]
try:
for i in (content[indexes[0]:indexes[1]]):
self.chapter.append(i)
except IndexError:
#not shure what you want to do here
for i in (content[indexes[0]:]):
self.chapter.append(i)
return self
# sendData has to run after readChapters automatically
def sendData(self):
pass
#do what ever with self.chapter
def get_raw_chapters(self):
return self.chapter
Also, check PEP 8 Style Guide for naming conventions (https://www.python.org/dev/peps/pep-0008/#function-and-variable-names)
More reading in
Method chaining - why is it a good practice, or not?
What __init__ and self do on Python?

How do I capture the function name with the class name right outside it?

I have developed a Tkinter application which will basically display the test functions inside a test file and the user can select the particular test functions and run pytest on it. It was working well so far as I had only test functions and no classes. Now, there are classes and functions inside it. How do I capture that those functions come inside that particular class? I thought of using regex but there might be functions outside the class too. So, I dont know how to solve this issue.
So far I have something like this:
Test file:
def test_x():
....
def test_y():
....
Source Code:
with open("{}.py".format(testFile), "r") as fp:
line = fp.readline()
while line:
line = fp.readline()
if ("#" not in line) and ("def" and "test_" in line):
x = line.split()[1].split('(')[0]
gFunctionList.append([testName, x])
Based on which all selected:
#var2State is the checkbutton states
for j in range(len(var2State)):
if var2State[j].get() == 1:
runString += "{}.py::{} ".format(gFunctionList[j][0],
gFunctionList[j][1])
else:
continue
if runString != "":
res = os.system("pytest " + runString)
From the above code, it will run: pytest testFile.py::test_x if test_x is selected.
Now if the test file is like this:
Class test_Abc():
def test_x():
....
def test_y():
....
def test_j():
....
Class test_Xyz():
def k():
....
def test_l():
....
Class test_Rst():
def test_k():
....
def ltest_():
....
Now, if test_l is selected, it should run: pytest testFile.py::test_Xyz::test_l.
But how do I get the test_Xyz above?
if test_j is selected, it should run: pytest testFile.py::test_j.
So, how do I capture the class name right outside a particular set of test functions and not capture if it's not inside the class?
I am not really that familiar with Tkinter or how things get selected, but this might point you in the right direction.
As the link I provided in the comments indicates, instances (i.e. classes) do not have names. If you want to give an instance a name, you just need to include it in the def __init__(self):. When any method (i.e. function) from test_ABC (which also inherits self) is called, you will always have access to self.name.
class test_Abc():
def __init__(self):
self.name = 'test_Abc'
def test_x(self):
return self.name
def test_y(self):
return self.name
abc = test_Abc()
a = abc.test_x()
print('pytest testFile.py::' + a + '::test_x')
which returns:
pytest testFile.py::test_Abc::test_x

Search for a string inside a text document

I'm new to python and was wondering what am i missing in my code.
I want to build a class that receives 3 letter airport destination and origin, and prints out if it's in the text file
I appreciate your help !
class departure:
def __init__(self, destfrom, destto):
self.destfrom = destfrom
self.destto = destto
def verdest(self,dest):
flag = 0
destinations = ["JFK","AMS"]
for i in destinations:
if i == dest:
flag = i
return flag
if verdest() in open('airportlist.txt').read():
print("true")
There are a few changes you need to make. if i == dest: is checking if JFK is equal to the file contents, you probably mean in. Then you have a class but you never initialize it.
class departure:
def __init__(self, destfrom, destto):
self.destfrom = destfrom
self.destto = destto
def verdest(self,dest):
flag = 0
destinations = ["JFK","AMS"]
for i in destinations:
if i in dest: # change to in
flag = i
return flag
d = departure(['BWI'],['AMS'])
f = open('airportlist.txt','r')
flag = d.verdest(f.read()) #find last airport that was in file, could modify this to return list
if flag:
print("true" + flag)
else:
print('false')
f.close() #close the file
read reads the lines of a file into a single string.
If you use readlines instead you will get a list of lines in the file.
Then you can see if an individual code is in these lines.
Without a class, like this:
def verdest(self, dest):
flag = 0 # note - not used!
destinations = open('airportlist.txt').readlines()
return dest in destinations
if verdest("LGW"):
print("true")
If you want to store the two airport names in the class and look them up in a file later one, save the three letter codes as you do, but pass the filename contents to the checking function?
class departure:
def __init__(self, destfrom, destto):
self.destfrom = destfrom
self.destto = destto
def verdest(self, destinations):
return self.destfrom in destinations and self.destto in destinations
Then make a class and use it:
places = departure("JFK","AMS")
#This makes your class, and remembers the variables in member variables
if places.verdest(open('airportlist.txt').readlines()):
#In this member function call, places remembers the member variable set up above
print("true")
Now, you could read the file in the __init__ method of the class, rather than every time you want to check.
You are missing an argument in verdest() function call.

Accessible variables at the root of a python script

I've declared a number of variables at the start of my script, as I'm using them in a number of different methods ("Functions" in python?). When I try to access them, I can't seem to get their value = or set them to another value for that matter. For example:
baseFile = open('C:/Users/<redacted>/Documents/python dev/ATM/Data.ICSF', 'a+')
secFile = open('C:/Users/<redacted>/Documents/python dev/ATM/security.ICSF', 'a+')
def usrInput(raw_input):
if raw_input == "99999":
self.close(True)
else:
identity = raw_input
def splitValues(source, string):
if source == "ident":
usrTitle = string.split('>')[1]
usrFN = string.split('>')[2]
usrLN = string.split('>')[3]
x = string.split('>')[4]
usrBal = Decimal(x)
usrBalDisplay = str(locale.currency(usrBal))
elif source == "sec":
usrPIN = string.split('>')[1]
pinAttempts = string.split('>')[2]
def openAccount(identity):
#read all the file first. it's f***ing heavy but it'll do here.
plString = baseFile.read()
xList = plString.split('|')
parm = str(identity)
for i in xList:
substr = i[0:4]
if parm == substr:
print "success"
usrString = str(i)
else:
lNumFunds = lNumFunds + 1
splitValues("ident", usrString)
When I place baseFile and secFile in the openAccount method, I can access the respective files as normal. However, when I place them at the root of the script, as in the example above, I can no longer access the file - although I can still "see" the variable.
Is there a reason to this? For reference, I am using Python 2.7.
methods ("Functions" in python?)
"function" when they "stand free"; "methods" when they are members of a class. So, functions in your case.
What you describe does definitely work in python. Hence, my diagnosis is that you already read something from the file elsewhere before you call openAccount, so that the read pointer is not at the beginning of the file.

Categories

Resources