Python import module load_source - python

I have question on the load_source.
when my 2 .py files are in the same directory /home/pi they work fine.
main.py
#!/usr/bin/python
import buttonlog
buttonlog.py
import datetime
i = datetime.datetime.now()
#OPEN FILE & APPEND
f=open('buttonlog.txt','a')
#WRITE DATE THEN NEW LINE WITH THE '\N'
f.write(i.isoformat() + '\n')
When I run python main.py it writes an entry like I'd expect.
However I'd like to store main.py in another directory so I tried this, it is stored in the /home/pi/test
#!/usr/bin/python
import imp
imp.load_source('buttonlog', '/home/pi/buttonlog.py')
When I run python /home/pi/test/main.py I do not get any errors nor does it write an entry into my file. What am I doing wrong?

The secret is the use of the open command.
As the documentation says about the first argument,
file is a path-like object giving the pathname (absolute or relative to the current working directory) of the file to be opened or an integer file descriptor of the file to be wrapped.
By passing just "buttonlog.txt", this is not an absolute pathname, so it's relative to the current working directory.
The simplest way to fix this is to use a full path. If you always want it writing in to /home/pi, you just need:
f=open('/home/pi/buttonlog.txt','a')
There are other alternatives, though I think this is the cleanest. You could also change your current working directory prior to issuing the open command for the same results. Simply put this code above the open line:
import os
os.chdir("/home/pi")

Related

Regarding file io in Python

I mistakenly, typed the following code:
f = open('\TestFiles\'sample.txt', 'w')
f.write('I just wrote this line')
f.close()
I ran this code and even though I have mistakenly typed the above code, it is however a valid code because the second backslash ignores the single-quote and what I should get, according to my knowledge is a .txt file named "\TestFiles'sample" in my project folder. However when I navigated to the project folder, I could not find a file there.
However, if I do the same thing with a different filename for example. Like,
f = open('sample1.txt', 'w')
f.write('test')
f.close()
I find the 'sample.txt' file created in my folder. Is there a reason for the file to not being created even though the first code was valid according to my knowledge?
Also is there a way to mention a file relative to my project folder rather than mentioning the absolute path to a file? (For example I want to create a file called 'sample.txt' in a folder called 'TestFiles' inside my project folder. So without mentioning the absolute path to TestFiles folder, is there a way to mention the path to TestFiles folder relative to the project folder in Python when opening files?)
I am a beginner in Python and I hope someone could help me.
Thank you.
What you're looking for are relative paths, long story short, if you want to create a file called 'sample.txt' in a folder 'TestFiles' inside your project folder, you can do:
import os
f = open(os.path.join('TestFiles', 'sample1.txt'), 'w')
f.write('test')
f.close()
Or using the more recent pathlib module:
from pathlib import Path
f = open(Path('TestFiles', 'sample1.txt'), 'w')
f.write('test')
f.close()
But you need to keep in mind that it depends on where you started your Python interpreter (which is probably why you're not able to find "\TestFiles'sample" in your project folder, it's created elsewhere), to make sure everything works fine, you can do something like this instead:
from pathlib import Path
sample_path = Path(Path(__file__).parent, 'TestFiles', 'sample1.txt')
with open(sample_path, "w") as f:
f.write('test')
By using a [context manager]{https://book.pythontips.com/en/latest/context_managers.html} you can avoid using f.close()
When you create a file you can specify either an absolute filename or a relative filename.
If you start the file path with '\' (on Win) or '/' it will be an absolute path. So in your first case you specified an absolute path, which is in fact:
from pathlib import Path
Path('\Testfile\'sample.txt').absolute()
WindowsPath("C:/Testfile'sample.txt")
Whenever you run some code in python, the relative paths that will be generate will be composed by your current folder, which is the folder from which you started the python interpreter, which you can check with:
import os
os.getcwd()
and the relative path that you added afterwards, so if you specify:
Path('Testfiles\sample.txt').absolute()
WindowsPath('C:/Users/user/Testfiles/sample.txt')
In general I suggest you use pathlib to handle paths. That makes it safer and cross platform. For example let's say that your scrip is under:
project
src
script.py
testfiles
and you want to store/read a file in project/testfiles. What you can do is get the path for script.py with __file__ and build the path to project/testfiles
from pathlib import Path
src_path = Path(__file__)
testfiles_path = src_path.parent / 'testfiles'
sample_fname = testfiles_path / 'sample.txt'
with sample_fname.open('w') as f:
f.write('yo')
As I am running the first code example in vscode, I'm getting a warning
Anomalous backslash in string: '\T'. String constant might be missing an r prefix.
And when I am running the file, it is also creating a file with the name \TestFiles'sample.txt. And it is being created in the same directory where the .py file is.
now, if your working tree is like this:
project_folder
-testfiles
-sample.txt
-something.py
then you can just say: open("testfiles//hello.txt")
I hope you find it helpful.

Save a CSV in same directory as python file, using 'to_csv' and 'os.path'?

I want this line to save the csv in my current directory alongside my python file:
df.to_csv(./"test.csv")
My python file is in "C:\Users\Micheal\Desktop\VisualStudioCodes\Q1"
Unfortunately it saves it in "C:\Users\Micheal" instead.
I have tried import os path to use os.curdir but i get nothing but errors with that.
Is there even a way to save the csv alongside the python file using os.curdir?
Or is there a simpler way to just do this in python without importing anything?
import os
directory_of_python_script = os.path.dirname(os.path.abspath(__file__))
df.to_csv(os.path.join(directory_of_python_script, "test.csv"))
And if you want to read same .csv file later,
pandas.read_csv(os.path.join(directory_of_python_script, "test.csv"))
Here, __file__ gives the relative location(path) of the python script being runned. We get the absolute path by os.path.abspath() and then convert it to the name of the parent directory.
os.path.join() joins two paths together considering the operating system defaults for path seperators, '\' for Windows and '/' for Linux, for example.
This kind of an approach should work, I haven't tried, if does not work, let me know.

.pyc file closes immediately

I am using this code to convert .py file into .pyc
import py_compile
import os
import glob
path = ''
for infile in glob.glob( os.path.join(path, '*.py') ):
print(f"current file is: {infile}")
strDestination = 'compiled/' + infile + 'c'
py_compile.compile(infile,strDestination)
I converted 6 similar scripts, that uses:
pandas, calendar, datetime, gc, numpy ,multiprocessing modules. However, when I try to execute .pyc files, 3 one them work fine and 3 of them closes immediately.
I try to add an input() at the start and the end of the code, but it also closes immediately.
If I execute the same script .py, it works normally.
When the conversion occurs, is it necessary to avoid some specific library ?
#### UPDATE
I noticed if I change the name of the .pyc file to the same name of the one that worked, it works. However, it needs to be on the directory folder. Why ?
The answer: .pyc File name cannot have special characters.
I hope this help someone.

Get script's location when called by another app?

How can my Python script reliably get its own location so it can write a file next to itself?
I made a Python script that writes a new file with some working statistics:
import os
NAME = __file__.split('/')[-1]
PATH = os.path.dirname(os.path.realpath(__file__))
PROPER_PATH = os.path.join(MY_PATH, MY_NAME)
with open(os.path.join(PATH, STATS_NAME), 'wb') as statsfile:
statsfile.write(mystats)
This works great and I can call it from anywhere and it writes the stats file in the same place, next to the script. Apart from when I call the script from a macro VBA script.
The script gets called okay but writes its data to:
"C:\Users\lsp\AppData\Roaming\Microsoft\Templates"
How do I make sure it writes to the correct path (same as the script path)?
As a work-around I can imagine giving the path as an argument and then providing it in the VBA but surely there's a Pythonic way to achieve the behavior?

What is the standard way to use Python module os to specify the paths for third parties?

(I'm not used to writing python programs for other users to use, so hopefully this question is appropriate.)
My users will download a file generic_file.csv and let's assume that this file will be saved in the "current directory".
So, I write a python script named reader.py
#!/usr/bin/env python
from __future__ import (print_function, absolute_import)
import os
import csv
import random
import string
cd_path = os.getcwd() # return path of current directory
filename = 'generic_file.csv' # filename 'test_enigma.csv'
filepath = os.path.join(os.getcwd(), filename) # returns path to open fname
print(filepath)
Now, if the user runs this in the terminal with python reader.py, it should output the name of the file, ONLY IF the file was saved in the current directory.
That's inconvenient. Most users will just download the file, and they would like reader.py to change to the subdirectory Downloads and read generic_file.csv from that directory.
(1) How does one use os.chdir() to work for every user?
(2) What is the standard way to do this if I was writing third-party software? I imagine I would have the user download the specific CSV file and Python script together.
If you are looking to get the path name of User A's download file, you can do os.path.expanduser('~/Downloads'). This will return /Users/A/Downloads

Categories