Critic my module

  • Thread starter Devyn Collier Johnson
  • Start date
D

Devyn Collier Johnson

Aloha Python Users!

I made a Python3 module that allows users to use certain Linux shell
commands from Python3 more easily than using os.system(),
subprocess.Popen(), or subprocess.getoutput(). This module (once placed
with the other modules) can be used like this

import boash; boash.ls()

I attached the module. I plan to release it on the Internet soon,
but feel free to use it now. It is licensed under LGPLv3.

The name comes from combining "Boa" with "SHell". Notice that the
module's name almost looks like "BASH", a common Linux shell. The Boa is
a constrictor snake. This module makes Unix shells easier to use via
Python3. This brings the system shell closer to the Python shell.


Mahalo,

Devyn Collier Johnson
(e-mail address removed)
 
A

Alain Ketterlin

Devyn Collier Johnson said:
I made a Python3 module that allows users to use certain Linux
shell commands from Python3 more easily than using os.system(),
subprocess.Popen(), or subprocess.getoutput(). This module (once
placed with the other modules) can be used like this

Good, but I doubt it's really useful: I think nobody is going to add a
dependency on your module for, basically, one-line wrappers...

Here are a few comments:
def ls():
version = '0.3'
print(subprocess.getoutput('ls'))

version is local here, so basically your first statement is useless
(search for "global" in python's language ref).
def uname():
version = '0.3'
print(platform.uname())

I once learned: "never print anything in a library function". This is a
bad thing to do, for a variety of reasons. For instance, stdout may be
redirected during this call...
def man(x):
version = '0.3'
print(subprocess.getoutput('man' + x))

getoutput is (essentially) Popen(...,shell=True), and the doc says:

"the use of shell=True is strongly discouraged in cases where the
command string is constructed from external input"

(for very good reasons)
def clear_bash_history():
version = '0.3'
print(subprocess.getoutput('history -c'))

Who told you subprocess will use bash? Again, the doc:

"On Unix with shell=True, the shell defaults to /bin/sh."

All your uses of bash-isms may break (esp. "!!")
def firefox():
version = '0.3'
print(subprocess.Popen('(firefox &)'))

See section "Replacing the os.spawn family" in... the doc.
def go_back():
version = '0.3'
print(subprocess.Popen('cd !!:1'))

Hopeless. Have you tried this?
def reboot():
version = '0.3'
print(subprocess.Popen('shutdown -r now'))

What do you expect this to print? I mean, after shutdown/reboot.
version = '0.6b'

So, what's the version? 0.3 or 0.6b

(btw, are you sure this "version" is the same as the one you use in all
functions?).

-- Alain.
 
D

Devyn Collier Johnson

Good, but I doubt it's really useful: I think nobody is going to add a
dependency on your module for, basically, one-line wrappers...

Here are a few comments:

version is local here, so basically your first statement is useless
(search for "global" in python's language ref).

I once learned: "never print anything in a library function". This is a
bad thing to do, for a variety of reasons. For instance, stdout may be
redirected during this call...

getoutput is (essentially) Popen(...,shell=True), and the doc says:

"the use of shell=True is strongly discouraged in cases where the
command string is constructed from external input"

(for very good reasons)

Who told you subprocess will use bash? Again, the doc:

"On Unix with shell=True, the shell defaults to /bin/sh."

All your uses of bash-isms may break (esp. "!!")

See section "Replacing the os.spawn family" in... the doc.

Hopeless. Have you tried this?

What do you expect this to print? I mean, after shutdown/reboot.

So, what's the version? 0.3 or 0.6b

(btw, are you sure this "version" is the same as the one you use in all
functions?).

-- Alain.

The version in each function is the version of that function if users
want to know what version they are using. The last version is for the
whole module. The module overall is version 0.6b. The module started
with a few functions and as I increased the number of functions, I
increased the module version number. It is a coincidence that all of the
modules happen to have the same version number. I increase the version
number after I work on a function. I cannot remember the command to
print a module's/function's version number, but with that command, you
could see the version of a particular function or module. No, I have not
tried go_back(), thank you for catching that.

The main point of this is for shell users that are using Python and do
not know some of the Python commands. This module would make Python more
like a Linux shell. For instance, a shell user would type boash.uname()
because they may not know they can type "import platform; platform.uname()".

I know that printing is not really the best of ideas, but how else can I
make the output be displayed without quotes or newline marks?

Thank you very much Alain Ketterlin for your feedback!

Mahalo,

DCJ
 
J

Joshua Landau

But they will know how to import your module?

to be honest I think this module is a solution looking for a problem &
you have re-invented the wheel (Square).
don't let that put you off, there are many command line tools that could
do with a good wrapper to make them easier to use,perhaps you are tryingto
be too general.


I actually think
http://plumbum.readthedocs.org<http://plumbum.readthedocs.org/en/latest/>
, http://sarge.readthedocs.org and http://amoffat.github.io/sh/ do a really
good job at this. I might one day even try them ;).
 
S

Steven D'Aprano

As requested, some constructive criticism of your module.

#!/usr/bin/python3
#Made by Devyn Collier Johnson, NCLA, Linux+, LPIC-1, DCTS

What's NCLA, Linux+, LPIC-1, DCTS? Do these mean anything? Are we
supposed to know what they mean?

"Made by" has no legal significance. You probably want:

Copyright © 2013 Devyn Collier Johnson.

#Made using the Geany IDE

Nobody gives a monkey's toss what editor you used to type up the module.
You might as well mention the brand of monitor you used, or whether the
keyboard is Dvorak or Qwerty.


You can't just drop in a mention of "LGPLv3" and expect it to mean
anything. You actually have to obey the licence yourself, and that
includes *actually including the licence in your work*. (You're
technically in violation of the licence at the moment, however since the
only person whose copyright you are infringing is yourself, it doesn't
matter. However anyone else using your code is at risk.)

http://www.gnu.org/licenses/gpl-howto.html

In the case of the LGPL, you have to include the text of *both* the GPL
and the LGPL, not just one.


import re, sys, subprocess, platform
def grep(regex,textf):
#Sample Command: grep.grep("^x",dir()) #Syntax:
boash.grep(regexp_string,list_of_strings_to_search)

Comments using # are only of use to people reading the source code. If
you want comments to be available at the interactive prompt, you should
write them as doc strings:

def grep(regex, textf):
"""This string is a docstring.

Sample command: ...
Blah blah blah
"""

Then, at the interactive prompt, the user can say:

help(boash.grep)

to read the docstring.

version = '0.2a'

That's quite useless, since it is a local variable invisible outside of
the function.

Also, why would you bother giving every individual function a version
number? That's rather pointless. The user cannot pick and choose function
A with version number 0.6 and function B with version number 0.7 if the
module provides versions 0.7 of both.

expr = re.compile(regex)
match = re.findall(expr, textf)
if match != None:
print(match)

When comparing with None, it is preferred to use "is" and "is not" rather
than equality tests.

def ls():
version = '0.3'
print(subprocess.getoutput('ls'))
def dir():
version = '0.3'
print(subprocess.getoutput('dir'))

A blank line or two between functions does wonders for readability. There
is no prize for conserving newlines.

You might like to read PEP 8, the Python style guide. It is optional, but
still makes a very good guide.

http://www.python.org/dev/peps/pep-0008/

def bash(*arg):
version = '0.3'
print(subprocess.getoutput(arg))
def shell(*arg):
version = '0.3'
print(subprocess.getoutput(arg))

bash is not a synonym for "shell". "The shell" might be sh, csh, bash, or
any one of many other shells, all of which are slightly (or not so
slightly) different.

def clear_bash_history():
version = '0.3'
print(subprocess.getoutput('history -c'))
[...]

Do you really need ten aliases for 'history -c'?

If you want to define aliases for a function, don't recreate the entire
function ten times. Start with defining the function once, then:

clear_bash_hist = clear_hist = clear_history = clear_bash_history

etc. But really, having ten names for the one function just confuses
people, who then wonder what subtle difference there is between
delete_history and clear_history.
def firefox():
version = '0.3'
print(subprocess.Popen('(firefox &)'))

Is Firefox really so important that it needs a dedicated command?

What about Debian users? Doesn't Iceweasel get a command?

def xterm():
version = '0.3'
print(subprocess.Popen('(xterm &)'))

Surely the user already has an xterm open, if they are running this
interactively? Why not just use your xterm's "new window" or "new tab"
command?


[...delete more trivial calls to subprocess...]
def repeat_cmd():
version = '0.3'
print(subprocess.Popen('!!'))
[... delete two exact copies of this function...]
def ejcd():
version = '0.3'
print(subprocess.Popen('eject cdrom1'))
[... delete FOURTEEN exact copies of this function...]

Really? Is anyone going to type "eject_disc_tray" instead of "eject"?


I think that will do.

This doesn't really do anything except define a large number of trivial
wrappers to commands already available in the shell. Emphasis on the
*trivial* -- with the exception of the grep wrapper, which is all of four
lines (ignoring the useless internal version number), every single one of
these wrapper functions is a one-liner.[1] In other words, you're not
adding any value to the shell commands by wrapping them in Python. There
are plenty of big, complex shell commands that take a plethora of options
and could do with some useful Python wrappers, like wget. But you haven't
done them.

Nor have you added extra security, or even extra convenience. You've done
nothing that couldn't be done using the shell "alias" command, except in
Python where the syntax is less convenient (e.g. "ls" in the shell,
versus "ls()" in Python).




[1] I think every newbie programmer goes through a stage of pointlessly
writing one-liner wrappers to every second function they see. I know I
did. The difference is, before the Internet, nobody did it publicly.
 
D

Devyn Collier Johnson

As requested, some constructive criticism of your module.

#!/usr/bin/python3
#Made by Devyn Collier Johnson, NCLA, Linux+, LPIC-1, DCTS
What's NCLA, Linux+, LPIC-1, DCTS? Do these mean anything? Are we
supposed to know what they mean?

"Made by" has no legal significance. You probably want:

Copyright © 2013 Devyn Collier Johnson.

#Made using the Geany IDE
Nobody gives a monkey's toss what editor you used to type up the module.
You might as well mention the brand of monitor you used, or whether the
keyboard is Dvorak or Qwerty.

You can't just drop in a mention of "LGPLv3" and expect it to mean
anything. You actually have to obey the licence yourself, and that
includes *actually including the licence in your work*. (You're
technically in violation of the licence at the moment, however since the
only person whose copyright you are infringing is yourself, it doesn't
matter. However anyone else using your code is at risk.)

http://www.gnu.org/licenses/gpl-howto.html

In the case of the LGPL, you have to include the text of *both* the GPL
and the LGPL, not just one.


import re, sys, subprocess, platform
def grep(regex,textf):
#Sample Command: grep.grep("^x",dir()) #Syntax:
boash.grep(regexp_string,list_of_strings_to_search)
Comments using # are only of use to people reading the source code. If
you want comments to be available at the interactive prompt, you should
write them as doc strings:

def grep(regex, textf):
"""This string is a docstring.

Sample command: ...
Blah blah blah
"""

Then, at the interactive prompt, the user can say:

help(boash.grep)

to read the docstring.

version = '0.2a'
That's quite useless, since it is a local variable invisible outside of
the function.

Also, why would you bother giving every individual function a version
number? That's rather pointless. The user cannot pick and choose function
A with version number 0.6 and function B with version number 0.7 if the
module provides versions 0.7 of both.

expr = re.compile(regex)
match = re.findall(expr, textf)
if match != None:
print(match)
When comparing with None, it is preferred to use "is" and "is not" rather
than equality tests.

def ls():
version = '0.3'
print(subprocess.getoutput('ls'))
def dir():
version = '0.3'
print(subprocess.getoutput('dir'))
A blank line or two between functions does wonders for readability. There
is no prize for conserving newlines.

You might like to read PEP 8, the Python style guide. It is optional, but
still makes a very good guide.

http://www.python.org/dev/peps/pep-0008/

def bash(*arg):
version = '0.3'
print(subprocess.getoutput(arg))
def shell(*arg):
version = '0.3'
print(subprocess.getoutput(arg))
bash is not a synonym for "shell". "The shell" might be sh, csh, bash, or
any one of many other shells, all of which are slightly (or not so
slightly) different.

def clear_bash_history():
version = '0.3'
print(subprocess.getoutput('history -c'))
[...]

Do you really need ten aliases for 'history -c'?

If you want to define aliases for a function, don't recreate the entire
function ten times. Start with defining the function once, then:

clear_bash_hist = clear_hist = clear_history = clear_bash_history

etc. But really, having ten names for the one function just confuses
people, who then wonder what subtle difference there is between
delete_history and clear_history.
def firefox():
version = '0.3'
print(subprocess.Popen('(firefox &)'))
Is Firefox really so important that it needs a dedicated command?

What about Debian users? Doesn't Iceweasel get a command?

def xterm():
version = '0.3'
print(subprocess.Popen('(xterm &)'))
Surely the user already has an xterm open, if they are running this
interactively? Why not just use your xterm's "new window" or "new tab"
command?


[...delete more trivial calls to subprocess...]
def repeat_cmd():
version = '0.3'
print(subprocess.Popen('!!'))
[... delete two exact copies of this function...]
def ejcd():
version = '0.3'
print(subprocess.Popen('eject cdrom1'))
[... delete FOURTEEN exact copies of this function...]

Really? Is anyone going to type "eject_disc_tray" instead of "eject"?


I think that will do.

This doesn't really do anything except define a large number of trivial
wrappers to commands already available in the shell. Emphasis on the
*trivial* -- with the exception of the grep wrapper, which is all of four
lines (ignoring the useless internal version number), every single one of
these wrapper functions is a one-liner.[1] In other words, you're not
adding any value to the shell commands by wrapping them in Python. There
are plenty of big, complex shell commands that take a plethora of options
and could do with some useful Python wrappers, like wget. But you haven't
done them.

Nor have you added extra security, or even extra convenience. You've done
nothing that couldn't be done using the shell "alias" command, except in
Python where the syntax is less convenient (e.g. "ls" in the shell,
versus "ls()" in Python).




[1] I think every newbie programmer goes through a stage of pointlessly
writing one-liner wrappers to every second function they see. I know I
did. The difference is, before the Internet, nobody did it publicly.
Wow! Thanks for the thorough critic. I appreciate your feed back and
thank you so much for the PEP link. I learned a lot. I never saw that
page before.

The "NCLA, Linux+, LPIC-1, DCTS" are my computer certifications. As for
mentioning Geany, I am trying to promote and give credit to Geany.

Good point about the Made by/Copyright suggestion. Although, I have not
copyrighted the file, can I still say "Copyrighted by ...". Thank you
for the LGPLv3 suggestion. I know that I must include the GPL license
for GPL programs, but I thought for LGPL code I could just have
"#LGPLv3". Thank you so much for that feedback. I definitely need to
read about all of the types of licenses.

I thought it would be helpful to include the version numbers for each
function, but you and another Python developer said it is pointless. I
see what you mean.

The grep emulating function does not work yet. I am still working on that.

Yeah, I have a VERY BAD habit of treating bash and the Linux shell (or
any/all shells) as the same thing. I know they are all very different,
but for some reason I still keep calling all shells in general BASH.

I will be sure to create aliases. I make alias commands so that it is
easier to guess or remember a command. For instance, a Python user my
want to clear the shell's history, but can only remember one form of the
command or must guess. On my Ubuntu system, I have set up numerous shell
aliases. I am addicted to aliases.

I still need to add the other browsers. Do very many people use Iceweasel?

I did not notice that I have "print(subprocess.Popen('(xterm &)'))"
instead of "subprocess.Popen('(xterm &)')". The worst computer errors
are ID-10-T errors.

True, the user my have Xterm open, but what if they use Guake (like me)
or Pterm, EvilVTE, Valaterm, Gnome-Terminal, Konsole, etc.?

How could I add security and convenience? Okay, I will try to add wget.
Are there any other shell commands that anyone feels I should add?

The point of this module is to allow Linux shell users to use Python3 as
a regular shell. Instead of using CSH, Bash, Tcsh, FISH, etc., users
could use Python3 and import this module. Python is more powerful than
any shell, so I want to make it easier for anyone to use Python as the
default shell. For instance, instead of typing "print(os.getcwd())" to
get the current working directory, users could type "boash.ls()". I hope
that is easier to remember than "print(os.getcwd())". As for the print()
command, I do not like how os.getcwd() has single quotes around the
output. Plus, Linux shell do not print output with quotes.

I want to make this a very useful and popular module, so I will use the
suggestions and add more useful wrappers. Would it help if I made a
Youtube video showing how this module can be used?

I will post the next version on this mailing list for another review.
Thanks everyone, and thanks a lot Steven D'Aprano!


Mahalo,

Devyn Collier Johnson
(e-mail address removed)
 
D

Devyn Collier Johnson

As requested, some constructive criticism of your module.

#!/usr/bin/python3
#Made by Devyn Collier Johnson, NCLA, Linux+, LPIC-1, DCTS
What's NCLA, Linux+, LPIC-1, DCTS? Do these mean anything? Are we
supposed to know what they mean?

"Made by" has no legal significance. You probably want:

Copyright © 2013 Devyn Collier Johnson.

#Made using the Geany IDE
Nobody gives a monkey's toss what editor you used to type up the module.
You might as well mention the brand of monitor you used, or whether the
keyboard is Dvorak or Qwerty.

You can't just drop in a mention of "LGPLv3" and expect it to mean
anything. You actually have to obey the licence yourself, and that
includes *actually including the licence in your work*. (You're
technically in violation of the licence at the moment, however since the
only person whose copyright you are infringing is yourself, it doesn't
matter. However anyone else using your code is at risk.)

http://www.gnu.org/licenses/gpl-howto.html

In the case of the LGPL, you have to include the text of *both* the GPL
and the LGPL, not just one.


import re, sys, subprocess, platform
def grep(regex,textf):
#Sample Command: grep.grep("^x",dir()) #Syntax:
boash.grep(regexp_string,list_of_strings_to_search)
Comments using # are only of use to people reading the source code. If
you want comments to be available at the interactive prompt, you should
write them as doc strings:

def grep(regex, textf):
"""This string is a docstring.

Sample command: ...
Blah blah blah
"""

Then, at the interactive prompt, the user can say:

help(boash.grep)

to read the docstring.

version = '0.2a'
That's quite useless, since it is a local variable invisible outside of
the function.

Also, why would you bother giving every individual function a version
number? That's rather pointless. The user cannot pick and choose function
A with version number 0.6 and function B with version number 0.7 if the
module provides versions 0.7 of both.

expr = re.compile(regex)
match = re.findall(expr, textf)
if match != None:
print(match)
When comparing with None, it is preferred to use "is" and "is not" rather
than equality tests.

def ls():
version = '0.3'
print(subprocess.getoutput('ls'))
def dir():
version = '0.3'
print(subprocess.getoutput('dir'))
A blank line or two between functions does wonders for readability. There
is no prize for conserving newlines.

You might like to read PEP 8, the Python style guide. It is optional, but
still makes a very good guide.

http://www.python.org/dev/peps/pep-0008/

def bash(*arg):
version = '0.3'
print(subprocess.getoutput(arg))
def shell(*arg):
version = '0.3'
print(subprocess.getoutput(arg))
bash is not a synonym for "shell". "The shell" might be sh, csh, bash, or
any one of many other shells, all of which are slightly (or not so
slightly) different.

def clear_bash_history():
version = '0.3'
print(subprocess.getoutput('history -c'))
[...]

Do you really need ten aliases for 'history -c'?

If you want to define aliases for a function, don't recreate the entire
function ten times. Start with defining the function once, then:

clear_bash_hist = clear_hist = clear_history = clear_bash_history

etc. But really, having ten names for the one function just confuses
people, who then wonder what subtle difference there is between
delete_history and clear_history.
def firefox():
version = '0.3'
print(subprocess.Popen('(firefox &)'))
Is Firefox really so important that it needs a dedicated command?

What about Debian users? Doesn't Iceweasel get a command?

def xterm():
version = '0.3'
print(subprocess.Popen('(xterm &)'))
Surely the user already has an xterm open, if they are running this
interactively? Why not just use your xterm's "new window" or "new tab"
command?


[...delete more trivial calls to subprocess...]
def repeat_cmd():
version = '0.3'
print(subprocess.Popen('!!'))
[... delete two exact copies of this function...]
def ejcd():
version = '0.3'
print(subprocess.Popen('eject cdrom1'))
[... delete FOURTEEN exact copies of this function...]

Really? Is anyone going to type "eject_disc_tray" instead of "eject"?


I think that will do.

This doesn't really do anything except define a large number of trivial
wrappers to commands already available in the shell. Emphasis on the
*trivial* -- with the exception of the grep wrapper, which is all of four
lines (ignoring the useless internal version number), every single one of
these wrapper functions is a one-liner.[1] In other words, you're not
adding any value to the shell commands by wrapping them in Python. There
are plenty of big, complex shell commands that take a plethora of options
and could do with some useful Python wrappers, like wget. But you haven't
done them.

Nor have you added extra security, or even extra convenience. You've done
nothing that couldn't be done using the shell "alias" command, except in
Python where the syntax is less convenient (e.g. "ls" in the shell,
versus "ls()" in Python).




[1] I think every newbie programmer goes through a stage of pointlessly
writing one-liner wrappers to every second function they see. I know I
did. The difference is, before the Internet, nobody did it publicly.

About the aliases, I have tried setting pwd() as an alias for
"os.getcwd()", but I cannot type "pwd()" and get the desired output.
Instead, I must type "pwd". I tested this in Guake running Python3.3.
Traceback (most recent call last):
File "<stdin>", line 1
SyntaxError: can't assign to function call


How could I make pwd() work?

Mahalo,

DCJ
 
D

Dave Angel

About the aliases, I have tried setting pwd() as an alias for
"os.getcwd()", but I cannot type "pwd()" and get the desired output.
Instead, I must type "pwd". I tested this in Guake running Python3.3.

Traceback (most recent call last):

File "<stdin>", line 1
SyntaxError: can't assign to function call


How could I make pwd() work?

Don't call getcwd() when making the alias. You want it to be called
when USING the alias.

pwd = os.getcwd #creates the alias

pwd() #runs the alias
 
C

Chris “Kwpolska†Warrick

About the aliases, I have tried setting pwd() as an alias for "os.getcwd()",
but I cannot type "pwd()" and get the desired output. Instead, I must type
"pwd". I tested this in Guake running Python3.3.

Traceback (most recent call last):

File "<stdin>", line 1
SyntaxError: can't assign to function call


How could I make pwd() work?


Mahalo,

DCJ
 
C

Chris Angelico

About the aliases, I have tried setting pwd() as an alias for "os.getcwd()",
but I cannot type "pwd()" and get the desired output. Instead, I must type
"pwd". I tested this in Guake running Python3.3.

Try:

Otherwise you're calling it immediately.

ChrisA
 
D

Devyn Collier Johnson

Don't call getcwd() when making the alias. You want it to be called
when USING the alias.

pwd = os.getcwd #creates the alias

pwd() #runs the alias
Thanks! It works!
'/home/collier'


Mahalo, Dave!


DCJ
 
D

Dave Angel

<SNIP>

Somehow during this thread, you have changed your purpose for this
library. It used to be a library that Python programmers could import
and use. And now, it's a shell replacement? The user runs the Python
interpreter, and types the line import boash to get started.
Yeah, I have a VERY BAD habit of treating bash and the Linux shell (or
any/all shells) as the same thing. I know they are all very different,
but for some reason I still keep calling all shells in general BASH.

I seem to recall that BASH is an acronym, for Bourne Again SHell.
I will be sure to create aliases. I make alias commands so that it is
easier to guess or remember a command. For instance, a Python user my
want to clear the shell's history, but can only remember one form of the
command or must guess. On my Ubuntu system, I have set up numerous shell
aliases. I am addicted to aliases.

Nothing wrong with aliases. But how does your user create his own
aliases? That's much more important than having yours available.
Remember that any new globals he defines are lost when he exits the
interpreter (or crashes).
I still need to add the other browsers. Do very many people use Iceweasel?

I did not notice that I have "print(subprocess.Popen('(xterm &)'))"
instead of "subprocess.Popen('(xterm &)')". The worst computer errors
are ID-10-T errors.

True, the user my have Xterm open, but what if they use Guake (like me)
or Pterm, EvilVTE, Valaterm, Gnome-Terminal, Konsole, etc.?

Exactly. If they're using a terminal with tabs, they might want to
create a new tab, not a new instance of the terminal. Or if they're
running screen or the equivalent, they want the new terminal to show up
on their (remote) console.
How could I add security and convenience? Okay, I will try to add wget.
Are there any other shell commands that anyone feels I should add?

How about tab? The command-completion and filename-completion and
parameter-completion logic of a good shell is extremely complex, and
very useful.
The point of this module is to allow Linux shell users to use Python3 as
a regular shell. Instead of using CSH, Bash, Tcsh, FISH, etc., users
could use Python3 and import this module. Python is more powerful than
any shell, so I want to make it easier for anyone to use Python as the
default shell. For instance, instead of typing "print(os.getcwd())" to
get the current working directory, users could type "boash.ls()". I hope
that is easier to remember than "print(os.getcwd())".

It's easier, but doesn't begin to do the same thing.

As for using this INSTEAD of csh, bash, etc., that might be likely once
it gets beyond 10% of the usefulness. Right now, it's at about 0.01%
And any habits a user gets within this environment have to be unlearned
when he returns to a standard shell.

Back in the early days of MSDOS, the FORMAT command didn't require you
to specify a drive letter. So people could intend to format their
floppy, and actually trash their hard disk. So I had colleagues who put
a FORMAT.BAt command on their path which hard-wired the A: parameter.
Now what happens to one of those folks when he goes to another machine
which doesn't have that batch file? Ouch! Instead I wrote a batch file
that checked to make sure you had the A: parameter. Rapidly, my fingers
learned that FORMAT A: was the valid syntax, and pretty soon the batch
file was unnecessary (for me).

If I were going to define a dozen aliases for other people to use, I'd
make them something like:

def clear_hist():
print "The function you want is probably clear_history()"

As for the print()
command, I do not like how os.getcwd() has single quotes around the
output.

Those quotes come from the Python interpreter, not from getcwd().
Plus, Linux shell do not print output with quotes.

I want to make this a very useful and popular module, so I will use the
suggestions and add more useful wrappers. Would it help if I made a
Youtube video showing how this module can be used?

I will post the next version on this mailing list for another review.
Thanks everyone, and thanks a lot Steven D'Aprano!

Have you figured out how you're going to do things like cd (os.chdir),
which have to remember state? And how to pass the new current directory
to the shell that launched Python?

Have you looked at ipython (ipython.org) ? At least from there, you can
get command completion with tab, one-third of the bash functionality.
So if you type boash.cle then <tab> it'll fill in the rest.
 
D

Devyn Collier Johnson

<SNIP>

Somehow during this thread, you have changed your purpose for this
library. It used to be a library that Python programmers could import
and use. And now, it's a shell replacement? The user runs the Python
interpreter, and types the line import boash to get started.


I seem to recall that BASH is an acronym, for Bourne Again SHell.


Nothing wrong with aliases. But how does your user create his own
aliases? That's much more important than having yours available.
Remember that any new globals he defines are lost when he exits the
interpreter (or crashes).


Exactly. If they're using a terminal with tabs, they might want to
create a new tab, not a new instance of the terminal. Or if they're
running screen or the equivalent, they want the new terminal to show
up on their (remote) console.


How about tab? The command-completion and filename-completion and
parameter-completion logic of a good shell is extremely complex, and
very useful.


It's easier, but doesn't begin to do the same thing.

As for using this INSTEAD of csh, bash, etc., that might be likely
once it gets beyond 10% of the usefulness. Right now, it's at about
0.01% And any habits a user gets within this environment have to be
unlearned when he returns to a standard shell.

Back in the early days of MSDOS, the FORMAT command didn't require you
to specify a drive letter. So people could intend to format their
floppy, and actually trash their hard disk. So I had colleagues who
put a FORMAT.BAt command on their path which hard-wired the A:
parameter. Now what happens to one of those folks when he goes to
another machine which doesn't have that batch file? Ouch! Instead I
wrote a batch file that checked to make sure you had the A:
parameter. Rapidly, my fingers learned that FORMAT A: was the valid
syntax, and pretty soon the batch file was unnecessary (for me).

If I were going to define a dozen aliases for other people to use, I'd
make them something like:

def clear_hist():
print "The function you want is probably clear_history()"



Those quotes come from the Python interpreter, not from getcwd().


Have you figured out how you're going to do things like cd (os.chdir),
which have to remember state? And how to pass the new current
directory to the shell that launched Python?

Have you looked at ipython (ipython.org) ? At least from there, you
can get command completion with tab, one-third of the bash
functionality. So if you type boash.cle then <tab> it'll fill in
the rest.

Thanks! I will look into IPython. I am familiar with it already. Yes, I
have two purposes for the module, but after reading these suggestions I
have modified my goal and purpose to achieve the goal of making a useful
and popular Python3 module. The whole point of my boash project is to
make a useful module. How can I make this module useful? I am fixing the
problems and implementing suggestions.

Would a Python3 game module be more useful? I plan to make a function
that rolls a die and prints the output (You got a 5) and other similar
random games.


Mahalo,

DCJ
 
D

Dave Angel

There is no special process to Copyright anything.
the simple act of writing it automatically gives you the copyright on
your own work.

Proving that it was you that created the work & when may be a little
trickier if you do not find a reliable means of recording the event
though.
(posting to this news group actually gives a reasonable time stamp
provided the article has not expired by the time it is needed)

The copyright law varies by country, and it's wise to look up your own
country's rules, as well as investigate international law. The
following is based only on my limited recollection of US law. I include
references below, but have not re-studied them. Nor am I a lawyer.

Generally, a copyright does belong to the author, as soon as he provably
commits the text to medium. However, if you ever expect to defend a
copyright, it can be useful to register it. Registration is limited by
law to certain time limits. I don't recall exactly, but I believe that
once something is published, it has to be registered within 3 months or so.

Registration is easy, but not free. You can copyright a number of works
simultaneously, but I think they have to be of the same type. And if it
is registered, you can sue for larger amounts, and you'll have a much
easier time getting a lawyer to take the case for you.

See: http://www.copyright.gov/

and especially:
http://www.copyright.gov/circs/circ01.pdf
 

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,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top