Re: [Tutor] dict vs several variables?

2012-02-18 Thread Peter Otten
Leam Hall wrote:

 On 02/17/2012 09:26 AM, Dave Angel wrote:
 There are two ways to think of a class. One is to hold various related
 data, and the other is to do operations on that data. If you just
 consider the first, then you could use a class like a dictionary whose
 keys are fixed (known at compile time).
 
 I think a class is the way to go for a couple reasons. First, of course,
 is that it pushes me to learn more. It also lets me encapsulate a lot of
 the work into one thing and keep the methods there.

One word of caution. If you make just one do-it-all class with a single 
instance and use instance attributes as if they were global variable the 
improvement over the global dictionary is minimal. You still should strive 
to make dependencies explicit, e. g. prefer

def add(a, b): return a + b

over

class DoItAll:
def add_a_and_b(self):
self.c = self.a + self.b

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] dict vs several variables?

2012-02-18 Thread Leam Hall

On 02/18/2012 03:39 AM, Peter Otten wrote:

Leam Hall wrote:


On 02/17/2012 09:26 AM, Dave Angel wrote:

There are two ways to think of a class. One is to hold various related
data, and the other is to do operations on that data. If you just
consider the first, then you could use a class like a dictionary whose
keys are fixed (known at compile time).


I think a class is the way to go for a couple reasons. First, of course,
is that it pushes me to learn more. It also lets me encapsulate a lot of
the work into one thing and keep the methods there.


One word of caution. If you make just one do-it-all class with a single
instance and use instance attributes as if they were global variable the
improvement over the global dictionary is minimal. You still should strive
to make dependencies explicit, e. g. prefer

def add(a, b): return a + b

over

class DoItAll:
 def add_a_and_b(self):
 self.c = self.a + self.b


Understood. In this case I'm starting the application and there are two 
separate bits. I'm studying tkinter for the class I'm in so the GUI 
stuff is one module and the formulas are in another module. The reason I 
considered a global dict or a class is because all of the data bits are 
directly related.


Dave angel wrote:

class MyDiver(object):
def __init__(self, depth, gasmix, time, rate):
self.depth = int(depth)
self.gasmix = int(gasmix)
self.time = datetime.datetime(time)
self.rate  = float(rate)

Which is a pretty good start, makes me think he's done scuba before.  :)

The object in question is a scuba dive. The user types in how deep they 
want to go, what gas mix they are on, how long they plan on staying, and 
what they think their air consumption rate will be. The formulas 
calculate absolute atmospheres which are used in other formulas, O2 
concentration (a risk factor), how much of the daily increased O2 
exposure the dive will create, and how much gas is needed to make that 
dive.


If the program grew the only thing that might be pulled out is the air 
consumption rate. That would likely go into a diver object so there was 
a profile for each diver. However, at the moment the app is just giving 
you dive profile information so you can plan your bottom time and gas 
consumption.


That's my thinking as of this morning. I need to go back and build 
unittests; will do so while moving it into a class. Should be fun and 
good learning!


Leam
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] dict vs several variables?

2012-02-17 Thread Leam Hall
I'm building a program that uses one of my own modules for a bunch of 
formula defs and another module for the tkinter GUI stuff. There are 
half a dozen input variables and about the same in calculated variables. 
Is it better/cleaner to just build a global dict and have everything go 
into it or pass multiple arguments to each function and have it return 
the calculated value?


Thanks!

Leam

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] dict vs several variables?

2012-02-17 Thread Peter Otten
Leam Hall wrote:

 I'm building a program that uses one of my own modules for a bunch of
 formula defs and another module for the tkinter GUI stuff. There are
 half a dozen input variables and about the same in calculated variables.
 Is it better/cleaner to just build a global dict and have everything go
 into it or pass multiple arguments to each function and have it return
 the calculated value?

The latter. It makes the dependencies explicit to a reader of the function, 
it simplifies unit tests, allows it to reuse functions in a different 
context, and it is more likely to work in a multi-threaded environment.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] dict vs several variables?

2012-02-17 Thread leam hall
Thanks Peter!

My concern with variables is that they have to be passed in specific
order to the function, and they may have to have their type set
multiple times so that you can perform the right functions on them. In
a dict you could set it on insert and not have to worry about it.

Thanks!

Leam

On 2/17/12, Peter Otten __pete...@web.de wrote:
 Leam Hall wrote:

 I'm building a program that uses one of my own modules for a bunch of
 formula defs and another module for the tkinter GUI stuff. There are
 half a dozen input variables and about the same in calculated variables.
 Is it better/cleaner to just build a global dict and have everything go
 into it or pass multiple arguments to each function and have it return
 the calculated value?

 The latter. It makes the dependencies explicit to a reader of the function,
 it simplifies unit tests, allows it to reuse functions in a different
 context, and it is more likely to work in a multi-threaded environment.

 ___
 Tutor maillist  -  Tutor@python.org
 To unsubscribe or change subscription options:
 http://mail.python.org/mailman/listinfo/tutor



-- 
Mind on a Mission http://leamhall.blogspot.com/
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] dict vs several variables?

2012-02-17 Thread Sander Sweers
On 17 February 2012 14:04, leam hall leamh...@gmail.com wrote:
 My concern with variables is that they have to be passed in specific
 order to the function, and they may have to have their type set
 multiple times so that you can perform the right functions on them. In
 a dict you could set it on insert and not have to worry about it.

There is **kwargs which is behaves like a dict. This is very powerful
but comes with the drawback that you have to make sure you get all the
variables you need for your function to work properly.

I found [1] that is a decent explanation of how these work. Other
might have better explanations.

Greets
Sander
[1] http://basicpython.com/understanding-arguments-args-and-kwargs-in-python/
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] dict vs several variables?

2012-02-17 Thread Dave Angel



On 2/17/12, Peter Otten__pete...@web.de  wrote:

Leam Hall wrote:


I'm building a program that uses one of my own modules for a bunch of
formula defs and another module for the tkinter GUI stuff. There are
half a dozen input variables and about the same in calculated variables.
Is it better/cleaner to just build a global dict and have everything go
into it or pass multiple arguments to each function and have it return
the calculated value?

The latter. It makes the dependencies explicit to a reader of the function,
it simplifies unit tests, allows it to reuse functions in a different
context, and it is more likely to work in a multi-threaded environment.


On 02/17/2012 08:04 AM, leam hall wrote:

Thanks Peter!

My concern with variables is that they have to be passed in specific
order to the function, and they may have to have their type set
multiple times so that you can perform the right functions on them. In
a dict you could set it on insert and not have to worry about it.

Thanks!

Leam


Please don't top-post.  Put your remarks after the parts you're quoting.

You're asking for best-practice, presumably as part of your transition 
from small snippets to larger scale.  First habit that beginners have to 
break is the tendency to keep things in globals.  Can it make things 
easier?  Yes, until you try to return to that code and make changes, 
and discover that one change affects an unknown number of other parts.  
Yes, until you decide you want to use one of those functions in a 
multithreaded environment.  Yes, until somebody else has to use your code.


Variable can't get their type set.  They are bound at any moment to an 
object, and that object has a type.  Period.


Passed in a specific order?  Of course.  Very few functions, even binary 
ones, are commutative on their arguments.  Do you expect

divide(7, 42) to give the same answer as  divide(42, 7) ?
You can also use keyword arguments to help disambiguate the order of 
arguments.  That's especially useful when some arguments are optional.


Real question is whether some (seldom all) of those variables are in 
fact part of a larger concept.  If so, it makes sense to define a class 
for them, and pass around objects of that class.  Notice it's not 
global, it's still passed as an argument.  This can reduce your 
parameters from 20 to maybe 6.  But make sure that the things the class 
represents are really related.


Dictionaries are a built-in collection class, as are lists, sets, and 
tuples.  But you can write your own.  An example of needing a class 
might be to hold the coordinates of a point in space.  You make a 
Location class, instantiate it with three arguments, and use that 
instance for functions like

   move_ship(ship, newlocation)

There are times to have arbitrary lists or dictionaries to pass into a 
function, and Python has added syntax (*args and **kwargs) to make that 
convenient. But  the times that is needed are very specialized.



--

DaveA

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] dict vs several variables?

2012-02-17 Thread Peter Otten
leam hall wrote:

 My concern with variables is that they have to be passed in specific
 order to the function, 

Yes, unless you use keywords. You can invoke

def div(x, y):
   return x // y

a = div(3, 2)
b = div(y=3, x=2)
assert a == b

 and they may have to have their type set

I have no idea what you mean by have their type set. Can you give an 
example?

 multiple times so that you can perform the right functions on them. In
 a dict you could set it on insert and not have to worry about it.

Instead you'll have to worry about the contents of the dict which I suspect 
will be even harder to verify in a non-trivial script.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] dict vs several variables?

2012-02-17 Thread leam hall
On 2/17/12, Dave Angel d...@davea.name wrote:

 Real question is whether some (seldom all) of those variables are in
 fact part of a larger concept.  If so, it makes sense to define a class
 for them, and pass around objects of that class.  Notice it's not
 global, it's still passed as an argument.  This can reduce your
 parameters from 20 to maybe 6.  But make sure that the things the class
 represents are really related.

 Dictionaries are a built-in collection class, as are lists, sets, and
 tuples.  But you can write your own.  An example of needing a class
 might be to hold the coordinates of a point in space.  You make a
 Location class, instantiate it with three arguments, and use that
 instance for functions like
 move_ship(ship, newlocation)

 DaveA

Understood. In this case, the first half dozen variables are input and
the rest are derived from the first ones. A class might make sense and
though I understand them a little, not enough to make a good judgement
on it.

The task is to take parameters for a scuba dive; depth, gas mix, time,
air consumption rate, and compute the O2 load, gas required, etc.

Leam

-- 
Mind on a Mission http://leamhall.blogspot.com/
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] dict vs several variables?

2012-02-17 Thread leam hall
On 2/17/12, Peter Otten __pete...@web.de wrote:
 leam hall wrote:
 and they may have to have their type set

 I have no idea what you mean by have their type set. Can you give an
 example?

Peter,

The variables input seem to be assumed to be strings and I need them
to be an integer or a float most of the time. Doing simple math on
them.

Thanks!

Leam

-- 
Mind on a Mission http://leamhall.blogspot.com/
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] dict vs several variables?

2012-02-17 Thread Dave Angel

On 02/17/2012 09:06 AM, leam hall wrote:

On 2/17/12, Dave Angeld...@davea.name  wrote:


Real question is whether some (seldom all) of those variables are in
fact part of a larger concept.  If so, it makes sense to define a class
for them, and pass around objects of that class.  Notice it's not
global, it's still passed as an argument.  This can reduce your
parameters from 20 to maybe 6.  But make sure that the things the class
represents are really related.

Dictionaries are a built-in collection class, as are lists, sets, and
tuples.  But you can write your own.  An example of needing a class
might be to hold the coordinates of a point in space.  You make a
Location class, instantiate it with three arguments, and use that
instance for functions like
 move_ship(ship, newlocation)

DaveA

Understood. In this case, the first half dozen variables are input and
the rest are derived from the first ones. A class might make sense and
though I understand them a little, not enough to make a good judgement
on it.

The task is to take parameters for a scuba dive; depth, gas mix, time,
air consumption rate, and compute the O2 load, gas required, etc.

Leam

There are two ways to think of a class.  One is to hold various related 
data, and the other is to do operations on that data.  If you just 
consider the first, then you could use a class like a dictionary whose 
keys are fixed (known at compile time).


class MyDiver(object):
def __init__(self, depth, gasmix, time, rate):
self.depth = int(depth)
self.gasmix = int(gasmix)
self.time = datetime.datetime(time)
self.rate  = float(rate)



Now if you want to use one such:

sam = MyDiver(200, 20, 04/14/2011,  3.7)
bill = MyDiver(.)

And if you want to fetch various items, you'd do something like:
   if sam.depth  bill.depth

instead of using   sam[depth]  and bill[depth]

Next thing is to decide if the functions you're describing are really 
just methods on the class


class MyDiver(object):
def __init__( ... as before)


def get_load(self):
return self.gasmix/self.rate(or whatever)

and used as print sam.get_load()

that last could be simplified with a decorator

@property
def load(self):
return self.gasmix/self.rate

now it's used as though it's a regular data attribute

print sam.load



--

DaveA

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] dict vs several variables?

2012-02-17 Thread Peter Otten
leam hall wrote:

 On 2/17/12, Peter Otten __pete...@web.de wrote:
 leam hall wrote:
 and they may have to have their type set

 I have no idea what you mean by have their type set. Can you give an
 example?
 
 Peter,
 
 The variables input seem to be assumed to be strings and I need them
 to be an integer or a float most of the time. Doing simple math on
 them.

If you are processing user input you should convert that once no matter what 
the structure of your program is. Example:

#WRONG, integer conversion in many places in the code
def sum(a, b): return int(a) + int(b)
def difference(a, b): return int(a) - int(b)
a = raw_input(a )
b = raw_input(b )
print a + b =, sum(a, b)
print a - b =, difference(a, b)

#BETTER, integer conversion in a single place
def sum(a, b): return a + b
def difference(a, b): return a - b
def get_int(prompt):
return int(raw_input(prompt))
a = get_int(a )
b = get_int(b )
print a + b =, sum(a, b)
print a - b =, difference(a, b)

The second form has the added benefit that you can easily make get_int() 
more forgiving (allow the user to try again when his input is not a valid 
integer) or make other changes to the code (e. g. allow floating point 
input).

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] dict vs several variables?

2012-02-17 Thread Alan Gauld

On 17/02/12 14:10, leam hall wrote:


The variables input seem to be assumed to be strings


They are not assumed to be strings, they *are* strings. Users can only 
type characters at the keyboard (the usual source of input). Your 
program has to interpret those characters and convert to the right type.


It's good practice to do that as soon as possible which is why you often 
see code like:


numVal = int( raw_input(Type a number: ) )
fltVal = float( raw_input(Type a number: ) )
strVal = raw_input(Type your name: )

This also has the advantage that you can catch user input errors early 
and request re-input. If you just store whatever the user types
(four say) and then try to convert during the math you get an error 
far too late to fix. eg. try


print pow(int(four), 2)

You can convert them to strings for display later but usually you
don't want to, because you will use string formatting to improve
their appearance (especially with floats).

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] dict vs several variables?

2012-02-17 Thread Leam Hall

On 02/17/2012 09:26 AM, Dave Angel wrote:

There are two ways to think of a class. One is to hold various related
data, and the other is to do operations on that data. If you just
consider the first, then you could use a class like a dictionary whose
keys are fixed (known at compile time).


I think a class is the way to go for a couple reasons. First, of course, 
is that it pushes me to learn more. It also lets me encapsulate a lot of 
the work into one thing and keep the methods there.


Thanks!

Leam

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] dict vs several variables?

2012-02-17 Thread Steven D'Aprano

Leam Hall wrote:
I'm building a program that uses one of my own modules for a bunch of 
formula defs and another module for the tkinter GUI stuff. There are 
half a dozen input variables and about the same in calculated variables. 
Is it better/cleaner to just build a global dict and have everything go 
into it or pass multiple arguments to each function and have it return 
the calculated value?



A global dict is like the Dark Side of the Force: easier, quicker, simpler, 
but it leads to pain and anguish and great suffering.


I assume you understand why global variables should be avoided as much as 
possible? E.g.


# Bad! Wrong! Do not do this!
x = ''
y = ''
z = ''

def get_user_input():
global x, y
x = raw_input(Please enter x: )
y = raw_input(Please enter y: )

def do_calculation():
   global z
   z = The answer is %s % (x.upper() + y.lower())

def main()
get_user_input()
do_calculation()
print z


If you're not familiar with the reasons to avoid global variables, you should 
google for Global variables considered harmful, or start here:


http://c2.com/cgi/wiki?GlobalVariablesAreBad


Well, using a single global dict is *almost* as bad, and for most of the same 
reasons:


# Do not do this either.
values = {'x': '', 'y': '', 'z': ''}

def get_user_input(values):
values['x'] = raw_input(Please enter x: )
values['y'] = raw_input(Please enter y: )

def do_calculation(values):
   x = values['x']
   y = values['y']
   values['z'] = The answer is %s % (x.upper() + y.lower())

def main()
get_user_input(values)
do_calculation(values)
print values['z']


This is a mild improvement, at least you can pass in an alternative dict if 
needed, but it still suffers from failure of encapsulation (all functions that 
have access to the dict have access to all variables, whether they need them 
or not) and other problems.


Just about the only valid use of this pattern I can think of is for global 
settings that apply application-wide. Such settings tend to be write-once, 
which mitigates the disadvantages of global and pseudo-global variables.


By the way, in case it isn't obvious, changing from a dict to a instance with 
named attributes values.x values.y values.z is just a cosmetic change, it 
doesn't change the basic problems.


For a toy problem like the above, it might seem hardly worth the hassle of 
de-globalising the functions, but for real code this really pays off in fewer 
bugs and easier maintenance:



def get_user_input():
x = raw_input(Please enter x: )
y = raw_input(Please enter y: )
 return (x, y)

def do_calculation(x, y):
   return The answer is %s % (x.upper() + y.lower())

def main()
a, b = get_user_input()
result = do_calculation(a, b)
print result


I assume the problem you are solving is more than just a toy. In that case, 
passing individual variables to only the functions that need them is a better 
solution. RELATED variables that MUST stay together can be collected into data 
structures such as tuples, lists, dicts, or custom classes. But don't be 
tempted to dump everything into one giant dict -- that's barely better than 
using globals.




--
Steven
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor