I have two file in directory abc
test.py
hello.txt
File test.py:
import os.path
if os.path.exists('hello.txt'):
print('yes')
else:
print('no')
when execute test.py in same directory, the output is, as I'd expect, 'yes'
abc > python test.py
output: yes
but when try to execute form other directory
~ > python ~/Desktop/abc/test.py
output: no
how to correct this
# the real case
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
it works when executing within directory abc but fails form outside.
thanks, everyone, finally I found the solution, never thought that would be easy.... just change the working directory and voila๐ its work๐๐ใใใ
import os
...
script_path = os.path.dirname(os.path.realpath(__file__))
os.chdir(script_path)
...
...
Do a complete path, the tilda
~
specifies from where you "are right now"
to correctly specify it do the complete path. Easiest way to do this is go to file explorer, right click on the file, and press copy path. This should get you the complete path to the file which can be specified anywhere.
Please let me know if this helped!
In this case you need to search the file after walking through the directories and reading the contents.
You might consider os.scandir() to walk through the directories [python 3.5].
https://www.python.org/dev/peps/pep-0471/
Sample:
def find_file(path: str) -> str:
for entry in scandir(path):
if entry.is_file() and entry.name == 'token.pickle':
return_path = f'{path}\{entry.name}'
yield return_path
elif entry.is_dir():
yield from find_file(entry.path)
if __name__ == '__main__':
for path in find_file('.'):
with open(path, 'rb') as token:
creds = pickle.load(token)
well, if you do not know the complete path, this is much more difficult IMHO. I don't have any good, pythonic idea to do that!
To search for the file within your whole PC, use subprocess module and execute "find" command on linux (you're on linux, right?), catch the output, and ask if your file is there:
import subprocess
file_name = "test.txt"
sp = subprocess.Popen(["find", '/', "-name", file_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output = sp.communicate()
found = False
for line in output:
if file_name.encode() in line:
found = True
print("Found:", found)
NOTE: to delimit the search replace "/" by the parent folder you expect the file to be in.
EDIT: On windows, though I could not test it, the command would be: "dir /s /p hello.txt", so the subprocess call would look like this: sp = subprocess.Popen(["cmd", "/c", 'dir', '/s', '/p', 'Links'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
I see you already post an answer to your own question here
Anyway, I wanted to advice you there's no need to use os.chdir() for the purpose here really, simply do it like this:
# the real case
path_to_your_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),"token.pickle")
if os.path.exists(path_to_your_file):
with open(path_to_your_file, 'rb') as token:
...
P.S.
If you're wondering, there's several good reason to prefer using os.path.join() over manual string concatenation, the main one being it makes your coding platform independent in the first place
Related
I'm trying to look at all the items we have in a directory, and check whether there are file or directory. Sadly, all of them aren't directory, neither a file.
import io, sys, os, json
path_input = "C:\\Users\\Me\\AppData\\Local\\somewhere\\"
for file in os.listdir(path_input):
print("Looking at " + file)
isFile = os.path.isfile(file) # False
isDir = os.path.isdir(file) # False
I'm pretty sure I'm missing something with how I handle file.
I forgot to add the path in my function to properly locate the file (or the directory)
isDirectory = os.path.isdir(path_input+file)
Someone posted the solution but the post got deleted
Hey and thanks for all of your answers. I try to write a piece of python code that only executes once, (first time the program is installed) and copies the program into the windows startup folders.
(C:\Users\ USER \AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup)
That's the code i wrote for this. (Please don't judge me. I know it's
very shitty code. But I'm very new to coding. (this is the second
little program i try to write)
import os
import shutil
#get username
user = str(os.getlogin())
user.strip()
file_in = ('C:/Users/')
file_in_2 = ('/Desktop/Py Sandbox/test/program.py')
file_in_com = (file_in + user + file_in_2)
folder_seg_1 = ('C:/Users/')
folder_seg_2 = ('/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup')
#create FolderPath
folder_com = (folder_seg_1 + user + folder_seg_2)
shutil.copy2(file_in_com, folder_com)
Because i got an error, that there is no such internal, external,
command, program or batch file named Installer. I tried to generate a batch file with
nothing in it that executes when the installation process is finished.(But the error is still there.)
save_path = 'C:/Windows/assembly/temp'
name_of_file = str("Installer")
completeName = os.path.join(save_path, name_of_file+".bat")
file1 = open(completeName, "w")
file1.close()
The main idea behind this that there is my main Program, you execute
it it runs the code above and copies itself to the startup folder.
Then the code the whole installer file gets deleted form my main
program.
import Installer
#run Installer File
os.system('Installer')
os.remove('Installer.py')
But maybe there's someone out there who knows the answer to this problem.
And as I said earlier, thanks for all of your answers <3.
BTW I'm currently using Python 3.5.
Okay guys now I finally managed to solve this problem. It's actually not that hard but you need to think from another perspective.
This is now the code i came up with.
import os
import sys
import shutil
# get system boot drive
boot_drive = (os.getenv("SystemDrive"))
# get current Username
user = str(os.getlogin())
user.strip()
# get script path
script_path = (sys.argv[0])
# create FolderPath (Startup Folder)
folder_seg_1 = (boot_drive + '/Users/')
folder_seg_2 = ('/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup')
folder_startup = (folder_seg_1 + user + folder_seg_2)
#check if file exits, if yes copy to Startup Folder
file_name = (ntpath.basename(script_path))
startup_file = (folder_startup + ("/") + file_name)
renamed_file = (folder_startup + ("/") + ("SAMPLE.py"))
# checkfile in Startup Folder
check_path = (os.path.isfile(renamed_file))
if check_path == True:
pass
else:
shutil.copy2(script_path, folder_startup)
os.rename(startup_file, renamed_file)
This script gets your username, your boot drive, the file location of
your file than creates all the paths needed. Like your personal
startup folder. It than checks if there is already a file in the
startup folder if yes it just does nothing and goes on, if not it
copies the file to the startup folder an than renames it (you can use that if you want but you don't need to).
It is not necessary to do an os.getenv("SystemDrive") or os.getlogin(), because os.getenv("AppData") already gets both. So the most direct way of doing it that I know of is this:
path = os.path.join(os.getenv("appdata"),"Microsoft","Windows","Start Menu","Programs","Startup")
I have made a simple test code in python that reads from a text file, and then preforms an action if the text file contains a line "on".
My code works fine if i run the script on my hardive with the text file in the same folder. Example, (C:\Python27\my_file.txt, and C:\Python27\my_scipt.py).
However, if I try this code while my text file is located on my flashdrive and my script is still on my hardrive it won't work even though I have the correct path specified. Example, (G:\flashdrive_folder\flashdrive_file.txt, and C:\Python27\my_scipt.py).
Here is the code I have written out.
def locatedrive():
file = open("G:\flashdrive_folder\flashdrive_file.txt", "r")
flashdrive_file = file.read()
file.close()
if flashdrive_file == "on":
print "working"
else:
print"fail"
while True:
print "trying"
try:
locatedrive()
break
except:
pass
break
The backslash character does double duty. Windows uses it as a path separator, and Python uses it to introduce escape sequences.
You need to escape the backslash (using a backslash!), or use one of the other techniques below:
file = open("G:\\flashdrive_folder\\flashdrive_file.txt", "r")
or
file = open(r"G:\flashdrive_folder\flashdrive_file.txt", "r")
or
file = open("G:/flashdrive_folder/flashdrive_file.txt", "r")
cd /media/usb0
import os
path = "/media/usb0"
#!/usr/bin/python
import os
path = "/usr/tmp"
# Check current working directory.
retval = os.getcwd()
print "Current working directory %s" % retval
# Now change the directory
os.chdir( path )
# Check current working directory.
retval = os.getcwd()
print "Directory changed successfully %s" % retval
Use:
import os
os.chdir(path_to_flashdrive)
I am working on a small program for work, and I have looked everywhere for help on this!
What I'm trying to do is to allow the user to put in string to search. The program will search multiple .txt files in a defined directory for the string and then either print the result, or open the .txt file using the default text editor.
Can someone please point me in the right direction for this search feature?
Thanks in advance!
Edit:
This is what I have so far. I cant use grep as this program wil be running on Windows as well as OSX. I have yet to test on Windows, but on OSX my results are access denied.
import os
import subprocess
text = str(raw_input("Enter the text you want to search for: "))
thedir = './f'
for file in os.listdir(thedir):
document = os.path.join(thedir, file)
for line in open(document):
if text in line:
subpocess.call(document, shell=True)
There are much better tools to do this (grep was mentioned, and it is probably the best way to go).
Now, if you want a Python solution (which would run very slow), you can start from here:
import os
def find(word):
def _find(path):
with open(path, "rb") as fp:
for n, line in enumerate(fp):
if word in line:
yield n+1, line
return _find
def search(word, start):
finder = find(word)
for root, dirs, files in os.walk(start):
for f in files:
path = os.path.join(root, f)
for line_number, line in finder(path):
yield path, line_number, line.strip()
if __name__ == "__main__":
import sys
if not len(sys.argv) == 3:
print("usage: word directory")
sys.exit(1)
word = sys.argv[1]
start = sys.argv[2]
for path, line_number, line in search(word, start):
print ("{0} matches in line {1}: '{2}'".format(path, line_number, line))
Please take this with a grain of salt: it will not use regular expressions, or be smart at all. For example, if you try to search for "hola" it will match "nicholas", but not "Hola" (in the latter case, you could add a line.lower() method.
Again, it is just a beginning to show you a possible way to start. However, please PLEASE use grep.
Cheers.
Sample run (I called this script "pygrep.py"; $ is the command prompt):
$python pygrep.py finder .
./pygrep.py matches in line 12: 'finder = find(word)'
./pygrep.py matches in line 16: 'for line_number, line in finder(path):'
./pygrep.py~ matches in line 11: 'finder = find(word)'
below are hints to your answer :)
You can use os.walk to traverse all the files in the specified directory structure, search the string in the file, use subprocess module to open the file in the required editor...
import os
import subprocess
text = str(raw_input("Enter the text you want to search for: "))
thedir = 'C:\\your\\path\\here\\'
for file in os.listdir(thedir):
filepath = thedir + file
for line in open(filepath):
if text in line:
subprocess.call(filepath, shell=True)
break
I'm trying to create a Python script that would :
Look into the folder "/input"
For each video in that folder, run a mencoder command (to transcode them to something playable on my phone)
Once mencoder has finished his run, delete the original video.
That doesn't seem too hard, but I suck at python :)
Any ideas on what the script should look like ?
Bonus question : Should I use
os.system
or
subprocess.call
?
Subprocess.call seems to allow for a more readable script, since I can write the command like this :
cmdLine = ['mencoder',
sourceVideo,
'-ovc',
'copy',
'-oac',
'copy',
'-ss',
'00:02:54',
'-endpos',
'00:00:54',
'-o',
destinationVideo]
EDIT : Ok, that works :
import os, subprocess
bitrate = '100'
mencoder = 'C:\\Program Files\\_utilitaires\\MPlayer-1.0rc2\\mencoder.exe'
inputdir = 'C:\\Documents and Settings\\Administrator\\Desktop\\input'
outputdir = 'C:\\Documents and Settings\\Administrator\\Desktop\\output'
for fichier in os.listdir(inputdir):
print 'fichier :' + fichier
sourceVideo = inputdir + '\\' + fichier
destinationVideo = outputdir + '\\' + fichier[:-4] + ".mp4"
commande = [mencoder,
'-of',
'lavf',
[...]
'-mc',
'0',
sourceVideo,
'-o',
destinationVideo]
subprocess.call(commande)
os.remove(sourceVideo)
raw_input('Press Enter to exit')
I've removed the mencoder command, for clarity and because I'm still working on it.
Thanks to everyone for your input.
To find all the filenames use os.listdir().
Then you loop over the filenames. Like so:
import os
for filename in os.listdir('dirname'):
callthecommandhere(blablahbla, filename, foo)
If you prefer subprocess, use subprocess. :-)
Use os.walk to iterate recursively over directory content:
import os
root_dir = '.'
for directory, subdirectories, files in os.walk(root_dir):
for file in files:
print os.path.join(directory, file)
No real difference between os.system and subprocess.call here - unless you have to deal with strangely named files (filenames including spaces, quotation marks and so on). If this is the case, subprocess.call is definitely better, because you don't need to do any shell-quoting on file names. os.system is better when you need to accept any valid shell command, e.g. received from user in the configuration file.
The new recommend way in Python3 is to use pathlib:
from pathlib import Path
mydir = Path("path/to/my/dir")
for file in mydir.glob('*.mp4'):
print(file.name)
# do your stuff
Instead of *.mp4 you can use any filter, even a recursive one like **/*.mp4. If you want to use more than one extension, you can simply iterate all with * or **/* (recursive) and check every file's extension with file.name.endswith(('.mp4', '.webp', '.avi', '.wmv', '.mov'))
Python might be overkill for this.
for file in *; do mencoder -some options "$file"; rm -f "$file" ; done
The rm -f "$file" deletes the files.
AVI to MPG (pick your extensions):
files = os.listdir('/input')
for sourceVideo in files:
if sourceVideo[-4:] != ".avi"
continue
destinationVideo = sourceVideo[:-4] + ".mpg"
cmdLine = ['mencoder', sourceVideo, '-ovc', 'copy', '-oac', 'copy', '-ss',
'00:02:54', '-endpos', '00:00:54', '-o', destinationVideo]
output1 = Popen(cmdLine, stdout=PIPE).communicate()[0]
print output1
output2 = Popen(['del', sourceVideo], stdout=PIPE).communicate()[0]
print output2
Or you could use the os.path.walk function, which does more work for you than just os.walk:
A stupid example:
def walk_func(blah_args, dirname,names):
print ' '.join(('In ',dirname,', called with ',blah_args))
for name in names:
print 'Walked on ' + name
if __name__ == '__main__':
import os.path
directory = './'
arguments = '[args go here]'
os.path.walk(directory,walk_func,arguments)
I had a similar problem, with a lot of help from the web and this post I made a small application, my target is VCD and SVCD and I don't delete the source but I reckon it will be fairly easy to adapt to your own needs.
It can convert 1 video and cut it or can convert all videos in a folder, rename them and put them in a subfolder /VCD
I also add a small interface, hope someone else find it useful!
I put the code and file in here btw: http://tequilaphp.wordpress.com/2010/08/27/learning-python-making-a-svcd-gui/