Kivy - Passing variables on app startup from a file - python

I have a text file I am using as a calibration file for a rudder indicator I am making. (It stores the port and stbd limits and the center position)
I would like to call this file when the program is booted so it had the same calibration settings from previously.
I can store the 3 numbers as a str in a .txt file and know how to recall them as a list.
My thought is to run a function when the app starts defining each part of the list as a variable eg.
calibrationfile1 = open('calfile.txt','r')
lines = calibrationfile1.readlines()
calvalue1 = lines[0].replace(",","").replace("[","").replace("]","")
calvalue = calvalue1.split()
rudderlimits = calvalue
port_rudder_limit = rudderlimits[0]
stbd_rudder_limit = rudderlimits[1]
center_position = rudderlimits[2]
how do I do call this in a function at startup and make the variables available in another function I dont want to use 'global'?
I have already made a funciton that is a calibration that creates this calfile.txt and it works.
thanks for your help :)

you can load the file on the app on_start method
class YourApp(App):
def on_start(self):
self.calibration_data = your_file_loading_function() # returns a dict?
... # other places in your code
class Popcorn(Widget):
def on_callback(self):
port_rudder_limit = App.get_running_app().calibration_data['port_rudder_limit']
... # do something....
or from kv file
<MyWidget>:
port_rudder_limit: app.calibration_data['port_rudder_limit']

Related

why python get me this error: filenotfound

i have a irrational error,
code:
#====================================================#
#X Programming Language 2022(for Jadi) License: GPL #
#====================================================#
from os import system #importing system func. for cmd
code_location = "" #saving code location in this
code = "" #saving code in this
def main(): #main func.
code_location = input() #get code location from user
code = get_code() #cal get_code and save res to code var
print(code) #print code
end() #calling end
def get_code(): #get_code func. for getting code from file
code_file = open(code_location, 'r') #openning file with method read and saving to code_file
res = code_file.readlines() #saving the content from file to res
return res #returning res
def compiler(): #compiler func. for compiling code
pass
def end(): #when program end...
input("Press Enter to Countinue...")
if __name__ == "__main__":
main()
and this is code directory:
enter image description here
running:
enter image description here
Short answer: Your two code_location variables are not the same thing.
Variable scopes
Variables have a property called a scope, which is essentially which context they belong to. Unless specified otherwise, variables within a function exist only within that function. Consider:
a = 0
def set_a():
a = 1
set_a()
print(a)
This will print 0. This is because the a variable within the function set_a is actually a different variable to the a defined in line 1. Although they have the same name, they point to different places in memory.
Solutions
There are a few ways to do this:
Defining scope
Either, you can set the scope of a within the function to global (instead of local). What this does is now, instead of a within the function pointing to a different memory location, it points to the same memory location as a outside the variable. This is done like so:
a = 0
def set_a():
global a
a = 1
set_a()
print(a)
In this case, a will be set to 1, and "1" will be printed
Passing as an argument
Another way to do this, and may be more relevant in your circumstance, is to pass the value as a variable to the function. In your case, you are using code_location as the file path, so therefore what you want to pass code_location into the function. You would then have to define your function like this:
def get_code(code_location):
and call the function (from your main function) like this:
code = get_code(code_location)
Notes
When operating on files, it is best practice to use a with block. This handles closing your file when you are done with it, and can prevent corruption of files in the rare case that something goes wrong with your code. This can be done like this:
with open(code_location, 'r') as code_file:
res = code_file.readlines()
return res
Python global variables are read-only in local scopes (e.g. your function's scope) by default.
So in the line code_location = input() you are essentially creating a new new local variable of the same name and assigning the input to it.
In order to write to your global variable instead, you first have to declare your intention:
def main(): #main func.
global code_location # DECLARE WRITE INTENTION FOR GLOBAL
code_location = input() #get code location from user
code = get_code() #cal get_code and save res to code var
print(code) #print code
end() #calling end
You don't have to do the same thing in get_code() since you are only reading from code_location there.
PS:
As was alluded to in the comment, it's good practice to close opened files after you've finished with them:
def get_code(): #get_code func. for getting code from file
code_file = open(code_location, 'r') #openning file with method read and saving to code_file
res = code_file.readlines() #saving the content from file to res
code_file.close() # CLOSE FILE
return res #returning res
Or have it done automatically by a context manager:
def get_code(): #get_code func. for getting code from file
with open(code_location, 'r') as code_file: #openning file with method read and saving to code_file
res = code_file.readlines() #saving the content from file to res
return res #returning res

How to solve class objecto has no atribute

beginner Python user here.
So, I´m trying to make a program that orders the files of my (many) Downloads folder.
I made a class object to work with the many folders:
class cContenedora:
def __int__(self, nCarp, dCarp): #nCarp Stands is the file name and dCarp Stands for file directory.
self.nCarp = nCarp
self.dCarp = dCarp
So, y wrote a instance like this:
Download = cContenedora()
Download.nCarp = "Downloads/"
#The side bar is for making a path to move my archives from with shutil.move(path, dest)
Download.dCarp = "/Users/MyName/Download/"
#This is for searching the folder with os.listdir(Something.dCarp)
Then, I wrote my function, and it goes something like this:
def ordenador(carpetaContenedora, formato, directorioFinal): #carpetaContenedora is a Download Folder
carpetaContenedora = cContenedora() #carpetaContenedora one of the class objects
dirCCont = os.listdir(carpetaContenedora.dCarp) #The to directory is carpetaContenedora.cCarp
for a in dirCCont:
if a.endswith(formato):
path = "/Users/Aurelio Induni/" + carpetaContenedora().nCarp + a
try:
shutil.move(path, directorioFinal)
print(Fore.GREEN + a + "fue movido exitosamente.")
except:
print(Fore.RED + "Error con el archivo" + a)
pass
for trys in range(len(listaCarpetasDestino)-1): #Is a list full of directories.
for container in listaCarpetasFuente: #A short list of all my Downloads Folder.
for formatx in listaFormatos: #listaFormatos is a list ful of format extensions like ".pdf"
#try: #I disabled this to see the error istead of "Error Total"
ordenador(container, formatx, listaCarpetasDestino[trys])
#except:
#print(Fore.RED + "Error Total") #I disabled this to see the error.
But every time I run it I get the following:
AttributeError: 'cContenedora' object has no attribute 'dCarp'
It says the error is in line 47 (the one with the os.listdir(carpetaContenedora.dCarp))
I´m sure is something small. Python is so amazing, but it also can be so frustrating not knowing what´s wrong.
There is a spelling mistake in the initialization of your instance. It should be "init" instead of "int".
In the class cContenedora, the function should be
class cContenedora:
def __init__(self, nCarp, dCarp):
self.nCarp = nCarp
self.dCarp = dCarp
Additionally, When you are passing in the parameter. Make sure to pass in both of the parameters in the line with Value.
CContenedora(nCarp="something",dCarp="something")
Your class initializer, i.e., __init__() function has 2 parameters nCarp and dCarp but when you are actually creating the object there are no parameters passed.
Your function ordenador takes the first parameter as carpetaContenedora, on the first line same variable is assigned a new object of cContenedora, at this line the original values you passed are lost forever.
This could be the reason it is giving for the error.
Refer this link for more details on how to create classes and instantiate the object.

Instance attributes in Python and __init__ method

I am trying to writing a program to read a configuration file but while testing it am having this error:
self.connection_attempts = self.config_file.get('CONNECTION_ATTEMPTS', 'TIME')
AttributeError: 'list' object has no attribute 'get'
I ma pretty sure it is something I don't get, but it is few hours I am trying to understand where the problem is.
My __init__ method looks like this:
import simpleconfigparser
class ReportGenerator:
def __init__(self):
self.config_parser = simpleconfigparser.configparser()
self.config_file = config_parser.read('config.ini')
self.connection_attempts = config_file.get('CONNECTION_ATTEMPTS', 'TIME')
self.connection_timeout = config_file.get('CONNECTION_TIMEOUT', 'TIMEOUT')
self.report_destination_path = config_file.get('REPORT', 'REPORT_PATH')
This code uses the SimpleConfigParser package.
You want config_parser.get() not config_file.get(). config_parser.read() simply returns the list of config files successfully read after populating the config object. (Usually it is called config or cfg, not config_parser).
This list (config_file) serves no purpose in your code and you might as well not capture it at all.
from simpleconfigparser import simpleconfigparser
TIME = 5
TIMEOUT = 10
REPORT_PATH = '/tmp/'
class ReportGenerator:
def __init__(self):
self.config = simpleconfigparser()
config.read('config.ini')
self.connection_attempts = config.get('CONNECTION_ATTEMPTS', TIME)
self.connection_timeout = config.get('CONNECTION_TIMEOUT', TIMEOUT)
self.report_destination_path = config.get('REPORT', REPORT_PATH)
My guess would also be, that you use the default value in .get() the wrong way, but i cannot be certain with the information you have given.

Python, returning data collected in npyscreen

So I'm creating a basic TUI for a script I created. The goal is to collect several variables that include paths to directories and files. What I'm not sure about is once I've created the visual aspect of it, how to get those pieces of information to interact with other parts of the code.
Below is what I have so far in terms of the visual portion (the other part is about 500 lines), and honestly I'm at a loss on how to even print any of the variables set under the class and any pointers would be greatly appreciated.
#!/usr/bin/env python
# encoding: utf-8
import npyscreen
class PlistCreator(npyscreen.NPSApp):
def main(self):
screen = npyscreen.Form(name="Welcome to Nicks Playlist Creator!")
plistName = screen.add(npyscreen.TitleText, name="Playlist Name:" )
csvPath = screen.add(npyscreen.TitleFilenameCombo, name="CSV Schedule:")
toaPath = screen.add(npyscreen.TitleFilenameCombo, name="Path to ToA Video Folder:", use_two_lines=True)
outputPath = screen.add(npyscreen.TitleFilenameCombo, name = "Output Folder:", use_two_lines=True)
dateOfAir = screen.add(npyscreen.TitleDateCombo, name="Date of Air:")
timeOfStart = screen.add(npyscreen.TitleText, name="Time of Air (TC):")
screen.edit()
if __name__ == "__main__":
App = PlistCreator()
App.run()
You can get the value of any form object using the dit notation.
plistName = screen.add(npyscreen.TitleText, name="Playlist Name:" )
playlist_name = self.screen.plistName.value
etc. Note there are no parentheses after value. Once you have it in a variable, you can build another method in the class to handle the information.

How do I access variables/objects in my whole application?

I'm developping a PyQT application. This application is able to load some data from a database, and then do various analysis on these data. All of this works. But as the analyses can be quite complicated, and as a will not be the only user, I had to develop a system with users defined script.
Basically, there's a text editor where the user can program his own small python script (with functions). Then the user can save the script or execute it, by loading the file as a module (within the application).
Here, there a simplified version of my application.
The core of the application is in My_apps.py
and the plugins are here in the same folder i.e. Plugin_A.py
this is the code of My_apps.py:
import sys,os
class Analysis(object):
def __init__(self):
print "I'm the core of the application, I do some analysis etc..."
def Analyze_Stuff(self):
self.Amplitudes_1=[1,2,3,1,2,3]
class Plugins(object):
def __init__(self):
newpath = "C:\Users\Antoine.Valera.NEUROSECRETION\Desktop\Model" #where the file is
sys.path.append(newpath)
Plugin_List=[]
for module in os.listdir(newpath):
if os.path.splitext(module)[1] == ".py":
module=module.replace(".py","")
Plugin_List.append(module)
for plugin in Plugin_List:
a=__import__(plugin)
setattr(self,plugin,a)
def Execute_a_Plugin(self):
Plugins.Plugin_A.External_Function(self)
if __name__ == "__main__":
Analysis=Analysis()
Plugins=Plugins()
Plugins.Execute_a_Plugin()
and here is an example of the code of Plugin_A.py
def External_Function(self):
Analysis.Analyze_Stuff()
print Analysis.Amplitudes_1
why do I get :
Traceback (most recent call last):
File "C:\Users\Antoine.Valera.NEUROSECRETION\Desktop\Model\My_Apps.py", line 46, in <module>
Plugins.Execute_a_Plugin()
File "C:\Users\Antoine.Valera.NEUROSECRETION\Desktop\Model\My_Apps.py", line 37, in Execute_a_Plugin
Plugins.Plugin_A.External_Function(self)
File "C:\Users\Antoine.Valera.NEUROSECRETION\Desktop\Model\Plugin_A.py", line 8, in External_Function
Analysis.Analyze_Stuff()
NameError: global name 'Analysis' is not defined
but if I add the 2 lines following lines instead of Plugins.Execute_a_Plugin()
Analysis.Analyze_Stuff()
print Analysis.Amplitudes_1
then, it works.
How could I indicate to every dynamically loaded plugins that he has to use the variables/objects already existing in Analysis? Why can't I print Analysis.Amplitudes_1 from within the plugin?
Thank you!!
The error message seems perfectly clear: the name "Analysis" doesn't exist in the namespace of the Plugin_A module you imported, and so External_Function cannot access it.
When you import the Plugin_A module, it doesn't get access to the names in the namespace of the importing module, My_apps. So it cannot "see" the instance of the Analysis class that you created there.
A simple solution to this is to change the signature of External_Function (and other related functions), so that it can take an instance of the Analysis class:
Plugin_A.py:
def External_Function(self, analysis):
analysis.Analyze_Stuff()
print analysis.Amplitudes_1
My_apps.py:
...
def Execute_a_Plugin(self):
plugins.Plugin_A.External_Function(self, analysis)
if __name__ == "__main__":
analysis = Analysis()
plugins = Plugins()
plugins.Execute_a_Plugin()
Note that I have altered the naming so that the instance names don't shadow the class names.
You have to import your module. Add the following on top of Plugin_A.py
from My_apps import Analysis
A = Analysis()
A.Analyze_Stuff()
print A.Amplitudes_1

Categories