Why are my class functions executed when importing the class? - python-3.x

it's probably a very basic question but I was unable to find an answer that I could thoroughly understand.
In my main program main_program.py, I'm importing a class that itself imports another class:
in main_program.py:
from createTest import *
in createTest.py:
print("TEST")
from recordRecallQused import *
print("TEST")
now in recordRecallQused:
class recordRecallQused:
def __init__(self, path):
self.path = path
try:
with open(self.path, 'r',newline = '') as question_used:
question_used.closed
except IOError:
#if file doesnt exist
print("the file doesn't exist")
with open(self.path, 'w',newline = '') as question_used:
question_used.closed
def recallQused(self):
list_Qused = []
print("I'm being executed")
with open(self.path, 'r',newline = '') as question_used:
questionused = csv.reader(question_used)
for item in questionused:
if len(item)>0:
list_Qused.append(item[0])
question_used.closed
return list_Qused
What I obtain in the kernel:
>TEST
>I'm being executed
>TEST
so functions inside the class are executed even though they are not called, but I have read that it's "normal", "def" are no statements but "live" things.
Still, I have tried something much more simple:
in main_program_TEST.py
from class1 import *
a = class1()
in class1.py:
print("t")
from class2 import *
print("t")
class class1:
def __init__(self):
pass
def message(self):
print("prout")
in class2.py:
class class2:
def __init__(self):
pass
def message(self):
print("prout2")
When executing main_program_TEST.py the kernel displays
>t
>t
so this time the functions in class2.py have not been executed, otherwise the kernel would show instead:
>t
>prout2
>t
I really wonder why.

Stephen Rauch you are right, part of my code in recordRecallQused.py was calling the function.
"""#load all list
print("loading questions info")
# questions info: answers, category
list_AllQ = []
with open('questionsInfoTo130.csv', newline = '') as csvfile:
questionsInfo = csv.reader(csvfile)
# loop over the questions information rows
for (i,row) in enumerate(questionsInfo):
if(i!=0):
list_AllQ.append(row)
csvfile.close()
path = 'question_used.csv'"""
list_AllQ = [[0,1,2,1,"que"],[0,1,2,2,"que"],[0,1,2,3,"que"],[0,1,2,4,"que"],[0,1,2,55,"que"],[0,1,2,6,"que"],[0,1,2,7,"que"],[0,1,2,8,"que"],[0,1,2,9,"que"]]
a = recordRecallQused('question_used.csv')
list_Qused = a.recallQused()
list_avQ = a.createListavQ(list_Qused, list_AllQ)
list_Qtest = a.createListQtest(list_avQ)
a.recordQused(list_Qtest)

Related

Unit test initializes class without calling parameters, how do I get the parameters into the class?

So I'm working with Linked Lists in python, and the UnitTest our professor gave us calls C = Course(), but asserts the values after. This is what they use to grade, but I can't find a way to call the class then wait for the variables, and apply them to the class without parameters so it doesn't crash. Thoughts? Am I missing something obvious?
Tried to only include the relevant code. If people need full code for clarification or just for kicks/giggles let me know.
import courselist
import course
def load_data(data):
with open(data) as f:
for line in f:
dline = line.strip().split(",")
C = course.Course(dline[0],dline[1],dline[2],dline[3])
course_list = courselist.CourseList()
course_list.insert(C)
return course_list
def main():
data = "data.txt"
full_list = load_data(data)
print(full_list.__str__())
main()
class Course:
def __init__(self, c_num, c_name, c_hour, c_grade):
self.c_num = c_num
self.c_name = c_name
self.c_hour = c_hour
self.c_grade = c_grade
self.next = None
class TestEmptyCourse(unittest.TestCase):
def test_course_creation(self):
# make sure that an empty course is correct
c = Course()
self.assertEqual(c.name(), "")
self.assertEqual(c.number(), 0)
self.assertEqual(c.credit_hr(), 0.0)
self.assertEqual(c.grade(), 0.0)
self.assertEqual(c.next, None)
I was missing something obvious... Hangs head in shame For those interested here's how to fix it. It's always when you ask for help that you get it just in time to look like an idiot haha. Thanks to those to checked it out. If someone has an alternate solution I'll be sure to upvote you
class Course:
def __init__(self, num=0, cname="", c_hr=0.0, cgrade=0.0, next=None):
self.num = num
self.cname = cname
self.c_hr = c_hr
self.cgrade = cgrade
self.next = None
def number(self):
return int(self.num)
def name(self):
return str(self.cname)
def credit_hr(self):
return self.c_hr
def grade(self):
return self.cgrade
def __str__(self):
return f"cs{self.num} {self.cname} Grade:{self.cgrade} Credit Hours: {self.c_hr}"

Can we skip explicit object creation in Python

When I do not crate object for CP class, the operations are not captured. I am referring to the code below, Can somebody help me understand why we need obj creation in this case
from abc import ABC, abstractmethod
class P(ABC):
def __init__(self):
super().__init__()
self._pre_map = {}
self._pre_order = []
def set_pre(self, tag_value):
index = len(self._pre_map)
print(index)
self._pre_map[index] = tag_value
self._pre_order.append(index)
def execute(self):
pass
class CP(P):
def __init__(self):
super().__init__()
def execute(self):
self.prnt()
def prnt(self):
print (self._pre_map)
print (self._pre_order)
#Working
print("\n++++++++ working")
obj = CP()
obj.set_pre("test string added")
obj.execute()
#Not Working
print("\n+++++++ not working")
CP().set_pre("test string added")
CP().execute()
It produces,
++++++++working
0
{0: 'test string added'}
[0]
+++++++not working
0
{}
[]
When you call the class the second time with CP.execute(), you have created a completely new instance of the CP class. It is not going to have the text string you specified.
If you actually wanted it to print the values like the working one you can make the functions return self after each call in the P class. If you did that you could do something like this.
from abc import ABC, abstractmethod
class P(ABC):
def __init__(self):
super().__init__()
self._pre_map = {}
self._pre_order = []
def set_pre(self, tag_value):
index = len(self._pre_map)
print(index)
self._pre_map[index] = tag_value
self._pre_order.append(index)
##need to return self here
return self
def execute(self):
pass
class CP(P):
def __init__(self):
super().__init__()
def execute(self):
self.prnt()
def prnt(self):
print (self._pre_map)
print (self._pre_order)
#Working
print("\n++++++++ working")
obj = CP()
obj.set_pre("test string added")
obj.execute()
#Not Working
print("\n+++++++ not working: but now working after returning self in the P class")
CP().set_pre("test string added").execute()
++++++++ working
0
{0: 'test string added'}
[0]
+++++++ not working: but now working after returning self in the P class
0
{0: 'test string added'}
[0]
This would print the result you want.
The reason for the difference is the fact that in the first one, you are creating an instance, and using that instance the whole way through, whereas in the second one, you are using two different instances of your class.
The two different instances cannot share their attributes, so you are unable to recall what happened. If you really don't want to use a dedicated variable, change your P class to look like this:
class P(ABC):
...
def set_pre(self, tag_value):
index = len(self._pre_map)
print(index)
self._pre_map[index] = tag_value
self._pre_order.append(index)
return self
...
And use CP().set_pre("test string added").execute()

unable to access objects of one class in another class in python

i am trying to access the functions of class Config in another class. i am unable to do it. This code follows MVC structure.
i have tried putting that piece of code in another file and importing it and tried to use. No success.
class Config:
def __init__(self):
try:
self.Data_load = ""
self.MongoDB_Host = ""
except:
print("Not found")
config = configparser.ConfigParser()
config.read('Config.ini')
def getMongoDB_Host(self):
return self.MongoDB_Host
def getMongoDB_Port(self):
return self.MongoDB_Port
class PredictionController(object):
def __init__(self):
self.path = config.DEFAULT['pickle_path']
def dev_train(self,df_dev):
self.df_dev=df_dev
Config_Obj = Config()
print(Config_obj.getMongoDB_Host()) #This is giving output : response 51 bytes [200 OK]

integrate tkinter whit Sqlite3

I'm looking for a suggestion: I have a Module called main.py where I write all GUI code.In order to avoid repeating all the sqlite queries, I have written all those queries un other Module called admin.py.
So there is this code in main.py:
B = tk.Entry()
B1= B.get()
In admin.py, I have the method validate.That is supposed take the B variable to make the query.Something like:
//Here the function will query the db to see if the value in B1.get() exist//
class myclass()
def validate(a):
....SELECT FROM table WHERE col_val = (a)
And here is the trouble: I don't know how to pass the value of B1 to the validate method. Could be something like this:
s= myclass()
s.validate(B1)
maybe?
I've done but i think could be better.Here is the way i did. Sorry for question i wasn't in the computer.
There is the module main.py
import tkinter as tk
import ingreso
from tkinter import messagebox
from ingreso import myclass
import sqlite3
def __init__(self):
tk.Tk.__init__(self)
frame = tk.Frame(self,width=380, height=420, bg="white", colormap="new")
self.fi = tk.Entry(frame)
self.fi.pack()
self.dni = tk.Entry(frame)
self.dni.pack()
frame.pack()
self.hi = tk.Button(self,text="guardar", command= self.validate)
self.hi.pack()
def validate(self):
messagebox.showwarning(title="validador",message="Se procedera a validar los campos")
fi= self.fi.get() #That is that i pass as class argument
dni= self.dni.get()
if len(fi)== 0 or len(dni)==0:
tk.messagebox.showwarning(message="campos requeridos")
else:
query = myclass(fi, dni) #Create the objet at instance of class
val = query.validar() #Determine if the object exist or not
There is the module ingreso.py:
class myclass():
def __init__(self, a= " ", b= " "): #There is the attributes of the class
self.db = db
self.a = a
self.b = b
def validar(self): # here i determine if the objet exist or not
fi = self.a
dni = self.b
conn = sqlite3.connect('ecina.db')
c = conn.cursor()
c.execute('''SELECT COUNT(*) FROM admision WHERE fi = (?) AND dni =(?)''', (fi, dni))
r = c.fetchone()
number_of_rows=r[0]
return number_of_rows
It's works but any suggestion or correction will be very appreciate.Thanks Alot.

PyQt ToolTip for QTreeView

Please axplain how to enable and show a tooltip for each item in QTreeView. I found a sample of code class TreeModel(QAbstractItemModel) but due to my beginner's level I can't understand how to apply it to my needs.
Data for tooltip should be taken from value of key "note" in dictionary data_for_tree.
#!/usr/bin/env python -tt
# -*- coding: utf-8 -*-
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
reload(sys)
sys.setdefaultencoding('utf8')
data_for_tree = {"tomato":{"color":"red","ammount":"10", "note":"a note for tomato"},"banana":{"color":"yellow","ammount":"1", "note":"b note for banana"}, "some fruit":{"color":"unknown","ammount":"100", "note":"some text"}}
class TreeModel(QAbstractItemModel):
def data(self, index, role=Qt.DisplayRole):
#...
if role == Qt.ToolTipRole:
return 'ToolTip'
def flags(self, index):
if not index.isValid():
return Qt.NoItemFlags # 0
return Qt.ItemIsSelectable # or Qt.ItemIsEnabled
class ProxyModel(QSortFilterProxyModel):
def __init__(self, parent=None):
super(ProxyModel, self).__init__(parent)
def lessThan(self, left, right):
leftData = self.sourceModel().data(left)
rightData = self.sourceModel().data(right)
try:
return float(leftData) < float(rightData)
except ValueError:
return leftData < rightData
class MainFrame(QWidget):
def __init__(self):
QWidget.__init__(self)
self.MyTreeView = QTreeView()
self.MyTreeViewModel = QStandardItemModel()
self.MyTreeView.setModel(self.MyTreeViewModel)
self.most_used_cat_header = ['Name', "ammount", "color"]
self.MyTreeViewModel.setHorizontalHeaderLabels(self.most_used_cat_header)
self.MyTreeView.setSortingEnabled(True)
self.MyTreeView_Fill()
MainWindow = QHBoxLayout(self)
MainWindow.addWidget(self.MyTreeView)
self.setLayout(MainWindow)
def MyTreeView_Fill(self):
for k in data_for_tree:
name = QStandardItem(k)
ammount = QStandardItem(data_for_tree[k]["ammount"])
note = QStandardItem(data_for_tree[k]["color"])
tooltip = data_for_tree[k]["note"]
item = (name, ammount, note)
self.MyTreeViewModel.appendRow(item)
self.MyTreeView.sortByColumn(1, Qt.DescendingOrder)
proxyModel = ProxyModel(self)
proxyModel.setSourceModel(self.MyTreeViewModel)
self.MyTreeView.setModel(proxyModel)
c = 0
while c < len(self.most_used_cat_header):
self.MyTreeView.resizeColumnToContents(c)
c=c+1
if __name__ == "__main__":
app = QApplication(sys.argv)
main = MainFrame()
main.show()
main.move(app.desktop().screen().rect().center() - main.rect().center())
sys.exit(app.exec_())
As you are using the QStandardItem and QStandardItemModel classes (which is what I would recommend!) you don't need to bother with the TreeModel class you have found. Creating your own model is rarely necessary, but for some reason tutorials often encourage you to do so. If you find something encouraging you to subclass QAbstractItemModel, I suggest you check on stack overflow first to see if there is a simpler way to do it! In this case, there is a very simple way to add your tooltips.
If you look at the C++ documentation (which I often find more useful than the PyQt documentation for finding out what methods are available), you will see that QStandardItem has a method called setToolTip().
So all you need to do is call this method on each of the items you add to the model. For example, inside the loop in the MyTreeView_Fill method:
name = QStandardItem(k)
ammount = QStandardItem(data_for_tree[k]["ammount"])
note = QStandardItem(data_for_tree[k]["color"])
tooltip = data_for_tree[k]["note"]
name.setToolTip(tooltip)
ammount.setToolTip(tooltip)
note.setToolTip(tooltip)
Here I've set the tooltip to be the same for every cell in the row (name, amount and note) but you could easily change this to have a different tooltip for one of the cells (hopefully it is obvious how to do that)

Resources