How to change working directory of Python script during execution? - python-3.x

I am working on a personal project and I have been stuck here.
I want to change the working directory of my program during its execution but it is not working and there is also no error.
def google_search(search_term, api, cse, num = 10):
service = build("customsearch", "v1", developerKey = api)
res = service.cse().list(q = search_term, cx = cse).execute()
#Creating new folder with search term
if not os.path.exists(search_term):
print('Creating project: ' + search_term)
os.makedirs(search_term)
return res['items']
os.chdir("../test 1/%s" %search_term)
When I execute the entire script I get no error, the script executes completely but the directory doesn't change to the directory I have just created using the 'search_term'.
If I individually run the command below in ipython shell(using the search_term value), it executes and takes me to the intended directory.
os.chdir("../test 1/%s" %search_term)
It is working as an individual command when I put in the name of the directory directly but it is not working when I use it in the whole script.

There is return statement before os.chdir, so that line is not executed.

Related

Beginner Python Project - My function is skipping, what is causing this?

as the title says I'm a beginner with Python. I have started to work on what I thought first was a simple enough script for scanning a folder and printing the names of each subdirectory to a CMD prompt.
However, I've run into an issue where the function in the code below does not execute. I suspect it's to do with Windows permissions which is why I've added in the is_admin(): function.
My question is, what is it that is causing the function to skip? and what is the proper way to achieve what it is I am trying to do?
Any and all help is appreciated and if anyone could point me in the direction for learning more about Python and the Windows OS technical side for programmers would be doing me a huge favor.
Thanks in advance :)
import os, sys, ctypes
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
if is_admin():
rootdir = 'C:/Windows'
def listdirs(rootdir):
for file in os.listdir(rootdir):
d = os.path.join(rootdir, file)
if os.path.isdir(d):
print(d)
listdirs(d)
listdirs(rootdir)
else:
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv\[1:\]), None, 1)
input('Press any key to continue...')
Expecting the program to:
Produce an output of all the subdirectories of a folder printed to a CMD prompt window and have the window stay open when the program has finished executing each line of code. The Window should remain open until the user is finished with it. The Windows UAC should prompt asking the user if they wish to run as admin, if the user is already an admin then it should skip this and proceed to run the program.

How to utilize subprocess when invoking sas code in python on Linux server

I am trying to run a SAS program on linux using python. This server has SAS installed (version 9.4). And python version I have is 3.7.3.
I learned there is a library saspy which I could use however my project does not have access to this library. So, I found another alternative, my intension is to invoke the sas program in python and get the return code when it is successfully completed. This Sas program usually takes 1hr to complete.
So, I would like to use the return code when it is successful and later would like to notify myself through an email. I wrote the below code (sample) and I unable to make the subprocess work ? Any help is appreciated. Thanks
#!usr/bin/python
import os
import subprocess
import time
**My function begins here**
def Trigger_func(T):
if T == 1:
start = time.time() /** want to start a timer to know how long it takes to complete*/
#cmd = os.system('BGsas -p path/Sample.sas') /** SAS code is being invoked properly if used in this way */
sas_script = 'path/Sample.sas' /* Just a variable for the sas code path */
cmd2 = f'BGsas -p {sas_script}'
result = subprocess.call(cmd2, shell=True) /* if I use this subprocess to call the sas code it is not working, I am getting the return code <> 0 **/
if result == 0:
stop = time.time() - start
return [1, stop]
else:
stop = time.time() - start
return [0, stop]
""""""""
When the above process is completed, I will use this success return code to notify myself through
an email
""""""""""""
subprocess.call is an older method of doing this, but it should work; per the documentation, you need to use the returncode attribute to access the return code.
You may be better off using subprocess.run(), which returns a CompletedProcess instance.
Either way, you probably should ensure that your shell command (which looks like a .bat file) actually returns the value from the SAS execution. If it uses call, for example (in Windows batch script), it may actually be running SAS in the background - which is consistent with what you're describing here, and also consistent with the filename (BGsas). You may want to use a different script to launch SAS in the foreground.
I embedded the sas program in shell script and then invoked in python using p = subprocess.run(['sh', './path/shellscript.sh']) and used the p.returncode for further operations.
I see BGsas is not working as intended in my case. Thanks Joe and Tom for your time.

Python multiprocessing manager showing error when used in flask API

I am pretty confused about the best way to do what I am trying to do.
What do I want?
API call to the flask application
Flask route starts 4-5 multiprocess using Process module and combine results(on a sliced pandas dataframe) using a shared Managers().list()
Return computed results back to the client.
My implementation:
pos_iter_list = get_chunking_iter_list(len(position_records), 10000)
manager = Manager()
data_dict = manager.list()
processes = []
for i in range(len(pos_iter_list) - 1):
temp_list = data_dict[pos_iter_list[i]:pos_iter_list[i + 1]]
p = Process(
target=transpose_dataset,
args=(temp_list, name_space, align_namespace, measure_master_id, df_searchable, products,
channels, all_cols, potential_col, adoption_col, final_segment, col_map, product_segments,
data_dict)
)
p.start()
processes.append(p)
for p in processes:
p.join()
My directory structure:
- main.py(flask entry point)
- helper.py(contains function where above code is executed & calls transpose_dataset function)
Error that i am getting while running the same?
RuntimeError: No root path can be found for the provided module "mp_main". This can happen because the module came from an import hook that does not provide file name information or because it's a namespace package. In this case the root path needs to be explicitly provided.
Not sure what went wong here, manager list works fine when called from a sample.py file using if __name__ == '__main__':
Update: The same piece of code is working fine on my MacBook and not on windows os.
A sample flask API call:
#app.route(PREFIX + "ping", methods=['GET'])
def ping():
man = mp.Manager()
data = man.list()
processes = []
for i in range(0,5):
pr = mp.Process(target=test_func, args=(data, i))
pr.start()
processes.append(pr)
for pr in processes:
pr.join()
return json.dumps(list(data))
Stack has an ongoing bug preventing me from commenting, so I'll just write up an answer..
Python has 2 (main) ways to start a new process: "spawn", and "fork". Fork is a system command only available in *nix (read: linux or macos), and therefore spawn is the only option in windows. After 3.8 spawn will be the default on MacOS, but fork is still available. The big difference is that fork basically makes a copy of the existing process while spawn starts a whole new process (like just opening a new cmd window). There's a lot of nuance to why and how, but in order to be able to run the function you want the child process to run using spawn, the child has to import the main file. Importing a file is tantamount to just executing that file and then typically binding its namespace to a variable: import flask will run the flask/__ini__.py file, and bind its global namespace to the variable flask. There's often code however that is only used by the main process, and doesn't need to be imported / executed in the child process. In some cases running that code again actually breaks things, so instead you need to prevent it from running outside of the main process. This is taken into account in that the "magic" variable __name__ is only equal to "__main__" in the main file (and not in child processes or when importing modules).
In your specific case, you're creating a new app = Flask(__name__), which does some amount of validation and checks before you ever run the server. It's one of these setup/validation steps that it's tripping over when run from the child process. Fixing it by not letting it run at all is imao the cleaner solution, but you can also fix it by giving it a value that it won't trip over, then just never start that secondary server (again by protecting it with if __name__ == "__main__":)

requests.get(url).headers.get('content-disposition') returning NONE on PYTHON

Well, I've got the need of automate a process in my job(actually I'm an intern), and I just wondered if I could use Python for such process. I'm still processing my ideas of how to do those stuffs, and now I'm currently trying to understand how to download a file from a web URL using python3. I've found a guide on another website, but there's no active help there. I was told to use the module requests to download the actual file, and the module re to get the real file name.
The code was working fine, but then I tried to add some features like GUI, and it just stopped working. I took off the GUI code, and it didn't work again. Now I have no idea of what to do to get the code working, pls someone helo me, thanks :)
code:
import os
import re
# i have no idea of how this function works, but it gets the real file name
def getFilename(cd):
if not cd:
print("check 1")
return None
fname = re.findall('filename=(.+)', cd)
if len(fname) == 0:
print("check 2")
return None
return fname[0]
def download(url):
# get request
response = requests.get(url)
# get the real file name, cut off the quota and take the second element of the list(actual file name)
filename = getFilename(response.headers.get('content-disposition'))
print(filename)
# open in binary mode and write to file
#open(filename, "wb").write(response.content)
download("https://pixabay.com/get/57e9d14b4957a414f6da8c7dda353678153fd9e75b50704b_1280.png?attachment=")
os.system("pause")```

How to make the path to songs in pygame relative

Im working on a simple Snake game in python, and its working as intended here at home, but when I put the code on github, it doesn't find the path to the songs, I want to make this path relative, intead of absolute so it works on every computer.
Here is the part of the code for the song files -
def game_sound(s):
""" Include the game sfx and music"""
if s == 0:
pygame.mixer.music.load("background.ogg")
pygame.mixer.music.play(-1)
elif s == 1:
pygame.mixer.Sound("eating.wav").play()
elif s == 2:
pygame.mixer.Sound("game-over.wav").play()
TL - DR- It works here at home and nowhere else, Im trying to find a way to fix that by making the path relative I just dont know how. Can someone help?
Standard method is to find real path to folder with application
import os, sys
APP_FOLDER = os.path.dirname(os.path.realpath(sys.argv[0]))
And later use it to create real path to file
full_path = os.path.join(APP_FOLDER, "eating.wav")
pygame.mixer.Sound(full_path).play()
Or you have to change "current working directory" (CWD) to application folder.
os.chdir(APP_FOLDER)
pygame.mixer.Sound("eating.wav").play()
You can check current working directory with
print(os.getcwd())
BTW: without this method problem is not only when you run on different computer but also when you run from different folder on the same computer - so it makes problem when you create shortcut/icon on desktop which executes program as python game_folder/game.py

Resources