Nested For and While Statements

  • Thread starter Bruno Desthuilliers
  • Start date
B

Bruno Desthuilliers

(e-mail address removed) a écrit :
(snip)
My actual code has different variables, but thanks for pointing that
out. I'm so used to coding in VB, where indenting isn't a problem, so
all this indenting is new to me how Python wants it dictated.

statement:
block line 1
block line 2
# end statement block


I made
the changes and still get an error at the same point after the second
For statement? So:

While :
Code under while
More under while.

For (x)
Part of x
Last of x

For(y)
Part of y
Still part of y
last part of y.
# end for(y)
New line part of x #where does this belong?

# end for(x)
Last line under while not in For #Should go under While, right?

# end while
 
K

koutoo

I start my code with some constants then a while statement. But I
have some For statements towards the end within the While statement
where I start getting some errors. I'm hoping I won't have to post my
code, but it looks something like this:

Import os, string

while this:

All Code indented like it should


Last line in While.

For i in range(1)
class = []
class2 = []
For i in range(2)
Do this
And this
And that.

Next Line hits snag here? Where should this line
be?
 
J

James Stroud

I start my code with some constants then a while statement. But I
have some For statements towards the end within the While statement
where I start getting some errors. I'm hoping I won't have to post my
code, but it looks something like this:

Import os, string

while this:

All Code indented like it should


Last line in While.

For i in range(1)
class = []
class2 = []
For i in range(2)
Do this
And this
And that.

Next Line hits snag here? Where should this line
be?

Your for loops both use the same counting index.
 
P

Paul McGuire

I start my code with some constants then a while statement. But I
have some For statements towards the end within the While statement
where I start getting some errors. I'm hoping I won't have to post my
code, but it looks something like this:

Import os, string

while this:

All Code indented like it should

Last line in While.

For i in range(1)
class = []
class2 = []
For i in range(2)
Do this
And this
And that.

Next Line hits snag here? Where should this line
be?

Why are the for loops further indented than the body of the while? If
they are part of the while, "For i in range(1)" should line up with
"Last line in While." If they are not part of the while, but come
after, then "For i in range(1)" should line up with "while this:".

Also, as James Stroud said, your for loop indexes are the same
variable.

-- Paul
 
Z

Zentrader

Your for loops both use the same counting index.

Since those variables are local to the for loop, theoretically it
should work with both loops using the same variable. Although bad
practice, I tested it on my machine and the following code does indeed
work as expected, so it appears that the problem is indenting the for
loops properly.
for j in range( 10 ):
print j, "first loop"
for j in range( 5 ):
print " ", j, "2nd loop"
 
Z

Zentrader

In addition, "for" is lower case, i.e not "For". If this doesn't
solve the problem then please post the actual error message. "Next
Line hits snag here? Where should this line be?" is not specific
enough.
 
K

koutoo

I start my code with some constants then a while statement. But I
have some For statements towards the end within the While statement
where I start getting some errors. I'm hoping I won't have to post my
code, but it looks something like this:
Import os, string
while this:
All Code indented like it should
Last line in While.
For i in range(1)
class = []
class2 = []
For i in range(2)
Do this
And this
And that.
Next Line hits snag here? Where should this line
be?

Why are the for loops further indented than the body of the while? If
they are part of the while, "For i in range(1)" should line up with
"Last line in While." If they are not part of the while, but come
after, then "For i in range(1)" should line up with "while this:".

Also, as James Stroud said, your for loop indexes are the same
variable.

-- Paul- Hide quoted text -

- Show quoted text -

My actual code has different variables, but thanks for pointing that
out. I'm so used to coding in VB, where indenting isn't a problem, so
all this indenting is new to me how Python wants it dictated. I made
the changes and still get an error at the same point after the second
For statement? So:

While :
Code under while
More under while.

For (x)
Part of x
Last of x

For(y)
Part of y
Still part of y
last part of y.

New line part of x #where does this belong?


Last line under while not in For #Should go under While, right?


If I want all my code to run under the while, then the While statement
should be the only line of code not indented once I state it then,
correct?
 
R

Roberto Bonvallet

[...] where I start getting some errors.
I'm hoping I won't have to post my code

"Doctor, I'm feeling bad. I hope I won't have to tell you my
symptoms. What do I have?"

Please provide the actual errors and the actual code. It is easier,
less error prone and more useful to copy and paste them instead of
writing some pseudocode. Maybe the repeated index i is a typo you
made when writing this post and the original code is correct, but we
don't have any way to know that.
 
K

koutoo

[...] where I start getting some errors.
I'm hoping I won't have to post my code

"Doctor, I'm feeling bad. I hope I won't have to tell you my
symptoms. What do I have?"

Please provide the actual errors and the actual code. It is easier,
less error prone and more useful to copy and paste them instead of
writing some pseudocode. Maybe the repeated index i is a typo you
made when writing this post and the original code is correct, but we
don't have any way to know that.

Here is my code, in the hopes that there is a reason why it isn't
running. Thanks guys.

Option Explicit - 'Sorry so use to writing this!

import os, string

# Get filename to work with
workspace = "c:\\temp"
filename = "\AVC1030708.14"
doc1 = workspace + filename

onedoc = open(doc1, "r")
rdoc1 = onedoc.read()
doclist1 = string.split(rdoc1, "\n")
for i in range(8):
doclist1.pop(0)

length = int(len(newlist1))-2
Nscheme = int(filename[12:14])
numlanes = length/Nscheme

site = filename[4:7]
year = filename[7:9]
month = filename[9:11]
Sscheme = str(Nscheme)

# Get Master AVC Table for Lanes & Direction
fileavc = "\AVCMaster"
doc2 = workspace + fileavc

twodoc = open(doc2, "r")
rdoc2 = twodoc.read()
doclist2 = string.split(rdoc2, "\n")
doclist2.pop(0)

# Dictionary of Zeros to add to Class Fields
addzeros = {1:"0", 2:"00", 3:"000", 4:"0000"}

while doclist1:

list1 = doclist1[0]
doclist1.pop(0)
newlist1 = list1.split(",")
date1 = newlist1[0]

if len(newlist1[0])== 8:
day = date1[2:3]
else:
day = date1[2:4]

if len(day)>1:
day = "0" +1

hour = newlist1[1]

lanex = []
# Find number of Lanes & Fields
if numlanes == 2:
lane1 = newlist1[2:2+Nscheme]
lanex.append(lane1)
lane2 = newlist1[2+Nscheme:2+Nscheme*2]
lanex.append(lane2)
else:
lane1 = newlist1[2:2+Nscheme]
lanex.append(lane1)
lane2 = newlist1[2+Nscheme:2+Nscheme*2]
lanex.append(lane2)
lane3 = newlist1[2+Nscheme*2:2+Nscheme*3]
lanex.append(lane3)
lane4 = newlist1[2+Nscheme*3:2+Nscheme*4]
lanex.append(lane4)

doctemp = doclist2
listtemp = doctemp[0]
avclist = listtemp.split(",")

while site <> avclist[0]:
doctemp.pop(0)
listtemp = doctemp[0]
avclist = listtemp.split(",")

dirx = []
fhlanex = []

dirx.append(avclist[2])
fhlanex.append(avclist[3])
dirx.append(avclist[5])
fhlanex.append(avclist[6])

if avclist[8] <> "0":
dirx.append(avclist[8])
fhlanex.append(avclist[9])
dirx.append(avclist [11])
fhlanex.append(avclist[12])


for x in range(1, numlanes+1):
avcclass = []
Nlanex = []
for i in range(1,Nscheme+1):
numzeros = 5 - int(len(lanex[i-1]))
avcclass.append(addzeros[numzeros] + lanex[i-1])
Nlanex.append(int(lanex[i-1])

lanex.pop(0)
totalclass = sum(Nlanex)
Stotalclass = str(totalclass)
#Create 90 Character File for SAS Job
classsum = avcclass[0] + avcclass[1] + avcclass[2] +
avcclass[3] + avcclass[4] + avcclass[5] \
+ avcclass[6] + avcclass[7] + avcclass[8] + avcclass[9] +
avcclass[10] \
+ avcclass[11] + avcclass[12] + avcclass[13]
classmn = "C27" + site + dirx[x] + lanex[x] + year + month +
day + hour + Stotalclass + classsum
break

avcsasdoc = workspace + "\avcsas.txt"
fdoc = open(avcsasdoc, "w")
fdoc.write(classmn)
 
R

richyjsm

Here is my code, in the hopes that there is a reason why it isn't
running. Thanks guys.

[code snipped]

You're missing the closing parenthesis on the last line of the inner
for loop.

Richard
 
P

Paul Hankin

First the bugs...

...
avcsasdoc = workspace + "\avcsas.txt"
...

There's quite a few cases like this where you don't escape
backslashes, so your filenames are mostly mangled. Here \a produces
character code 7, which is definitely wrong.

Either escape them like this: '\\avcsas.txt' or use raw strings where
backslashes aren't treated specially: r'\avcsas.txt'. You might want
to look at the 'os.path' module for help in constructing filenames.

You have a 'break' and the end of the last for loop. This has the
effect of stopping the for loop at the first iteration. Either it's a
bug, or you really didn't want a for loop!


There's also quite a few places where your code could be improved:
classsum = avcclass[0] + avcclass[1] + avcclass[2] +
avcclass[3] + avcclass[4] + avcclass[5] \
+ avcclass[6] + avcclass[7] + avcclass[8] + avcclass[9] +
avcclass[10] \
+ avcclass[11] + avcclass[12] + avcclass[13]

Is better written
classsum = ''.join(avcclass[:14])

addzeros = {1:"0", 2:"00", 3:"000", 4:"0000"}
...
... addzeros[numzeros] + lanex[i-1]

Good idea, but in this case python provides an easier alternative:
... '0' * numzeros + lanex[i - 1]
Or use the 'rjust' method which right-justifies a string:
... lanex[i - 1].rjust(5, '0')

for i in range(1,Nscheme+1):
numzeros = 5 - int(len(lanex[i-1]))
avcclass.append(addzeros[numzeros] + lanex[i-1])
Nlanex.append(int(lanex[i-1])

Is better as
for i in range(Nscheme):
... use i rather than i - 1

(I assume Visual Basic for loops are off by one).

In fact, this loop is even better if you just iterate over lanex
itself. Using a loop index rather than iterating directly is a common
mistake.

for lane in lanex:
avcclass.append(lane.rjust(5, '0'))
Nlanex.append(int(lane))

Or even better, use list comprehensions to construct your two lists
explicitly:

avcclass = [lane.rjust(5, '0') for lane in lanex]
Nlanex = [int(lane) for lane in lanex]

Note, each rewrite makes the intention of the code clearer, as well as
being shorter. This makes your code easier to read and understand, and
less buggy.


Since all you do with avcclass is sum it, combine this with the
classsum optimisation above to get

classsum = ''.join(lane.rjust(5, '0') for lane in lanex[:14])
Nlanex = [int(lane) for lane in lanex]
lanex = []
if numlanes == 2:
lane1 = newlist1[2:2+Nscheme]
lanex.append(lane1)
lane2 = newlist1[2+Nscheme:2+Nscheme*2]
lanex.append(lane2)
else:
lane1 = newlist1[2:2+Nscheme]
lanex.append(lane1)
lane2 = newlist1[2+Nscheme:2+Nscheme*2]
lanex.append(lane2)
lane3 = newlist1[2+Nscheme*2:2+Nscheme*3]
lanex.append(lane3)
lane4 = newlist1[2+Nscheme*3:2+Nscheme*4]
lanex.append(lane4)

List comprehensions beat copy/paste:

total_schemes = 2 if numlanes == 2 else 4
lanex = [newlist1[2 + i * Nscheme:2 + (i + 1) * Nscheme]
for i in range(total_schemes)]

HTH, and welcome to python!
 
P

Paul Hankin

First the bugs...

...
avcsasdoc = workspace + "\avcsas.txt"
...

There's quite a few cases like this where you don't escape
backslashes, so your filenames are mostly mangled. Here \a produces
character code 7, which is definitely wrong.

Either escape them like this: '\\avcsas.txt' or use raw strings where
backslashes aren't treated specially: r'\avcsas.txt'. You might want
to look at the 'os.path' module for help in constructing filenames.

You have a 'break' and the end of the last for loop. This has the
effect of stopping the for loop at the first iteration. Either it's a
bug, or you really didn't want a for loop!


There's also quite a few places where your code could be improved:
classsum = avcclass[0] + avcclass[1] + avcclass[2] +
avcclass[3] + avcclass[4] + avcclass[5] \
+ avcclass[6] + avcclass[7] + avcclass[8] + avcclass[9] +
avcclass[10] \
+ avcclass[11] + avcclass[12] + avcclass[13]

Is better written
classsum = ''.join(avcclass[:14])

addzeros = {1:"0", 2:"00", 3:"000", 4:"0000"}
...
... addzeros[numzeros] + lanex[i-1]

Good idea, but in this case python provides an easier alternative:
... '0' * numzeros + lanex[i - 1]
Or use the 'rjust' method which right-justifies a string:
... lanex[i - 1].rjust(5, '0')

for i in range(1,Nscheme+1):
numzeros = 5 - int(len(lanex[i-1]))
avcclass.append(addzeros[numzeros] + lanex[i-1])
Nlanex.append(int(lanex[i-1])

Is better as
for i in range(Nscheme):
... use i rather than i - 1

(I assume Visual Basic for loops are off by one).

In fact, this loop is even better if you just iterate over lanex
itself. Using a loop index rather than iterating directly is a common
mistake.

for lane in lanex:
avcclass.append(lane.rjust(5, '0'))
Nlanex.append(int(lane))

Or even better, use list comprehensions to construct your two lists
explicitly:

avcclass = [lane.rjust(5, '0') for lane in lanex]
Nlanex = [int(lane) for lane in lanex]

Note, each rewrite makes the intention of the code clearer, as well as
being shorter. This makes your code easier to read and understand, and
less buggy.


Since all you do with avcclass is sum it, combine this with the
classsum optimisation above to get

classsum = ''.join(lane.rjust(5, '0') for lane in lanex[:14])
Nlanex = [int(lane) for lane in lanex]
lanex = []
if numlanes == 2:
lane1 = newlist1[2:2+Nscheme]
lanex.append(lane1)
lane2 = newlist1[2+Nscheme:2+Nscheme*2]
lanex.append(lane2)
else:
lane1 = newlist1[2:2+Nscheme]
lanex.append(lane1)
lane2 = newlist1[2+Nscheme:2+Nscheme*2]
lanex.append(lane2)
lane3 = newlist1[2+Nscheme*2:2+Nscheme*3]
lanex.append(lane3)
lane4 = newlist1[2+Nscheme*3:2+Nscheme*4]
lanex.append(lane4)

List comprehensions beat copy/paste:

total_schemes = 2 if numlanes == 2 else 4
lanex = [newlist1[2 + i * Nscheme:2 + (i + 1) * Nscheme]
for i in range(total_schemes)]

HTH, and welcome to python!
 
B

Ben Finney

Roberto Bonvallet said:
[...] where I start getting some errors.
I'm hoping I won't have to post my code

"Doctor, I'm feeling bad. I hope I won't have to tell you my
symptoms. What do I have?"

Please provide the actual errors and the actual code. It is easier,
less error prone and more useful to copy and paste them instead of
writing some pseudocode.

Far better is to ask the querent to provide a minimal example that
demonstrates the problem.

"Minimal" in this case means "if I take away any part of this code,
the described behaviour no longer occurs". While that's not true, keep
whittling away at the example code until it *is* true, so we know that
all the code is necessary to repeat the problem.

Only then should you post the code — if, of course, you haven't yet
seen the solution with your own eyes.
 
M

metawilm

Since those variables are local to the for loop,

No, "for" loops don't introduce a scope. The one variable named "j" is
shared.
for j in range( 10 ):
print j, "first loop"
for j in range( 5 ):
print " ", j, "2nd loop"

The reason it does work as hoped, is that the generators, including
those created by the call to "range", keep internal state to know the
next value to yield. The existence or current value of iteration
variables like "j" is completely irrelevant.

Here, the first the call to "range" creates a generator, and binds j
to the first value yielded, which is 0. Then the second range-
generator is created, iterated over using the same variable. Then the
first generator is asked for its second value (= 1), and j is bound to
that regardless its current value.

- Willem
 
Z

Zentrader

Scope had to do with "visibility" and not with how memory was
allocated. Scope means, can this line of code access that block of
memory. Note that in list comprehension, [x for x in (1, 2, 3)], the
for loop allocates memory the same way, but the scope changes so that
"x" is visible outside the for loop, so I guess we will have to agree
to disagree.
 
M

metawilm

Note that in list comprehension, [x for x in (1, 2, 3)], the
for loop allocates memory the same way, but the scope changes so that
"x" is visible outside the for loop,

How is this different? The variable spilling of list comprehension is
the same as for regular for loops. The (#) and (##) lines below don't
print the same value of j.
.... print j, "first loop" (#)
.... for j in range(3):
.... print " ", j, "2nd loop"
.... print j, "first loop, again?" (##)


- Willem
 
G

Gabriel Genellina

Note that in list comprehension, [x for x in (1, 2, 3)], the
for loop allocates memory the same way, but the scope changes so that
"x" is visible outside the for loop,

How is this different? The variable spilling of list comprehension is
the same as for regular for loops.

The fact that list comprehensions "leak" its loop variable is an
unfortunate accident and will be corrected in Python 3.0
The (#) and (##) lines below don't
print the same value of j.

... print j, "first loop" (#)
... for j in range(3):
... print " ", j, "2nd loop"
... print j, "first loop, again?" (##)

Because neither list comprehensions nor for loops start a new scope. j is
a global here, might be local to the enclosing function if any. Anyway,
all j's are the same variable.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top