Python Random File From Directory

On

I'm working on a python module to randomly choose a wallpaper for my desktop background among thousands of pictures in my photo library.I though I'd make a general function: getrandomfile(ext, top)Return the name of a random file in a directory tree with top as root.Since I'm dealing with a very large directory tree, listing all possible files would be very time consuming (edit: see comments on C. Harley answer). So I went for heuristic method, making sure all files are covered and adding an upper bound in case there are no files with given extension.

  1. Python Random File From Directory Download
File

There are occasionally false negatives, which is not a too big deal, but most importantly, it runs nearly instantly.Algorithm is simple:. Get a list of directories, including.

Python Random File From Directory Download

File

Pick a random directory from that list. If the picked directory is. (either randomly, or only available option), then retrieve a list of files in that directory. If the list of files is empty, go back to 1.

Return a random file from that list.Note that this algorithm can go many levels deep into sub-directories.So far I'm happy with performance and returned values. It is able to quickly pick up a file in a very large tree.However, I'm after general comments in terms of performance and also code style.What I'm not particularly proud of in my code is the use of next(os.walk(top))1 to get the list of sub-directories in the current directory.There are also false negatives, when asking for a file extension with not many occurrences in a tree with many directories. However, I don't want to increase the limit too much to avoid waiting when really there are not such files in the tree.The code: # -.- coding: utf-8 -.-'Created on Wed Aug 29 14:@author: raf'import osimport sysimport globimport randomdef getrandomfiles(ext, top):'Return the name of a random file within a top path.Works recursivelly in subdirectories.Note that a full list of files could be got withglob(top + '/./.' + ext, recursive=True)However that would be extremely slow for large directories.'

Python Random File From Directory

'top = topct, limit = 0, 50000while True:if ct limit:return 'No file found after%d iterations.' % limitct += 1try:dirs = next(os.walk(top))1except StopIteration: # access denied and other exceptionstop = topcontinuei = random.randint(0, len(dirs))if i 0: # use.files = glob.glob(top + '/.' + ext)if not files:top = topcontinuei = random.randint(0, len(files)-1)return filesitop += '/' + dirsi-1if name 'main':if len(sys.argv) 1:print(getrandomfiles(sys.argv1, os.getcwd))else:print(getrandomfiles('.' , os.getcwd)). $begingroup$ Right - so it's not really a database, you've just got a heirarchial file system going on. HDDs store their data in File Allocation Tables (FAT) or similar, which is like an index file - real databases build lookup indexes to assist in fast determination of output. If I was you, I would have a program utilise or similar (I don't know your storage format) to maintain the index file, and rewrite the code to import that and print the matches.

That would be a much better design. $endgroup$–Sep 7 '18 at 23:52. There are many problems with your approach.It can be extremely unfair depending on your tree structure. Do a depth first complete walk and list probabilities. Root is probability 1, in each level divide by number of dirs (including.), finally divide by number of (matching) files. List all these hit probabilities and compare them.

If your tree is not balanced you will probably conclude to drop your approach.It will fail to find rare file patterns. The primary chance for a file to be found is depending on the directory structure only, only the last denominator is depending on the file pattern. So this approach will not scale, limit has to grow with the actual tree size and there is a good chance that you will fail even so. In a balanced tree you could fix that by going deep randomly once, then switching to a regular DFS walk. However this will not succeed when your patterns are not evenly distributed.I propose to do a database (simple file list or better) where you can efficiently match against your pattern and do the random select an all matches. Polski spiewnik rockowy. You can update the database in the background. You will not be limited to glob patterns but can also do regex and also match path names.

How do I open a random file in a folder, and set that only files with the specified filename extension(s) should be opened? (While preferably, supporting Unicode filenames too.)I've already looked around and found this batch script (.BAT): @echo off & setlocal:: start of mainrem Set your path here:set 'workDir=C:DVDCOVERS'rem Read the%random%, two times is'nt a mistake! Ask Bill.rem In fact at the first time%random% is nearly the same.@set /a 'rdm=%random%'set /a 'rdm=%random%'rem Push to your path.pushd '%workDir%'rem Count all files in your path. (dir with /b shows only the filenames)set /a 'counter=0'for /f 'delims='%%i in ('dir /b ^ find '.'

') do call:sub1rem This function gives a value from 1 to upper bound of filesset /a 'rdNum=(%rdm%.%counter%/32767)+1'rem Start a random fileset /a 'counter=0'for /f 'delims='%%i in ('dir /b ^ find '.' ') do set 'fileName=%%i' &call:sub2rem Pop back from your path.popd '%workDir%'goto:eof:: end of main:: start of sub1:sub1rem For each found file set counter + 1.set /a 'counter+=1'goto:eof:: end of sub1:: start of sub2:sub2rem 1st: count again,rem 2nd: if counted number equals random number then start the file.set /a 'counter+=1'if%counter%%rdNum% (start ' '%fileName%')goto:eof:: end of sub2:: -snap- end of batchSource:It works in opening any random file in a folder, but I would like to be able to set that only files with the specified filename extension(s) should be opened. A folder contains.MKV (video),.TP (video),.MP4 (video) and.JPG (image) files, and I would like to randomly open only video files, and not the.JPG image files.)It also does not support Unicode filenames. It makes Windows output this error message if it randomly opens a file with a Unicode filename:Windows cannot find (filename of file with Unicode filename, with the Unicode characters replaced with a question mark). Make sure you typed the name correctly, and try again.Purposes:.

If you would like to watch a random video from a folder, but the folder also contains non-video files. If you would like to view a random image from a folder, but the folder also contains non-image files. Etc.Suggestions to improve the.BAT file code (especially the 'randomness', as I often get the same file two-three times successively) or another better solution (even a non-batch script) is welcome. I am using Windows 7. This is an addition to.To use the Python script in, I saved the Python script at C:ProgramsScripts, with the filename, open-random-video.py (Python script that opens random videos).I then saved the following script as a:C:Python27python.exe 'C:ProgramsScriptsopen-random-video.py' cdNote that: C:Python27 is where Python is installed. This directory may change depending on where you installed Python.

Cd means the current directory.I then put the.BAT file in the folders I want to open random files of, and just run the.BAT file if I want a random file opened in that folder.