8
\$\begingroup\$

I have always been into HTML and CSS so I decided to give programming a try. I installed Python because I heard it is the best first programming language. So I made this program just now and I'm super excited and happy about it. I would like to have your criticism or feedback and tell me how I can make it better or add more functionality to it.

import os

name = input("Enter the name of your project here: ");

os.makedirs(name);

os.chdir(name);

os.makedirs('css');
os.makedirs('resources');

os.chdir('resources');

os.makedirs('img');
os.makedirs('js');

os.chdir('../');

html = input("Enter name of html file: ")+".html";
open(html, 'a');

os.chdir('css');

css = input("Enter name of css file: ")+".css";
open(css, 'a');
\$\endgroup\$
1
  • \$\begingroup\$ Definitely remove all of those semicolons. Semicolons are only used when separating multiple statements on the same line. \$\endgroup\$
    – mbomb007
    Apr 6, 2017 at 21:34

4 Answers 4

8
\$\begingroup\$

I think it would be nice, if you could define the directory structure once and then let the program create it. Something like this:

import os

folders = ["css", "resources/img", "resources/js"]

name = input("Enter the name of your project here: ")
for folder in folders:
    os.makedirs(os.path.join(name, os.path.normpath(folder)))
os.chdir(name)
...
# file opening like Peilonrayz suggested

This uses a list and os.path.join, which allows joining filenames with the platform specific file name separator (\ for Windows, / for UNIX), os.path.normpath to convert the / in the path to \ in case you are on Windows and it also uses a for-loop, if you have not seen them, yet.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you ! A bit advanced for me but I'll try and understand it \$\endgroup\$ Apr 6, 2017 at 16:59
2
\$\begingroup\$

I would put the code for creating the new directory structure in a function (Using @Peilonrayz suggestions):

def create_web_directory_structure(project_name, html_name, css_name):
    os.makedirs(project_name)
    os.chdir(project_name)
    os.makedirs('css')
    os.makedirs('resources')
    os.chdir('resources')
    os.makedirs('img')
    os.makedirs('js')
    os.chdir('../')

    with open(html_name, 'a'):
        pass

    os.chdir('css')

    with open(css_name, 'a'):
        pass

This is a basic but very useful concept, separation of input and program operation.

You can use this function by asking the information piecewise, to the user, like you did before:

create_web_directory_structure(
    input("Project name? "),
    input("html name? "),
    input("css name? ")
)

But you can also run it with command line arguments:

webdir.py pong pong_code pong_style

with the code being:

import sys
create_web_directory_structure(*sys.argv)

Or even other examples, you could get input from a Graphical User Interface, or calculated from another part of the program, all this flexibility because input is separated from further processing.

\$\endgroup\$
2
\$\begingroup\$

When I write code, I try to avoid doing chdir(). One important thing to note about the current working directory is that it is a kind of global state for your process — similar to global variables.

To understand what your code actually does, you have to mentally keep track of the changes to the current directory, so that you can know, for example, that os.makedirs('js') really means os.makedirs('name/resources/js').

In a large program where the flow is non-linear, it can be very difficult to trace what the current directory is, if you are frequently jumping around. In a multithreaded program, it would be even worse: changing the directory affects all threads in the process.

One way to avoid chdir() is to take advantage of os.makedirs(), which can create multiple levels of directories as needed. You're just using it as os.mkdir().

If you do change directories, try to do so in a logical and responsible manner. For example, try to return to the original directory as soon as you are done; don't end up in the css directory, for example.

Make it a habit to always call open() in the context of a with block, to ensure that the file descriptor gets closed, not leaked.

Below, I have organized the code for readability, such that all of the input is done together, and all of the file operations are done together. The two functions help make that possible. (Note that this is not exactly equivalent to your code. If you hit CtrlC at the second prompt, my program has no effect, but yours will have already created the directory structure.)

import os

def make_project_dirs(project_name):
    for d in ('css', 'resources/img', 'resources/js'):
        os.makedirs(os.path.join(project_name, d))

def touch(path):
    with open(path, 'a'):
        pass

name = input("Enter the name of your project: ")
html = input("Enter the name of HTML file: ")
css = input("Enter the name of CSS file: ")

make_project_dirs(name)
touch(os.path.join(name, html + '.html'))
touch(os.path.join(name, 'css', css + '.css'))
\$\endgroup\$
1
\$\begingroup\$

Python is a good first language, I personally would advise it over; C, C++, C#, and Java. But each language is better at some things than others. And your program would be better written in Bash/Fish/zsh/sh on Linux/MacOS or Batch/PowerShell on Windows. And so you'd instead want to use something like:

$name = Read-Host 'Enter the name of your project here'
$html = Read-Host 'Enter name of html file'
$css = Read-Host 'Enter name of css file'
mkdir "$name"
mkdir "$name/css"
mkdir "$name/resources"
mkdir "$name/resources/img"
mkdir "$name/resources/js"
echo $null >> "$name/$html.html"
echo $null >> "$name/css/$css.css"

However, you're learning Python, and telling you to learn something else is not what you want. Python wise, I'd use with so that you automatically close the file, rather than leave the file open. You also want to drop all your semi-colons, they're not needed and it's recommended to not use them. And so I'd use:

import os

name = input("Enter the name of your project here: ")
os.makedirs(name)
os.chdir(name)
os.makedirs('css')
os.makedirs('resources')
os.chdir('resources')
os.makedirs('img')
os.makedirs('js')
os.chdir('../')

html = input("Enter name of html file: ")+".html"
with open(html, 'a'):
    pass

os.chdir('css')

css = input("Enter name of css file: ")+".css"
with open(css, 'a'):
    pass
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.