Change working directory to most recently generated directory - python

Is there a way to change your directory to the most recently generated directory? I am creating a new directory every 12 hours and want to iteratively loop through the most recent x amount of directories.
Something similar to this but for a directory.
How to get the latest file in a folder using python

The following should basically work.
import os
parent_dir = "." # or whatever
paths = [os.path.join(parent_dir, name) for name in os.listdir(parent_dir)]
dirs = [path for path in paths if os.path.isdir(path)]
dirs.sort(key=lambda d: os.stat(d).st_mtime)
os.chdir(dirs[-1])
Note that this will change to the directory with the most recent modification time. This might not be the most recently created directory, if a pre-existing directory was since modified (by creating or deleting something inside it); the information about when a directory is created is not something that is stored anywhere -- unless of course you use a directory naming that reflects the creation time, in which case you could sort based on the name rather than the modification time.
I haven't bothered here to guard against race conditions with something creating/deleting a directory during the short time that this takes to run (which could cause it to raise an exception). To be honest, this is sufficiently unlikely, that if you want to deal with this possibility, it would be sufficient to do:
while True:
try:
#all the above commands
break
except OSError:
pass

Related

Deleting files in directory / deleting certain directory that is not empty

I am creating a login system and I want to reset the info whenever the system is restarted. I have stored my information in text files in a directory called accounts. There are text files and subdirectories in the data/accounts directory.
I thought that I can use os.remove, but it does not work. So far, I have tried this.
import os
def infoReset():
os.remove("data/accounts/")
But it just gives me back an "operation not permitted" error. How can I delete the data/accounts directory and its contents?
Consider using a TemporaryDirectory, which will be automatically removed after you're done with it. This prevents bugs related to your manual and potentially insecure management of a directory.
According to the documentation,
On completion of the context or destruction of the temporary directory object the newly created temporary directory and all its contents are removed from the filesystem.
The directory name can be retrieved from the name attribute of the returned object. When the returned object is used as a context manager, the name will be assigned to the target of the as clause in the with statement, if there is one.
The directory can be explicitly cleaned up by calling the cleanup() method.
Here's an abridged example that applies to your use case:
import tempfile
# At the beginning of your program, create a temporary directory.
tempdir = tempfile.TemporaryDirectory()
...
# Later, remove the directory and its contents.
tempdir.cleanup()
Alternatively, depending on how feasible this would be in your project, use a context manager.
import tempfile
with tempfile.TemporaryDirectory() as tmpdirname:
# Write files in the directory...
# ...
# As soon as your exit this block, the directory is automatically cleaned up.
os.remove() is for files, not directories. os.rmdir() is for removing directories, but only empty directories. To delete a directory and its contents, use shutil.rmtree().
import shutil
def infoReset():
shutil.rmtree("data/accounts/")

Making a directory for a file

I was making a exercise generator algorithm for my friend, but I stumbled across a problem. It is a python program, and I wanted to generate a folder in a directory that was above the program's location (like, the python file is in 'C:\Documents\foo' and the folder should be created in 'C:\Documents') so that it could then store the file the program created. Is there a way to do this or should I try something else?
Use the path argument of the os.mkdir() function.
Getting the current script directory is not a built-in feature, but there are multiple hacks suggested here.
Once you get the current script directory, you can build a path based off of that.
Not super familiar with Python in a Windows environment, but this should be easily do-able. Here is a similar question that might be worth looking at: How to check if a directory exists and create it if necessary?
Looks like the pathlib module might do what you are looking for.
from pathlib import Path
path = Path("/my/directory/filename.txt")
try:
if not path.parent.exists():
path.parent.mkdir(parents=True)
except OSError:
# handle error; you can also catch specific errors like
# FileExistsError and so on.
Appears to work on Win 7 with Python 2.7.8 as described:
import os.path
createDir = '\\'.join((os.path.abspath(os.path.join(os.getcwd(), os.pardir)), 'Foo'))
if not os.path.exists(createDir):
os.makedirs(createDir)

check if a directory is already created python

A very basic question, I have a module that creates directories on the fly, however, sometimes I want to put more than one file in a dir. If this happens, python rises an exception and says that the dir is already created, how can I avoid this and check if the dir is already created or not?
The save module looks something like this:
def createdirs(realiz):
# Create all the necessary directories
path = "./doubDifferences_probandamp_realiz%d/"%realiz
os.mkdir(path,0755)
directory = os.path.split(path)[0]
return directory
On the main program, I have this:
for realiz in range(1,1000):
for i in range(dim):
for j in range(i+1,i+4):
...
dirspaths = mod_savefile.createdirs(realiz)
You could go for a try except:
try:
os.mkdir(path,0755)
except OSError:
pass
“Easier to ask forgiveness than permission !”
Also this method is more safe that testing the directory before doing mkdir. Indeed, it is fairly possible that between the two os call implied by ispath and mkdir the directory may have been created or destroyed by another thread.
This should cover you. Just test if it is a directory before you try to create it.
if not os.path.isdir(path)
os.mkdir(path,0755)
You have several ways. Either use os.path.isdir function:
import os.path
def createdirs(realiz):
# Create all the necessary directories
path = "./doubDifferences_probandamp_realiz%d/"%realiz
if not os.path.isdir(path): # if not exists
os.mkdir(path,0755) # create it
directory = os.path.split(path)[0]
return directory
Or handle the exception.

Python function that navigates to top level module directory

I'm trying to write a function in python that navigates to the top level directory of the project i'm working on for bookkeeping purposes. Instead of writing abs paths everywhere which may change depending on the machine, I think this would be easier.
However, my funct isn't super sophisticated and goes into inf loops in situations. Does anyone have a good strategy for something like this?
def chdir_top():
while os.getcwd().split('/')[-1] != "myproj":
os.chdir('..')
if os.getcwd().split('/')[-2] != "myproj" and
"myproj" in os.listdir(os.getcwd()):
os.chdir("myproj")
Thank you.
Do not use os.getcwd() for this; use the module-level __file__ name instead. If the current working directory is elsewhere, you end up in an infinite loop when you reach the root directory and continually fail to go up one directory.
import os.path
here = os.path.dirname(os.path.abspath(__file__))
Now here is a path to the directory containing the current Python file. Use that to find the top of your project (not by using chdir() but by using os.path functions).

In Python, how can I efficiently manage references between script files?

I have a fair number of Python scripts that contain reusable code that are used and referenced by other Python scripts. However, these scripts tend to be scattered across different directories and I find it to be somewhat tedious to have to include (most often multiple) calls to sys.path.append on my top-level scripts. I just want to provide the 'import' statements without the additional file references in the same script.
Currently, I have this:
import sys
sys.path.append('..//shared1//reusable_foo')
import Foo
sys.path.append('..//shared2//reusable_bar')
import Bar
My preference would be the following:
import Foo
import Bar
My background is primarily in the .NET platform so I am accustomed to having meta files such as *.csproj, *.vbproj, *.sln, etc. to manage and contain the actual file path references outside of the source files. This allows me to just provide 'using' directives (equivalent to Python's import) without exposing all of the references and allowing for reuse of the path references themselves across multiple scripts.
Does Python have equivalent support for this and, if not, what are some techniques and approaches?
The simple answer is to put your reusable code in your site-packages directory, which is in your sys.path.
You can also extend the search path by adding .pth files somewhere in your path.
See https://docs.python.org/2/install/#modifying-python-s-search-path for more details
Oh, and python 2.6/3.0 adds support for PEP370, Per-user site-packages Directory
If your reusable files are packaged (that is, they include an __init__.py file) and the path to that package is part of your PYTHONPATH or sys.path then you should be able to do just
import Foo
This question provides a few more details.
(Note: As Jim said, you could also drop your reusable code into your site-packages directory.)
You can put the reusable stuff in site-packages. That's completely transparent, since it's in sys.path by default.
You can put someName.pth files in site-packages. These files have the directory in which your actual reusable stuff lives. This is also completely transparent. And doesn't involve the extra step of installing a change in site-packages.
You can put the directory of the reusable stuff on PYTHONPATH. That's a little less transparent, because you have to make sure it's set. Not rocket science, but not completely transparent.
In one project, I wanted to make sure that the user could put python scripts (that could basically be used as plugins) anywhere. My solution was to put the following in the config file for that project:
[server]
PYPATH_APPEND: /home/jason:/usr/share/some_directory
That way, this would add /home/jason and /usr/share/some_directory to the python path at program launch.
Then, it's just a simple matter of splitting the string by the colons and adding those directories to the end of the sys.path. You may want to consider putting a module in the site-packages directory that contains a function to read in that config file and add those directories to the sys.path (unfortunately, I don't have time at the moment to write an example).
As others have mentioned, it's a good idea to put as much in site-packages as possible and also using .pth files. But this can be a good idea if you have a script that needs to import a bunch of stuff that's not in site-packages that you wouldn't want to import from other scripts.
(there may also be a way to do this using .pth files, but I like being able to manipulate the python path in the same place as I put the rest of my configuration info)
The simplest way is to set (or add to) PYTHONPATH, and put (or symlink) your modules and packages into a path contained in PYTHONPATH.
My solution was to package up one utility that would import the module:
my_util is in site packages
import my_util
foo = myutil.import_script('..//shared1//reusable_foo')
if foo == None:
sys.exit(1)
def import_script(script_path, log_status = True):
"""
imports a module and returns the handle
"""
lpath = os.path.split(script_path)
if lpath[1] == '':
log('Error in script "%s" in import_script' % (script_path))
return None
#check if path is already in sys.path so we don't repeat
npath = None
if lpath[0] == '':
npath = '.'
else:
if lpath[0] not in sys.path:
npath = lpath[0]
if npath != None:
try:
sys.path.append(npath)
except:
if log_status == True:
log('Error adding path "%s" in import_script' % npath)
return None
try:
mod = __import__(lpath[1])
except:
error_trace,error_reason = FormatExceptionInfo()
if log_status == True:
log('Error importing "%s" module in import_script: %s' % (script_path, error_trace + error_reason))
sys.path.remove(npath)
return None
return mod

Categories

Resources