Python Forum
Thread Rating:
  • 1 Vote(s) - 1 Average
  • 1
  • 2
  • 3
  • 4
  • 5
more looping help?
#1
Hi,

I have another forLoop question if I may.

I want to loop through this line of code,
os.makedirs('.\\' + str(year) + '-01')
where with each iteration this part,
'-01'
increases by +1 integer and stops at 12.

Considering the many parts of that code line, I'm not sure how to do that.
Any ideas?
Thanks,
Phil Huh
Reply
#2
import os
year = 2018
for month in range(1, 13):
    folder = '{}-{:0>2}'.format(year, month) # folder = folder = f'{year}-{month:0>2}' # in 3.6+
    os.makedirs(os.path.join('.', folder))
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#3
for month in range(1, 13):
    folder = folder = f'{year}-{month:0>2}'
    os.makedirs(os.path.join('.', folder))
Thanks Buran. That worked.
Can you explain the code to me and, more importantly, your thought process to arrive at this code?
* How do I get past the point of just staring at a blank screen having no real idea how to start?
* Where did month come from? It's not a variable like 'year' which uses the datetime module.
* Why is the f-string using 2 folder-equals (folder = folder = f')? I've never seen that.
* What are you joining with os..join? What is the '.' pointing to, current folder? If so, where's the backslash (.\)?

Thanks for the help.
I quickly (for me Pray ) coded up a script to create a complete folder-subfolder structure for a tax year. This will be a yearly time saver and I'm quite proud of myself Dance LOL
Phil

BTW, for anybody here for future reference.

required dependencies:
import os
import datetime
year = datetime.now().year
The above forLoop replaces these lines of code:
os.makedirs('.\\' + str(year) + '-01')
os.makedirs('.\\' + str(year) + '-02')
os.makedirs('.\\' + str(year) + '-03')
os.makedirs('.\\' + str(year) + '-04')
os.makedirs('.\\' + str(year) + '-05')
os.makedirs('.\\' + str(year) + '-06')
os.makedirs('.\\' + str(year) + '-07')
os.makedirs('.\\' + str(year) + '-08')
os.makedirs('.\\' + str(year) + '-09')
os.makedirs('.\\' + str(year) + '-10')
os.makedirs('.\\' + str(year) + '-11')
os.makedirs('.\\' + str(year) + '-12')
Phil
Reply
#4
first of all it's my mistake. it should be
for month in range(1, 13):
    folder = f'{year}-{month:0>2}'
    os.makedirs(os.path.join('.', folder))
just FYI, this folder = folder = f'{year}-{month:0>2}' is called multiple assignments and in fact it's equivalent to execute:

folder = f'{year}-{month:0>2}'
folder = f'{year}-{month:0>2}'
in general case if you want assign value to both foo and bar variables you can do foo = bar = value
>>> foo = bar = 'some value'
>>> foo
'some value'
>>> bar
'some value'
>>>
(Oct-01-2018, 09:15 AM)pcsailor Wrote: * How do I get past the point of just staring at a blank screen having no real idea how to start?
well, I guess it's the experience. In general case you need to have algorithm (i.e. what and how you want to do). In this case - you have single year, and want to iterate over months (finite number of iterations over pre-defined range of numbers). So it suggest using for loop. you want certain format of the folder name, so using string formatting mini-language is self-evident.
(Oct-01-2018, 09:15 AM)pcsailor Wrote: * Where did month come from? It's not a variable like 'year' which uses the datetime module.
both year and month are variables/names. Neither comes from datetime module. you can and should use any [descriptive] name you like.
(Oct-01-2018, 09:15 AM)pcsailor Wrote: * Why is the f-string using 2 folder-equals (folder = folder = f')? I've never seen that.
that's my mistake. see correct code above
(Oct-01-2018, 09:15 AM)pcsailor Wrote: * What are you joining with os..join? What is the '.' pointing to, current folder? If so, where's the backslash (.\)?
'.' it will point to same folder where it points to in your code. os.path.join just creates the proper path given the OS using os-specific correct separator.
By the way, if you are going to use datetime module, this will also work

import os
from datetime import date
today = date.today()
for month in range(1, 13):
    folder = today.replace(month=month).strftime('%Y-%m')
    os.makedirs(os.path.join('.', folder))
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#5
To elaborate more on the origin of the "month" variable, for loops instantiate a variable when used. So

for month in range(1, 13):
instantiates the variable "month" and assigns the variable to the number for that loop. In effect it assigns month to 1 for the first iteration of the loop, reassigns it to 2 for the second iteration, etc.

Likewise, if we iterate over an iterable such as a list:

for month in ["Jan", "Feb", "Mar", "Apr", "May", ...]:
then it would assign month to "Jan" for the first iteration, reassign to "Feb" for the second iteration, etc.

Because of this behavior, we can use the variable within the loop, as buran did, and it will always use the current assigned value for the variable.
Reply
#6
(Oct-02-2018, 12:05 AM)stullis Wrote:
for month in ["Jan", "Feb", "Mar", "Apr", "May", ...]:
then it would assign month to "Jan" for the first iteration, reassign to "Feb" for the second iteration, etc.

Because of this behavior, we can use the variable within the loop, as buran did, and it will always use the current assigned value for the variable.

That is cool as f!!!. Have I completely missed this in forLoops?? So Python creates a variable with an iterated assignment value when you place an unknown name in the forLoop? Has JavaScript(JS) always done that? I was new and doing JS before Python and don't remember that with JS either.
Have these languages always done this type of variable assignment & I've completely missed it?

Thanks,
Phil
Reply
#7
(Oct-03-2018, 05:05 AM)pcsailor Wrote: That is cool as f!!!. Have I completely missed this in forLoops?? So Python creates a variable with an iterated assignment value when you place an unknown name in the forLoop? Has JavaScript(JS) always done that? I was new and doing JS before Python and don't remember that with JS either.
Have these languages always done this type of variable assignment & I've completely missed it?


Well, that is one of the main characteristics of a loop. If you missed that...
https://en.wikipedia.org/wiki/Control_flow#Loops

Given that in python everything is an object, the for loop in python is technically foreach (as per classification described in the wiki) even if they give an example also in for loop article. Also native way to loop over container objects is to directly iterate over objects, not using index to retrieve (i.e. loop with counter and then use the counter value to retrieve specific object from the container).

also note that you may reuse a name, doesn't have to be unknown one. Yiu can even use a undescore. By convention that means you don't care about the value, e.g. you just want to repeat loop body certain number of times.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#8
Or you can use several names in the loop. Two examples:

for number, key, value in enumerate(my_dictionary.items(), 1):
    print(number, key, value)
for _ , _ , files in os.walk(path):
    print(files)
os.walk walks through a directory tree and return a current directory, directories list and the files list in that directory or subdirectory in the path in that order. In this case, I do not care about the directory/subdirectory it walks through either the directory list. I want just the to know the files so I use underscore for the first two names and ignore them.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020