On 22/06/13 09:00, Jim Mooney wrote:
On 21 June 2013 14:59, ALAN GAULD <alan.ga...@btinternet.com> wrote:
Give us a clue, show us your code!
I was hoping you wouldn't say that since it's another of my insane
Lazy Typer programs to avoid typing, which are no doubt considered
frivolous. Although I'm learning a lot doing them ;')
Well, perhaps not *frivolous*. After all, Python itself might be said to be a "lazy
typer" programming language, compared to some such as Pascal, C, or especially Java.
Compare the archetypal "Hello World" program in Java versus Python:
=== Java version ===
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World");
}
}
=== Python version ===
print("Hello, World")
Speaking of Java, I get a kick out of this article and love to link to it on
every possible opportunity:
http://steve-yegge.blogspot.com.au/2006/03/execution-in-kingdom-of-nouns.html
:-)
Okay, I have a snippet that posts the below text in automatically. I
can use it to make any number of dicts, lists, or sets, from just
tokens in a single string, and they are printed out as the different
types, named and and numbered so they have different program names.
That way I don't have to type in quotes, commas, colons, and so forth.
Once the interpreter prints them out, I just select all and paste them
into my program, replacing what's below. Kind of a manual
meta-programming ;')
============= pasted in snippet ================
## Output sequence will be all strings. The first type in the 2nd
parameter list will be the
## default due to 'or" short circuiting, so you can just delete to get
what you want.
## You MUST have an even number of tokens for a dict or you'll get an exception.
from maker import makeseq
makeseq("Replace me, even number of tokens for dict", dict or list or set)
I think that a better design here would be three functions that explicitly tell
you what they do:
makedict
makelist
makeset
The three of them could call an underlying internal function that does most of
the work. Or not, as the case may be.
============= end snippet ====================
From this I can create any number of numbered dicts, lists or sets
*Numbered* variables? Oh wow, is it 1975 again? I didn't think I'd be
programming in BASIC again...
:-)
(The 'or' short circuit means I get dicts as default, and only have to
delete from the front to get the others - dicts are default since
they're the most annoying to type - now That's lazy.)
Surely typing one of "dict", "list" or "set" is not too much effort?
makeseq("stuff goes here ...", dict)
makeseq("stuff goes here ...", list)
makeseq("stuff goes here ...", set)
makeseq("stuff goes here ...", tuple)
makeseq("stuff goes here ...", frozenset)
You don't even need to put quotes around the type. In fact, you *shouldn't* put
quotes around the type, since that will stop it from working.
[...]
makeseq("this is a list and it is not a very big list", list or set)
Creating your own tools is fine, but they ought to do a little more than just
duplicate the functionality of built-in tools. I'll come back to the dict case
again further down, but the list and set cases are trivial:
L1 = "this is a list and it is not a very big list".split()
L2 = "Yet another list to show the different types increment separately".split()
S1 = set("and finally some sets".split())
Best of all, the time you save not having to type "makeseq" can now be used to
think of meaningful, descriptive names for the variables :-)
Here are some improvements to your makeseq function:
dictnumfarkadoodle = listnumfarkadoodle = setnumfarkadoodle = 0
# Since these are global I'm using words not likely to be duplicated
until I figure a different way and
# replace 'farkadoodle' with '' ;')
def makeseq(instring, typein):
global dictnumfarkadoodle, listnumfarkadoodle, setnumfarkadoodle
if isinstance(dict(), typein):
Rather than create a new dict, then check to see if it is an instance of
typein, you can just do this:
if typein is dict:
...
elif typein is list:
...
elif typein is set:
...
and similar for tuple and frozenset.
newdict = {}
dl = instring.split()
if len(dl) % 2 != 0:
raise Exception ("list entries must be even") # so they match
It is normally better to use a more specific exception. In this case, I
recommend using TypeError, since TypeError is used for cases where you pass the
wrong number of arguments to a type constructor (among other things).
for idx in range(0,len(dl),2):
newdict[dl[idx]] = dl[idx+1]
In general, any time you find yourself channeling Pascal circa 1984, you're
doing it wrong :-) There is very rarely any need to iterate over index numbers
like this. The preferred Python way would be to slice the list into two halves,
then zip them together:
keys = d1[0::2] # Every second item, starting at 0.
values = d1[1::2] # Every second item, starting at 1.
newdict = dict(zip(keys, values))
which can be re-written as a single line:
newdict = dict(zip(d1[0::2], d1[1::2]))
dictnumfarkadoodle += 1
print('D' + str(dictnumfarkadoodle) + ' =', newdict)
elif isinstance(list(), typein):
newlist = []
dl = instring.split()
for word in dl:
newlist.append(word)
dl is already a list. There's no need to laboriously, and manually, copy the
items from dl one by one. Instead you can tell Python to copy them:
newlist = list(dl)
or if you prefer slicing notation:
newlist = dl[:] # Slice from the beginning to the end.
but really, why bother to copy the list?
newlist = instring.split()
listnumfarkadoodle += 1
print('L' + str(listnumfarkadoodle) + ' =', newlist)
elif isinstance(set(), typein):
newset = set()
dl = instring.split()
for word in dl:
newset.add(word)
I'm going to leave this one for you. Given what you've seen with the list
section, how would you improve this one?
(Hint: here too, dl is a list, and set() takes a list as argument and returns a
set.)
setnumfarkadoodle += 1
print('S' + str(setnumfarkadoodle) + ' =', newset)
else: print('Second parameter must be list, set, or dict')
# oops, I error out on a non-type 2nd parameter. Fix this later
Actually, no, you don't error out. You just print a message. To make it a
proper error, you need to raise an exception:
raise TypeError("second param blah blah blah...")
or similar.
--
Steven
_______________________________________________
Tutor maillist - Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor