473,398 Members | 2,212 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

breaking from loop

Hi,

Following is the code:

def walk_tree_copy(sRepository, sFile, sSourceDir, bFound = None):
try:
if sRepository is not None:
for name in os.listdir(sRepository):
path = os.path.join(sRepository, name)
if os.path.isdir(path):
walk_tree_copy(path, sFile, sSourceDir, bFound)
elif name.endswith('.foo') or name.endswith('.bar'):
if name == sFile:
try:
shutil.copy(path, sSourceDir)
except IOError, (errno, errstring):
errfunc(errno, errstring)
except shutil.Error:
print name + " is available in " +
sSourceDir + "Skipping Copy!"
bFound = True
break
return bFound
except OSError, (errno, strerror):
print errno, strerror

This function allows me to walk into a directory based tree and search
for files ending with .foo and .bar. My requirement is to copy
..foo/.bar.
Say in directory temp=>test=>test.bar is found. So shutil.copy will
copy it. I want that once the copy is done, it should make bFound =
True and get out.
But since test directory is under temp, work_tree_copy makes two calls
of the same function _but_ break only is able to get out from the inner
call.

Where am I wrong in this code ? Is there a better way to implement it ?

Regards,
rrs

Feb 10 '06 #1
6 1275
Ritesh Raj Sarraf enlightened us with:
bFound = True
break
return bFound
I see two weird things. First of all, the retun statement won't be
reached due to the break before it. Let's assume the break isn't
needed, and you want just the return. Why set the variable if you're
going to return anyway? I'd change those three lines to "return True".
But since test directory is under temp, work_tree_copy makes two
calls of the same function _but_ break only is able to get out from
the inner call.


Raise an exception and catch it at the outer level.

Sybren
--
The problem with the world is stupidity. Not saying there should be a
capital punishment for stupidity, but why don't we just take the
safety labels off of everything and let the problem solve itself?
Frank Zappa
Feb 10 '06 #2
Ritesh Raj Sarraf wrote:
Following is the code:

def walk_tree_copy(sRepository, sFile, sSourceDir, bFound = None):
try:
if sRepository is not None:
for name in os.listdir(sRepository):
path = os.path.join(sRepository, name)
if os.path.isdir(path):
walk_tree_copy(path, sFile, sSourceDir, bFound)
elif name.endswith('.foo') or name.endswith('.bar'):
if name == sFile:
Pick /one/ the conditions

- file name must be ...
- file must end with ... or ...
try:
shutil.copy(path, sSourceDir)
except IOError, (errno, errstring):
errfunc(errno, errstring)
except shutil.Error:
print name + " is available in " +
sSourceDir + "Skipping Copy!"
bFound = True
break
return bFound
except OSError, (errno, strerror):
print errno, strerror

This function allows me to walk into a directory based tree and search
for files ending with .foo and .bar. My requirement is to copy
.foo/.bar.
Say in directory temp=>test=>test.bar is found. So shutil.copy will
copy it. I want that once the copy is done, it should make bFound =
True and get out.
But since test directory is under temp, work_tree_copy makes two calls
of the same function _but_ break only is able to get out from the inner
call.

Where am I wrong in this code ? Is there a better way to implement it ?


An implementation on top of os.walk() can simplify things a bit:

import os
import shutil

def files(root):
for path, folders, files in os.walk(root):
for file in files:
yield path, file

def copy_first_match(repository, filename, dest_dir): # aka walk_tree_copy()
for path, file in files(repository):
if file == filename:
shutil.copy(os.path.join(path, file), dest_dir)
return True
return False

files() and os.walk() take care of the recursion, and you can just break or
return from the loop in copy_first_match().

Peter

Feb 10 '06 #3
Ritesh Raj Sarraf wrote:
Hi,

Following is the code:

def walk_tree_copy(sRepository, sFile, sSourceDir, bFound = None):
try:
if sRepository is not None:
You're being overly defensive here. Passing None as first arg is clearly
a programming error, so the sooner you detect it the better. Hence, just
don't test, and let exceptions propagate.
for name in os.listdir(sRepository):
path = os.path.join(sRepository, name)
if os.path.isdir(path):
walk_tree_copy(path, sFile, sSourceDir, bFound)
elif name.endswith('.foo') or name.endswith('.bar'):
if name == sFile:
Why do you *first* test on the extension, and *then* on the whole name ?
The boolean expression:
(name.endswith('.foo') or name.endswith('.bar')) and name == sFile
logically implies that :
sFile.endswith('.foo') or sFile.endswith('.bar')

So the first test is pretty useless...

Also, why hardcode such tests ? Python makes it easy to write generic
(hence reusable) code.

try:
shutil.copy(path, sSourceDir)
except IOError, (errno, errstring):
errfunc(errno, errstring)
??? What is this function doing ?
except shutil.Error:
print name + " is available in " +
sSourceDir + "Skipping Copy!"
Don't assume the cause of the exception. FWIW, try the following snippet:
f = open('test.txt', 'w')
f.write('coucou')
f.close()
for i in range(10): .... shutil.copy('test.txt', 'testcopy.txt')
....


Also, stdout is meant to be used for normal program outputs. Other
messages should go to stderr.

bFound = True
break
return bFound
Err... this last statement won't be executed.
except OSError, (errno, strerror):
print errno, strerror

This function allows me to walk into a directory based tree and search
for files ending with .foo and .bar. My requirement is to copy
.foo/.bar.
Say in directory temp=>test=>test.bar is found. So shutil.copy will
copy it. I want that once the copy is done, it should make bFound =
True and get out.
What's the use of setting bFound to True ? If you want to get out
returning a value, just return that value :

# dummy exemple
def test(seq, target):
for item in seq:
if item == target:
return True
return False
But since test directory is under temp, work_tree_copy makes two calls
of the same function _but_ break only is able to get out from the inner
call.

You should first focus on making it work without worrying about error
handling. Ensure that all return path are covered (in your actual
implementation, your function always return None). Use a callback
function for testing if a file should be copied, so your code has a
chance of being reusable when specs evolve. And two hints:
* exceptions are not only for error handling, they are also useful to
control flow of execution...
* generators and iterators are great

AFAICT, what you're trying to do here is mainly to
1/ recursively search files matching a given condition in a directory tree
2/ do something with these files.

A solution could be to split your code accordingly:

def find_in_tree(tree_path, match):
join = os.path.join
isdir = os.path.isdir
isfile = os.path.isfile
for name in os.listdir(tree_path):
fpath = join(tree_path, name)
if isdir(fpath):
for foundpath in find_in_tree(fpath, match)
yield foundpath
elif isfile(fpath) and match(fpath):
yield fpath
raise StopIteration

def find_and_copy_to(tree_path,
dest_path, match,
stop_on_first_match=False):
done = []
for fpath in find_in_tree(tree_path, match):
if fpath not in done:
shutil.copy(fpath, dest_path)
done.append(fpath)
if stop_on_first_match:
break
return done

match_foo_bar = lambda fpath: \
fpath.endswith('.foo') or fpath.endswith('.bar')

done = find_and_copy_to(sRepository,
sSourceDir,
match_foo_bar,
stop_on_first_match=True)
NB1 : not tested

NB2: I'm not sure I clearly undestand your specs (you're mixing
functional specs and implementation details in your description of
you're trying to do), so this may not be exactly what you want...

Also some stylistic advices:

1/ hungarian notation is *evil* - and even worse in a dynamically typed
language. Better use explicit names. What's important is not the type of
a variable, but it's role.

2/ string formating is fine

print >> sys.stderr, \
"%s is available in %s - skipping copy" % (filename, source_dir)

Is there a better way to implement it ?


Probably. Anyway, the better implementation is usually no
implementation. What about:

find $Repository -name "*.bar" -exec cp {} $SourceDir/ \;

?-)
Well, time to have a coffee anyway...
HTH

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Feb 10 '06 #4
Thanks to everyone. It is really the best place and the best people to
learn from.
Here's what I followed from the discussion:

def files(root):
for path, folders, files in os.walk(root):
for file in files:
yield path, file
def copy_first_match(repository, filename, dest_dir): # aka
walk_tree_copy()
for path, file in files(repository):
if file == filename:
try:
shutil.copy(os.path.join(path, file), dest_dir)
sys.stdout.write("%s copied from local cache %s." %
(file, repository))
except shutil.Error:
sys.stdout.write("%s is available in %s. Skipping
Copy!" % (file, dest_dir))
return True
return False

All I've added is the exception check because in case "file" is
available in "dest_dir", I want to display a message.
Since I'm still new and learning will be great if you let me know if
this is the proper way or not.

Thanks to everyone once again. It's been a very good experience
understanding everyone's comments.

Regards,
rrs

Feb 10 '06 #5
Using the (non-standard yet) path module
(http://www.jorendorff.com/articles/python/path/), your code can be
simplified to:

from path import path, copy

def copy_first_match(repository, filename, dest_dir):
try:
first_match = path(repository).walkfiles(filename).next()
except StopIteration:
return False
else:
copy(first_match, dest_dir)
return True
I/O exceptions are left to propagate to the caller.

George

Feb 11 '06 #6
Ritesh Raj Sarraf wrote:
def copy_first_match(repository, filename, dest_dir): # aka
walk_tree_copy()
****for*path,*file*in*files(repository):
********if*file*==*filename:
************try:
****************shutil.copy(os.path.join(path,*fil e),*dest_dir)
****************sys.stdout.write("%s*copied*from*l ocal*cache*%s."*%
(file, repository))
************except*shutil.Error:
****************sys.stdout.write("%s*is*available* in*%s.*Skipping
Copy!" % (file, dest_dir))
************return*True
****return*False

All I've added is the exception check because in case "file" is
available in "dest_dir", I want to display a message.
Since I'm still new and learning will be great if you let me know if
this is the proper way or not.


I prefer to let the exception propagate. As you wrote it, the code calling
copy_first_match() has no way of knowing whether a file was copied or not.

If you don't want to bother with exceptions in the calling code I'd slightly
modify the try...except:

try:
# copy
except (shutil.Error, OSError), e:
# print failure message
return False

I. e.

- catch OSError, too. I think shutil.copy() is more likely to raise an
OSError than a shutil.Error.
- return False if an exception occurs. That way you can test if something
went wrong like so:

if not copy_first_match(...):
print "file not found or unable to copy it"

Peter

Feb 12 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Jay Davis | last post by:
We have a lot of simple code using 'urllib', that basically just goes out and opens and read()'s some http url. Very basic, ten line scripts, and they work fine with urllib. We want to use...
9
by: rbt | last post by:
What is the appropriate way to break out of this while loop if the for loop finds a match? while 1: for x in xrange(len(group)): try: mix = random.sample(group, x) make_string = ''.join(mix)...
3
by: el chupacabra | last post by:
Hi, I'm just learning Python....thanks in advance... Do you get out of this loop? Problem: When I type 'exit' (no quotes) the program doesn't quit the loop...it actually attemps to find entries...
5
by: Uday Deo | last post by:
Hi everyone, I am looping through 4 nested loops and I would like to break in the inner most loop on certain condition and get the control on the 2 nd loop instead of 3rd loop. Here is briefly...
22
by: mihiri | last post by:
When I use this code it compile without errors ,but when run it ,it shows segmentation fault.I have general idea about segmentation fault,but I can't identify why it happen in this code.Eventhough I...
13
by: Sunbags | last post by:
Hello, I'm a 2nd year Computer Engineering student and I have a problem with my VB6 code. I've just started learning VB6 for a project in which we have to create a form which displays the...
9
by: nunzio | last post by:
Hi, my problem is apparently simple: I have a while loop controlled by a flag and I want to interrupt it by clicking on a stop button. void buttonStart_Click( Object * sender, System::EventArgs *...
6
by: noemailplease0001 | last post by:
Any elegant way of breaking out of the outer for loop than below, I seem to have come across something, but it escapes me for i in outerLoop: for j in innerLoop: if condition: break else:...
5
by: Kris Kowal | last post by:
I had a thought that might be pepworthy. Might we be able to break outer loops using an iter-instance specific StopIteration type? This is the desired, if not desirable, syntax:: import...
13
by: Andrew | last post by:
Hi I was wondering if there is anyway with XML RPC to send a string of text from the server to the client with out calling return thus breaking my loop for example def somefunc(): for...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.