Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialhamsternation
26,616 PointsAm I tackling this directory renaming problem correctly?
Prompt: Finish the function named cleanup in consistency.py. This function should take a string which will be a path to a local directory. The file names in this directory are messy. I need you to clean them up so they all follow the same pattern. Examples and further explanation are in the comments in the file below.
My code:
import os
import re
import dateutil.parser
import datetime
# Filenames consist of a username (alphanumeric, 3-12 characters)
# and a date (four digit year, two digit month, two digit day),
# and an extension. They should end up in the format
# year-month-day-username.extension.
# Example: kennethlove2-2012-04-29.txt becomes 2012-04-29-kennethlove2.txt
def cleanup(path):
for name in os.listdir(path):
# parse out username from file name
username = re.search(r'[\w\d]*\d{3-12}', name).group()
# parse out time from filename:
re_time_search = re.search(r'\d{2,4}-\d{2,4}-\d{2,4}', name).group()
# reformats parsed out time into YYYY-MM-DD format and save it as date variable
date = dateutil.parser.parse(re_time_search).strftime('%Y-%m-%d')
# parse out extension from file, alphanumeric allowed (.mp3, etc)
ext = re.search(r'\.[\w\d]*', name).group()
rename = date + '-' + username + '-' + ext
os.rename(os.path.join(path, name), os.path.join(path, rename))
so my code lists the files in the path
directory and parses out the username, date, and ext of the filenames, then renames them using the os.rename
function.
The challenge returns the error
AttributeError: 'NoneType' object has no attribute 'group'
which means one of the re.search
functions didn't find a match.
So my question is, do all the files in the directory have a username, date, AND extension? are there subdirectories in the directory?
Not sure what I'm doing wrong here... please help?
5 Answers
frederikbussler
17,555 PointsTo better understand the problem I created a dummy directory (path) with a few dummy files (name). (Note: your datetime import is unused)
Your username parsing line is wrong. You can test it out on the string "kennethlove2-2012-04-29.txt" and you'll get zero matches. I found it was easier to use regex just for the date. Slicing is a much simpler way to find the extension and then the username.
Here's my working code, read all the comments:
# -*- coding: utf-8 -*-
"""
@author: Frederik Bussler
"""
import datetime
import os
import re
# Filenames consist of a username (alphanumeric, 3-12 characters)
# and a date (four digit year, two digit month, two digit day),
# and an extension. They should end up in the format
# year-month-day-username.extension.
# Example: kennethlove2-2012-04-29.txt becomes 2012-04-29-kennethlove2.txt
def cleanup(path):
for name in os.listdir(path):
# find the date in the pre-formatted file name
orig_date = re.search(r'\d{4}-\d{2}-\d{2}', name)
# format the date correctly
formatted_date = datetime.datetime.strptime(orig_date.group(), '%Y-%m-%d').date()
# the file extension is the last 4 characters (i.e. .txt)
ext = str(name[-4:])
# concatenate new string as date with a dash plus username plus extension
# username is found by slicing name up to index of dash (start of date)
new_str = str(formatted_date) + "-" + str(name[:name.index('-')]) + ext
# rename files, make sure to join path with file name
os.rename(os.path.join(path, name), os.path.join(path, new_str))
merc1er
6,329 PointsHi all!
Could you please let me know what is wrong with the following code (tested locally and worked but it won't work in the challenge):
import os
def cleanup(path):
cdir = os.listdir(path)
for f in cdir:
name, ext = os.path.splitext(f)
pseudo = name[0:-11:1]
date = name[-1:13:-1][::-1] + '-'
os.replace(f, date + pseudo + ext)
Thank you
Lawerence Lee
19,912 PointsThings of note regarding this challenge:
- The dates are indeed in YYYY-MM-DD format. If Kenneth had tried to trick you by including variants such as DD-MM-YYYY or MM-DD-YYYY, there wouldn't be any way for you to tell the difference between the formats. Case in point 12-11-2017 is valid for both variants I mentioned.
-
Using the RE library is allowed and worked for me.
- Here's a Python Regex cheatsheet if you need one.
TIP: Try and test your code using your terminal emulator (command line) and your actual file system.
- Create a
directory
, you can delete it later.
-
Fill it with variations of both the correct and incorrect formatting.
- You could do this with the following script:
files = ['2012-04-29-kennethlove2.txt', 'kennethlove2-2012-04-29.txt', 'philip34king-1312-12-05.zip', 'osk18ear55-2354-12-08.jpeg'] for a_file in files: os.system('touch {}'.format(a_file))
Provide the path to that directory as the argument for the cleanup function.
I'll leave the rest up to you...
Lynn Collins
10,080 PointsI hate to say it, but Kenneth is really starting to annoy me big time!!! He's so confusing and I think he forgets some of us aren't like him. Anyway, here's my attempt: def cleanup(path): cdir = os.listdir(path) for f in cdir: name, ext = os.path.splitext(f) pseudo = name[0:-11:1] date = name[-1:13:-1][::-1] + '-' os.replace(f, date + pseudo + ext) So what's wrong with it???
Lynn Collins
10,080 Pointsdef cleanup(path): cdir = os.listdir(path) for f in cdir: name, ext = os.path.splitext(f) pseudo = name[0:-11:1] date = name[-1:13:-1][::-1] + '-' os.replace(f, date + pseudo + ext)
files = ['2012-04-29-kennethlove2.txt', 'kennethlove2-2012-04-29.txt', 'philip34king-1312-12-05.zip', 'osk18ear55-2354-12-08.jpeg'] for a_file in files: os.system('touch {}'.format(a_file))files = ['2012-04-29-kennethlove2.txt', 'kennethlove2-2012-04-29.txt', 'philip34king-1312-12-05.zip', 'osk18ear55-2354-12-08.jpeg']
HELP ME!
Stephen Lorenz
3,271 PointsStephen Lorenz
3,271 PointsThat's pretty cool! Why can we use str(formatted_date) though? I thought we'd need to use strftime()