Skip to content

Conversation

@hachterberg
Copy link

Renames the hyphen to underscores as #152 and #172 suggest. I am not sure if I caught all the references to the files, but I used grepping the .md and code/.py to check for references.

@hachterberg hachterberg changed the title Feature/rename hypen modules Rename python files in code not to have hyphens Mar 25, 2016
@iglpdc
Copy link
Contributor

iglpdc commented Mar 25, 2016

The naming using dashes instead of underscores is intentional to prevent the module from being imported.

Python does not make any difference between modules (just .py files) that contain code meant to be directly executed (generally called scripts) or code meant to be imported (generally called libraries). Any Python module can be executed (python my_module.py) or imported (python -c "import my_module.py").

To prevent code from being imported you can change the PEP8-recommended _ to -, so python my-script.py still works, but python -c "import my-script.py" does not, as the - is interpreted as the minus sign.

The reason you may want certain files to not being "importable" is because there should be nothing useful to import in your scripts. See, for example, one of the scripts you are renaming:

$ cat code/argv_list.py
import sys
print('sys.argv is', sys.argv)

This code is meant to be executed, not imported and, in fact, fails when you import it.

In other cases it could be even worse, the code in code/gen_inflammation.py defines some variables module variables that would be made it to the global space and pollute it if you import it.

So, in general, importing a module should not execute code and therefore the - in the name.

I learned this from @ctb, so maybe he wants to add some comments or references.

@tbekolay
Copy link
Contributor

If we're worried about importing, why not a little block like:

if __name__ != '__main__':
    raise ImportError("Don't import this file; run it from the shell instead.")

at the top of the file?

@ctb
Copy link

ctb commented Mar 25, 2016

@tbekolay, the - is a visual convention that prevents people from thinking that scripts are modules that can be imported and then trying to import them. If there are scripts that should never be imported, it should be fine to name them with a - in there, right? This is a convention I've seen elsewhere in the Python world, but google doesn't do a good job of finding '-' ;).

(@iglpdc, in general I don't think we should be teaching 'from gen_inflammation import *' anyway, which is the only way namespaces would be polluted.)

@tbekolay
Copy link
Contributor

Hm... this is a convention that I've never heard before, so I would be interested to see examples of it; the only things I can find through googling is people asking how to import python scripts with hyphens (which is possible with __import__ or importlib, apparently). If it's a thing then we should add a note to the instructor guide or somewhere else stating why we do it.

@iglpdc
Copy link
Contributor

iglpdc commented Mar 25, 2016

(@iglpdc, in general I don't think we should be teaching 'from gen_inflammation import *' anyway, which is the only way namespaces would be polluted.)

@ctb Sure! The main point is that importing modules that execute code may side effects and this is not what people expects.

@tbekolay The standard way would be to enclose your script code into a main function and then call this function inside the conditional. This allows you have both a module and a script, in case when the code could be used both ways. However, this adds a few lines of cryptic code, so for small scripts that contain no reusable code at all, I think it's better to use the - in the name.

I think that having scripts with really long names is characteristic of scientific settings and maybe that's why it's no many Python references around.

@hachterberg
Copy link
Author

@iglpdc I think the __name__ == '__main__' construct is a bit cryptic for new users, but very very useful, because it enables you to create command line tools that have reusable parts. When I started I didn't realize this, but now I almost always do it automatically when I create a new script.

As I guess you all know, the most pythonic whay would be to embed scripts like:

def main():
    pass  # actual script here

if __name__ == '__main__':
    main()

but the question is, do we want to teach that to students or not? Maybe it is good to mention somewhere that importing a module executes the code? That is a valid warning to give when teaching students about import statements.

I think the hyphen is a poor substitute for the proper construct, so I would vote to either let it be importable (even though there is no reason to do so and it can have strange effects) or to use a proper way avoid it from accidental execution on import.

@tbekolay
Copy link
Contributor

I would say that very few novice workshops get to this topic anyhow, so I'm not too concerned about one line being a little cryptic if we have a callout box explaining it.

In any case, this is more contentious than I was expecting, so it probably warrants some additional comments. Looking back at the topic itself, most of the files already factor the code into a main function, so it would just be the addition of the if __name__ == '__main__': line, and possibly a callout box explaining what that line does.

@iglpdc
Copy link
Contributor

iglpdc commented Mar 25, 2016

Looking back at the topic itself, most of the files already factor the code into a main function, so it would just be the addition of the if name == 'main': line, and possibly a callout box explaining what that line does.

That's true. We could use underscores, main functions in the readings scripts and a call-out box "Why the main function" explaining the difference between a "script" module and a "library" module.

In any case, I think it's more important to be truthful to the language (import should not have side effects) that to PEP 8, which is just an style guide.

@ctb
Copy link

ctb commented Mar 26, 2016

Re dashes vs underscores vs..., Twitter conversation here --

https://twitter.com/ctitusbrown/status/713365613113028608

The most interesting bits are:

Anyway, I guess that's a -1 on teaching it as best practice...

@tbekolay tbekolay merged commit dae6441 into swcarpentry:gh-pages Jun 22, 2016
@tbekolay
Copy link
Contributor

I've merged this now, and added commits to add if __name__ == '__main__' blocks, a callout explaining that, and an entry in the Frequently Argued Issues in the instructor's guide pointing to this discussion.

rgaiacs pushed a commit to rgaiacs/swc-python-novice-inflammation that referenced this pull request May 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants