Python : Switching between different .py files with import files - python

I'm making a car parking system and I have some problems.
So the main thing is that I have 3 different py files, and all of them have different functions. For example I use Programa.py to ask users what they would like to do and some other functions. I use GETDATA.py to get rows from PostgreSQL server and then to pay for the parking charges.
And last of all I have REGISTRATION.py to Register car numbers to parking and insert them to SQL Database.
So the main problem is that after the "What would you like to do?" menu from Programa.py I use if statement, which imports other .py files to make their job done. Here's the code of If statement in Programa.py:
while Pasirinkimas:
try:
Registration_Or_Pay = int(input("~ What would you like to do?\n1.Register a car\n2.Pay for parking\n"))
if int(Registration_Or_Pay == 1):
import REGISTRATION
break
elif int(Registration_Or_Pay == 2):
import GETDATA
break
except ValueError:
print("NOT A NUMBER!")
After imported GETDATA.py Let's say I paid for parking and now I have to return to Programa.py to keep the program running and performing other parking operations as number registrations again.
And the problem is that after importing the Programa.py from GETDATA.py It launches, but after picking a number, to register a number program closes.
This is some lines of GETDATA.py file which I imported from main system .py file, which is called "Programa", you can see it at the end I'm trying to import it again to always keep the program running and to return to main script which asks what you would like to do.
finally:
#closing database connection.
if(connection):
cursor.close()
connection.close()
print("PostgreSQL connection is closed")
with open (Logs, mode='a',encoding='utf-8') as logwrite:
Time = datetime.datetime.now()
logwrite.writelines("\n {} Record SELECTED SUCCESSFULLY FROM Vartotojai DB. CARNUM {} REG_TIME: {} PARKING TIME: {} PRICE : {} STATUS : {}".format(Time.strftime("%Y-%m-%d %H:%M:%S"), car_numb, Laikas_ISDB, total_hours, total_charges, Time ))
logwrite.close()
time.sleep(2) # 2MINUTES 2 PAY.
os.system('cls')
import Programa # Return to program
I was talking with my friend who is good at python, he mentioned that I shouldn't use imports like this, because the import runs once in runtime. only first import directive takes effect. So my question would be How should I switch between these functions?

The last word in your question is actually what you should google for :).
Read something about functions. You put the code of the files you want to import into functions. Then you import all files you need at the beginning of your script and when you want to run the code you call the function its in.

Related

How to execute a program from another program?

Is there a way to make a program which executes other programs?
I was creating a project for school then I had an idea of creating a main program which will run different program according to my choice.
I am using VS code and I created 2 programs in same folder(Here is the screenshot in case you are confused):
Here as you can see I have 2 programs(one is rockpaper.py and other is pass.py) inside of a folder named (ROCKPAPER) is there a way I can run both of these program by making another program inside of this same folder(ROCKPAPER)????
Is there a module for this?
The best practice is to import the two programs in a 3rd one like
import pass
import rockpaper
which will execute those codes.
No module is needed, this is basic functionality and you can simply import your sub-scripts into the main script.
import rockpaper
import pass
to run them, simply write
rockpaper
pass
rock.py
def stone():
return ('This is rock')
paper.py
Note here I have imported rock and assigned rock's result to a variable
import rock
def papyrus():
return ("This is paper")
scissors.py
Note here, I got rock and paper imported and their return values are being printed from this file.
import rock
import paper
def sharp():
rocke = rock.stone()
papery = paper.papyrus()
print(f"{rocke} {papery} But I am a scissors")
if __name__ == "__main__":
sharp()
Output:
This is rock This is paper But I am a scissors
Process finished with exit code 0
You should really be studying these basics though.
Here's a short "driver" program you can put in the same folder as the others. What it does is create a menu of all the other Python script files it finds in the same folder as itself and asks the user to pick one to run. If the user enters number of one of those listed, it then runs that script and quits (otherwise it repeats the question).
It uses the subprocess module to execute the chosen script.
from pathlib import Path
import subprocess
import sys
filepath = Path(__file__)
current_folder = filepath.parent
this_script = filepath.name
print(f'{this_script=}')
print(f'{current_folder=}')
scripts = sorted(script for script in current_folder.glob('*.py') if script != filepath)
menu = [script.stem for script in scripts]
print('Available programs:')
for i, script in enumerate(menu, start=1):
print(f' {i:2d}. {script}')
while True:
choice = input('Which program would you like to run (or 0 to quit)? ')
try:
choice = int(choice)
except ValueError:
print("Sorry, did not understand that.")
continue
if choice in range(len(menu)+1):
break
else:
print("Sorry, that is not a valid response.")
continue
if choice:
print(f'Running program {menu[choice-1]}')
subprocess.run([sys.executable, f'{scripts[choice-1]}'])
It's actually pretty simple!
import os
os.system("python anotherProgram.py")
Essentially, you're giving it a shell command.

Using Rainmeter with Python

So I have designed a layout in Rainmeter which serves as a GUI for my Voice Assistant program. Now, I want to integrate the running of Rainmeter with Python. For example, if an user already has a Rainmeter layout loaded in his/her system, then running my script will automatically override his/her layout and activate my Layout unless he/she manually changes it back to his/her own layout. This process would continue whenever my script is run. It basically goes like this: The user runs the script, it checks whether any other skin is loaded or not (Assuming that Rainmeter is installed on the system). If any other skin is loaded, it overrides the skin with my one else it bypasses the override function and directly loads my skin.
I have no idea on how to achieve this thing. I have successfully written the lines to start and exit rainmeter with python but I don't know anything about how to load the layouts! Please help!
Here is the script I have written to start and exit Rainmeter:
import os
trigger = input()
if trigger == "y":
try:
os.startfile("C:\Program Files\Rainmeter\Rainmeter.exe")
print("Rainmeter started successfully")
except:
print("There was an error")
trigger = input()
if trigger == "exit":
try:
os.system("taskkill /f /im Rainmeter.exe")
print("Rainmeter closed successfully")
except:
print("There was an error")
You can use the following code to load a Rainmeter Layout:
import subprocess
subprocess.call(["C:\Program Files\Rainmeter\Rainmeter.exe", "!LoadLayout", "abcd"])
Here we are using rainmeter bangs to load the layout. Change abcd with name of your layout.

Python3: print statement of a variable leads to a different output

I write a Python script to manage my account on a webpage automatically.
Code Description:
The script has a while loop and at the end of the loop, it waits 12 hours before starting again.
Before the while loop starts, it's logging in to my account, and when entering the while loop, it checks if I'm still logged in. If not, it's logging in to my account again.
Problem:
After re-entering the while loop (first time everything goes fine), the script does only work, when print("Name is:") and print(name) is at the very beginning. I tested it several times and maybe it is just a bug/glitch, which was just unlucky to be caused only when the print statements aren't there, but this is very confusing me right now, how those print statements fixed my issue. I would like to know, what is or could causing the issue and how do I have to solve it properly?
Some side info:
The webpage is saving the login credentials through session cookies with a lifetime of ~6 hours. So after re-entering the script loop again, I'm not logged in for sure. If I'm reducing the wait time to 30 minutes instead of 12 hours, the script works also without the print statements.
General notes:
The script is running through nohup on my Raspberry Pi 3
Python version is 3.7.3
Code related notes:
I'm using the post method from requests to log in to my account
For checking, if I'm still logged in, I'm using beautifulSoup4
The following code is abbreviated and in a very basic shape.
"account" is an instance of a self-made class. When instantiating, it is log in itself with arguments, if given
This is the core code:
import time
import requests
from account import Account # costum made class
from bs4 import BeautifulSoup
# login credentials
name = "lol" # I replaced them with placeholders
pw = "lol"
account = Account(name, pw) # instantiating an account class and log in itself with given arguments
while True: # script loop
print("name is:") # Without those both print statements,
print(name) # the code won't work
if not account.stillAlive(): # if not signed in anymore ...
account.login(name, pw) # ... sign in again
account.doStuff() # Do the automating stuff
time.sleep(43200) # Wait 12 hours, before entering the while loop again
This is the doStuff() method from the Account class:
def doStuff(self):
html = requests.get("example.com").text # Note: example.com is only for demonstration purpose only
crawler = BeautifulSoup(html, "lxml")
lol = crawler.find("input", attrs={"name": "Submit2"}).get("value")
# ...
Error message:
So, if I'm executing the program without the print statements, I'm getting this error:
lol = crawler.find("input", attrs={"name": "Submit2"}).get("value")
AttributeError: 'NoneType' object has no attribute 'get'
This does not occur when executing with the print statements. With the print statements, the code runs fine.
My guess
My guess is, what the memory management of Python is deleting the name variable. When entering the script loop in the first time, I'm already logged in and therefore it is skipping the account.login(name, pw) part. Since this is the only part, where name is continued to be, maybe Python is interpreting this as dead code after too many time has passed without the line to be executed, and don't see the reason to keep the name/pw variable and deletes them. Still, I'm just an amateur and I don't have any expertise in this segment.
Side notes:
This is my first question I'm submitting, if I forgot or did something wrong, pls tell me.
I already searched for this problem, but I didn't find anything similar. Maybe I just searched badly, but I searched for a few hours now. If so, I apologize. (I had to wait for every test 12 hours and since I tried it several times, you can tell, I had some time available to search)

Data-logging from an i2c-connected Atlas Scientific Sensor to a CSV file

I am relatively new to Python, and programming as a whole. I am progressively getting the hang of it, however I have been stumped as of late in regards to one of my latest projects. I have a set of Atlas Scientific EZO circuits w/ their corresponding sensors hooked up to my Raspberry Pi 3. I can run the i2c script fine, and the majority of the code makes sense to me. However, I would like to pull data from the sensors and log it with a time stamp in a CSV file, taking data points in timed intervals. I am not quite sure how to pull the data from the sensor, and put it into a CSV. Making CSVs in Python is fairly simple, as is filling them with data, but I cannot seem to understand how I would make the data that goes into the CSV the same as what is displayed in the terminal when one runs the Poll function. Attached is the i2c sample code from Atlas' website. I have annotated it a bit more so as to help me understand it better.
I have already attempted to make sense of the poll function, but am confused in regards to the self.file_write and self.file_read methods used throughout the code. I do believe they would be of use in this instance but I am generally stumped in terms of implementation. Below you will find a link to the Python script (i2c.py) written by Atlas Scientific
https://github.com/AtlasScientific/Raspberry-Pi-sample-code/blob/master/i2c.py
I'm guessing by "the polling function" you are referring to this section of the code:
# continuous polling command automatically polls the board
elif user_cmd.upper().startswith("POLL"):
delaytime = float(string.split(user_cmd, ',')[1])
# check for polling time being too short, change it to the minimum timeout if too short
if delaytime < AtlasI2C.long_timeout:
print("Polling time is shorter than timeout, setting polling time to %0.2f" % AtlasI2C.long_timeout)
delaytime = AtlasI2C.long_timeout
# get the information of the board you're polling
info = string.split(device.query("I"), ",")[1]
print("Polling %s sensor every %0.2f seconds, press ctrl-c to stop polling" % (info, delaytime))
try:
while True:
print(device.query("R"))
time.sleep(delaytime - AtlasI2C.long_timeout)
except KeyboardInterrupt: # catches the ctrl-c command, which breaks the loop above
print("Continuous polling stopped")
If this is the case then if looks like you can recycle most of this code for your use. You can grab the string you are seeing in your console with device.query("R"), instead of printing it, grab the return value and write it to your CSV.
I think You should add method to AtlasI2C class which will write data to file
Just type under AtlasI2C init() this method:
def update_file(self, new_data):
with open(self.csv_file, 'a') as data_file:
try:
data = "{}\n".format(str(new_data))
data_file.write(data)
except Exception as e:
print(e)
add to AtlasI2C init statement about csv file name:
self.csv_file = <my_filename>.csv # replace my_filename with ur name
and then under line 51 (char_list = list(map(lambda x: chr(ord(x) & ~0x80), list(response[1:]))) add this line:
self.update_file(''.join(char_list))
Hope its gonna help You.
Cheers,
Fenrir

Python - Network WMI remotely run exe, and grab the text result

I have a python project called the "Remote Dongle Reader". There are about 200 machines that have a "Dongle" attached, and a corresponding .exe called "Dongle Manager". Running the Dongle Manager spits out a "Scan" .txt file with information from the dongle.
I am trying to write a script, which runs from a central location, which has administrative domain access to the entire network. It will read a list of hostnames, go through each one, and bring back all the files. Once it brings back all the files, it will compile to a csv.
I have it working on my Lab/Test servers, but in production systems, it does nto work. I am wondering if this is some sort of login issue since people may be actively using the system. THe process needs to launch silently, and do everything int he background. However since I am connecting to the administrator user, I wonder if there is a clash.
I am not sure what's going on other than tge application works up until the point I expect the file to be there. The "Dongle Manager" process starts, but it doesnt appear to be spitting the scan out on any machine not logged in as administrator (the account I am running off of).
Below is the snippet of the WMI section of the code. This was a very quick script so I apoliogize for any non pythonic statements.
c = wmi.WMI(ip, user=username, password=password)
process_startup = c.Win32_ProcessStartup.new()
process_startup.ShowWindow = SW_SHOWNORMAL
cmd = r'C:\Program Files\Avid\Utilities\DongleManager\DongleManager.exe'
process_id, result = c.Win32_Process.Create(CommandLine=cmd,
ProcessStartupInformation=process_startup)
if result == 0:
print("Process started successfully: %d" % process_id)
else:
print("Problem creating process: %d" % result)
while not os.path.exists(("A:/"+scan_folder)):
time.sleep(1)
counter += 1
if counter > 20:
failed.append(hostname)
print("A:/"+scan_folder+"does not exist")
return
time.sleep(4)
scan_list = os.listdir("A:/"+scan_folder)
scan_list.sort(key=lambda x: os.stat(os.path.join("A:/"+scan_folder, x)).st_mtime, reverse=True)
if scan_list is []:
failed.append(hostname)
return
recursive_overwrite("A:/"+scan_folder+"/"+scan_list[0],
"C:\\AvidTemp\\Dongles\\"+hostname+".txt")
Assuming I get a connection (computer on), it usually fails at the point where it either waits for teh folder to be created, or expects something in the list of scan_folder... either way, something is stopping the scan from being created, even though the process is starting
Edit, I am mounting as A:/ elsewhere in the code
The problem is that you've requested to show the application window but there is no logged on desktop to display it. WMI examples frequently use SW_SHOWWINDOW but that's usually the wrong choice because with WMI you are typically trying to run something in the background. In that case, SW_HIDE (or nothing) is the better choice.

Categories

Resources