Re: How call method from a method in same class?

2019-04-02 Thread dboland9
Cameron,

Again, thanks for the help. I agree with everything you wrote, but... The code 
was thrown together to produce the error so I could illustrate the problem. It 
was by design junk. But it did produce the error, I got some great answers to 
my situation, so I am very grateful for the help.

Dave,
April 1, 2019 10:30 PM, "Cameron Simpson" mailto:c...@cskk.id.au)> wrote:
 On 01Apr2019 22:02, Dave mailto:dbola...@offilive.com)> wrote:
 As classes get more complex, it is good to call a function to do some >of the 
processing, and make
the code easier to follow. My question is >how to do that? I've attached some 
silly code to
illustrate the >point. The error is: name 'validScale' is not defined. Well, 
yes it >is, but maybe
not the correct way. Suggestions? 

It is and it isn't. See below:
 class TempConverter():
""" Temperature Converter converts a tempeature from one scale
to another scale. For example: 32, F, C will return
0 degrees C
""" 

[...]
 def validScale(self, scaleName):
if scaleName.upper == 'F' or 'C' or 'K':
return True
else:
return False

def convertTemp(self):
""" Converts temperature scale if scales valid."""
if validScale(self.scale):
scaleValid = True 

[...]

It is an instance method, so:

if self.validScale(self.scale)

would resolve the name. However, there are several things worth discussing here.

First up, validScale itself returns a Boolean, so just return the test result. 
Change:

if scaleName.upper == 'F' or 'C' or 'K':
return True
else:
return False

into:

return scaleName.upper == 'F' or 'C' or 'K'

Second, the condition is buggy. You want this:

return scaleName.upper() in ('F', 'C', 'K')

i.e. you need to call (the "()") the .upper method, and you need to check if 
the result is in your
collection of valid results.

This expression:

value == A or B or C

means: True if value == A, otherwise B if B is true, otherwise C.

The next thing to observe is that you're testing whether self.scale is valid. 
Normal practice would
be to make that test in __init__, and raise a ValueError if it is not so:

def __init__(self, .scale...):
if scale.upper() not in ('F', 'C', 'K'):
raise ValueError("invalid scale %r: expected one of F, C or K" % (scale,))
why recite the scale in the message? Because it makes the offending value 
obvious. In particular,
if for example you called this incorrectly and had the temperature in there 
instead of the scale
that will be trivial to debug from the message.

Of course, you actually want to be able to test any scal evalue for validity, 
not just the one
stuffed into your instance (.scale). So lets revisit the validScale method:

def validScale(self, scale):
return scaleName.upper() in ('F', 'C', 'K')

You'll notice that it doesn't depend in "self". Or, for that matter, the class. 
So this is a
"static" method: a function defined in the class for conceptual clarity, but 
not with any
dependence on the class itself or a particular class instance. So:

@staticmethod
def validScale(scale):
return scaleName.upper() in ('F', 'C', 'K')

In __init__, and elsewhere, you can still call this from the instance:

def __init__(self, .scale...):
if not self.validScale(scale):
raise ValueError("invalid scale %r: expected one of F, C or K" % (scale,))
You can also call this from _outside_ the class, for example for other 
validation:

scale = input("Enter a temperate scale name (F, C or K): ")
if not TempConverter.validScale(scale):
print("Bad! Bad user!")
 newScaleValid = True 

Again, validScale returns a Boolean. So you could have just gone:

newScaleValid = self.validScale(newScale)
 if scaleValid and newScaleValid:
print('Scale converted')
else:
msg = "There was and error with the scales entered.n"
msg = msg + "You entered: " + self.scale
msg = msg + ' ' 'and' + self.newScale
print(msg)

if __name__ == "__main__":
myclass = TempConverter(32, 'f', 'c')
myclass.convertTemp() 

My personal inclination would be do define a Temperature class with a convert 
function to be used
like this:

temp = Temperature(32, 'f')
tempC = temp.convert('c')

This reduces the complexity of the class and IMO makes it easier to use 
elsewhere.

BTW, you get an instance back from tempConverter(...), not a class. So don't 
call it "myclass".

Cheers,
Cameron Simpson mailto:c...@cskk.id.au)>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How call method from a method in same class?

2019-04-01 Thread Dave

On 4/1/19 10:29 PM, Cameron Simpson wrote:

On 01Apr2019 22:02, Dave  wrote:
As classes get more complex, it is good to call a function to do some 
of the processing, and make the code easier to follow.  My question is 
how to do that?  I've attached some silly code to illustrate the 
point.  The error is: name 'validScale' is not defined.  Well, yes it 
is, but maybe not the correct way.  Suggestions?


It is and it isn't. See below:


class TempConverter():
   """ Temperature Converter converts a tempeature from one scale
   to another scale.  For example: 32, F, C will return
   0 degrees C
   """

[...]

   def validScale(self, scaleName):
   if scaleName.upper == 'F' or 'C' or 'K':
   return True
   else:
   return False

   def convertTemp(self):
   """ Converts temperature scale if scales valid."""
   if validScale(self.scale):
   scaleValid = True

[...]

It is an instance method, so:

    if self.validScale(self.scale)

would resolve the name. However, there are several things worth 
discussing here.


First up, validScale itself returns a Boolean, so just return the test 
result. Change:


    if scaleName.upper == 'F' or 'C' or 'K':
    return True
    else:
    return False

into:

    return scaleName.upper == 'F' or 'C' or 'K'

Second, the condition is buggy. You want this:

    return scaleName.upper() in ('F', 'C', 'K')

i.e. you need to call (the "()") the .upper method, and you need to 
check if the result is in your collection of valid results.


This expression:

    value == A or B or C

means: True if value == A, otherwise B if B is true, otherwise C.

The next thing to observe is that you're testing whether self.scale is 
valid. Normal practice would be to make that test in __init__, and raise 
a ValueError if it is not so:


    def __init__(self, .scale...):
  if scale.upper() not in ('F', 'C', 'K'):
    raise ValueError("invalid scale %r: expected one of F, C or K" % 
(scale,))
why recite the scale in the message? Because it makes the offending 
value obvious. In particular, if for example you called this incorrectly 
and had the temperature in there instead of the scale that will be 
trivial to debug from the message.


Of course, you actually want to be able to test any scal evalue for 
validity, not just the one stuffed into your instance (.scale). So lets 
revisit the validScale method:


    def validScale(self, scale):
  return scaleName.upper() in ('F', 'C', 'K')

You'll notice that it doesn't depend in "self". Or, for that matter, the 
class. So this is a "static" method: a function defined in the class for 
conceptual clarity, but not with any dependence on the class itself or a 
particular class instance. So:


    @staticmethod
    def validScale(scale):
  return scaleName.upper() in ('F', 'C', 'K')

In __init__, and elsewhere, you can still call this from the instance:

    def __init__(self, .scale...):
  if not self.validScale(scale):
    raise ValueError("invalid scale %r: expected one of F, C or K" % 
(scale,))
You can also call this from _outside_ the class, for example for other 
validation:


    scale = input("Enter a temperate scale name (F, C or K): ")
    if not TempConverter.validScale(scale):
  print("Bad! Bad user!")


   newScaleValid = True


Again, validScale returns a Boolean. So you could have just gone:

    newScaleValid = self.validScale(newScale)


   if scaleValid and newScaleValid:
   print('Scale converted')
   else:
   msg = "There was and error with the scales entered.\n"
   msg = msg + "You entered: " + self.scale
   msg = msg + ' ' 'and' + self.newScale
   print(msg)

if __name__ == "__main__":
   myclass = TempConverter(32, 'f', 'c')
   myclass.convertTemp()


My personal inclination would be do define a Temperature class with a 
convert function to be used like this:


    temp = Temperature(32, 'f')
    tempC = temp.convert('c')

This reduces the complexity of the class and IMO makes it easier to use 
elsewhere.



BTW, you get an instance back from tempConverter(...), not a class. So 
don't call it "myclass".


Cheers,
Cameron Simpson 


Cameron,

I'm going to need a while to work through this.  As I mentioned, this 
was quick and dirty code just to illustrate a point - not intended to be 
good code.  So I'll take a close read tomorrow.  Thanks again!!


Dave,
--
https://mail.python.org/mailman/listinfo/python-list


Re: How call method from a method in same class?

2019-04-01 Thread Cameron Simpson

On 01Apr2019 22:02, Dave  wrote:
As classes get more complex, it is good to call a function to do some 
of the processing, and make the code easier to follow.  My question is 
how to do that?  I've attached some silly code to illustrate the 
point.  The error is: name 'validScale' is not defined.  Well, yes it 
is, but maybe not the correct way.  Suggestions?


It is and it isn't. See below:


class TempConverter():
   """ Temperature Converter converts a tempeature from one scale
   to another scale.  For example: 32, F, C will return
   0 degrees C
   """

[...]

   def validScale(self, scaleName):
   if scaleName.upper == 'F' or 'C' or 'K':
   return True
   else:
   return False

   def convertTemp(self):
   """ Converts temperature scale if scales valid."""
   if validScale(self.scale):
   scaleValid = True

[...]

It is an instance method, so:

   if self.validScale(self.scale)

would resolve the name. However, there are several things worth 
discussing here.


First up, validScale itself returns a Boolean, so just return the test 
result. Change:


   if scaleName.upper == 'F' or 'C' or 'K':
   return True
   else:
   return False

into:

   return scaleName.upper == 'F' or 'C' or 'K'

Second, the condition is buggy. You want this:

   return scaleName.upper() in ('F', 'C', 'K')

i.e. you need to call (the "()") the .upper method, and you need to 
check if the result is in your collection of valid results.


This expression:

   value == A or B or C

means: True if value == A, otherwise B if B is true, otherwise C.

The next thing to observe is that you're testing whether self.scale is 
valid. Normal practice would be to make that test in __init__, and raise 
a ValueError if it is not so:


   def __init__(self, .scale...):
 if scale.upper() not in ('F', 'C', 'K'):
   raise ValueError("invalid scale %r: expected one of F, C or K" % (scale,)) 

why recite the scale in the message? Because it makes the offending 
value obvious. In particular, if for example you called this incorrectly 
and had the temperature in there instead of the scale that will be 
trivial to debug from the message.


Of course, you actually want to be able to test any scal evalue for 
validity, not just the one stuffed into your instance (.scale). So lets 
revisit the validScale method:


   def validScale(self, scale):
 return scaleName.upper() in ('F', 'C', 'K')

You'll notice that it doesn't depend in "self". Or, for that matter, the 
class. So this is a "static" method: a function defined in the class for 
conceptual clarity, but not with any dependence on the class itself or a 
particular class instance. So:


   @staticmethod
   def validScale(scale):
 return scaleName.upper() in ('F', 'C', 'K')

In __init__, and elsewhere, you can still call this from the instance:

   def __init__(self, .scale...):
 if not self.validScale(scale):
   raise ValueError("invalid scale %r: expected one of F, C or K" % (scale,)) 

You can also call this from _outside_ the class, for example for other 
validation:


   scale = input("Enter a temperate scale name (F, C or K): ")
   if not TempConverter.validScale(scale):
 print("Bad! Bad user!")


   newScaleValid = True


Again, validScale returns a Boolean. So you could have just gone:

   newScaleValid = self.validScale(newScale)


   if scaleValid and newScaleValid:
   print('Scale converted')
   else:
   msg = "There was and error with the scales entered.\n"
   msg = msg + "You entered: " + self.scale
   msg = msg + ' ' 'and' + self.newScale
   print(msg)

if __name__ == "__main__":
   myclass = TempConverter(32, 'f', 'c')
   myclass.convertTemp()


My personal inclination would be do define a Temperature class with a 
convert function to be used like this:


   temp = Temperature(32, 'f')
   tempC = temp.convert('c')

This reduces the complexity of the class and IMO makes it easier to use 
elsewhere.



BTW, you get an instance back from tempConverter(...), not a class. So 
don't call it "myclass".


Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: How call method from a method in same class?

2019-04-01 Thread Dave

On 4/1/19 10:02 PM, Dave wrote:
As classes get more complex, it is good to call a function to do some of 
the processing, and make the code easier to follow.  My question is how 
to do that?  I've attached some silly code to illustrate the point.  The 
error is: name 'validScale' is not defined.  Well, yes it is, but maybe 
not the correct way.  Suggestions?


Dave,

class TempConverter():
     """ Temperature Converter converts a tempeature from one scale
     to another scale.  For example: 32, F, C will return
     0 degrees C
     """

     def __init__(self, temperature, scale, newScale):
     self.temperature = temperature
     self.scale = scale
     self.newScale = newScale

     def validScale(self, scaleName):
     if scaleName.upper == 'F' or 'C' or 'K':
     return True
     else:
     return False

     def convertTemp(self):
     """ Converts temperature scale if scales valid."""
     if validScale(self.scale):
     scaleValid = True
     if validScale(self.newScale):
     newScaleValid = True
     if scaleValid and newScaleValid:
     print('Scale converted')
     else:
     msg = "There was and error with the scales entered.\n"
     msg = msg + "You entered: " + self.scale
     msg = msg + ' ' 'and' + self.newScale
     print(msg)

if __name__ == "__main__":
     myclass = TempConverter(32, 'f', 'c')
     myclass.convertTemp()


Thanks all for your (ready, wait for it) self-lessness help (get it?)

Dave (laughing)

--
https://mail.python.org/mailman/listinfo/python-list


Re: How call method from a method in same class?

2019-04-01 Thread Dave

On 4/1/19 10:12 PM, Irv Kalb wrote:



On Apr 1, 2019, at 7:02 PM, Dave  wrote:

As classes get more complex, it is good to call a function to do some of the 
processing, and make the code easier to follow.  My question is how to do that? 
 I've attached some silly code to illustrate the point.  The error is: name 
'validScale' is not defined.  Well, yes it is, but maybe not the correct way.  
Suggestions?

Dave,

class TempConverter():
""" Temperature Converter converts a tempeature from one scale
to another scale.  For example: 32, F, C will return
0 degrees C
"""

def __init__(self, temperature, scale, newScale):
self.temperature = temperature
self.scale = scale
self.newScale = newScale

def validScale(self, scaleName):
if scaleName.upper == 'F' or 'C' or 'K':
return True
else:
return False

def convertTemp(self):
""" Converts temperature scale if scales valid."""
if validScale(self.scale):
scaleValid = True
if validScale(self.newScale):
newScaleValid = True
if scaleValid and newScaleValid:
print('Scale converted')
else:
msg = "There was and error with the scales entered.\n"
msg = msg + "You entered: " + self.scale
msg = msg + ' ' 'and' + self.newScale
print(msg)

if __name__ == "__main__":
myclass = TempConverter(32, 'f', 'c')
myclass.convertTemp()
--
https://mail.python.org/mailman/listinfo/python-list



To answer your specific question, you call a method in the same class by 
calling:  self.methodName   For example:  self.validScale

However, once you fix that, you wind find that the if statement in that method 
is not built correctly.

Also, since the variable self.scale is already set in your __init__ method, 
there is no need to pass it into your function.  You could just use self.scale 
inside that method.

Irv



Irv,

Thanks for the response!  I realize the code is junk - just done to 
illustrate the problem.


Dave,
--
https://mail.python.org/mailman/listinfo/python-list


Re: How call method from a method in same class?

2019-04-01 Thread Dan Sommers

On 4/1/19 10:02 PM, Dave wrote:


  def validScale(self, scaleName):
  if scaleName.upper == 'F' or 'C' or 'K':
  return True
  else:
  return False

  def convertTemp(self):
  """ Converts temperature scale if scales valid."""
  if validScale(self.scale):
  scaleValid = True
  if validScale(self.newScale):
  newScaleValid = True
  if scaleValid and newScaleValid:
  print('Scale converted')
  else:
  msg = "There was and error with the scales entered.\n"
  msg = msg + "You entered: " + self.scale
  msg = msg + ' ' 'and' + self.newScale
  print(msg)


Note that validscale has a self parameter.  Call it just
like you would from outside the class:

if self.validScale(self.newScale):
newScaleValid = True

--
https://mail.python.org/mailman/listinfo/python-list


Re: How call method from a method in same class?

2019-04-01 Thread Irv Kalb


> On Apr 1, 2019, at 7:02 PM, Dave  wrote:
> 
> As classes get more complex, it is good to call a function to do some of the 
> processing, and make the code easier to follow.  My question is how to do 
> that?  I've attached some silly code to illustrate the point.  The error is: 
> name 'validScale' is not defined.  Well, yes it is, but maybe not the correct 
> way.  Suggestions?
> 
> Dave,
> 
> class TempConverter():
>""" Temperature Converter converts a tempeature from one scale
>to another scale.  For example: 32, F, C will return
>0 degrees C
>"""
> 
>def __init__(self, temperature, scale, newScale):
>self.temperature = temperature
>self.scale = scale
>self.newScale = newScale
> 
>def validScale(self, scaleName):
>if scaleName.upper == 'F' or 'C' or 'K':
>return True
>else:
>return False
> 
>def convertTemp(self):
>""" Converts temperature scale if scales valid."""
>if validScale(self.scale):
>scaleValid = True
>if validScale(self.newScale):
>newScaleValid = True
>if scaleValid and newScaleValid:
>print('Scale converted')
>else:
>msg = "There was and error with the scales entered.\n"
>msg = msg + "You entered: " + self.scale
>msg = msg + ' ' 'and' + self.newScale
>print(msg)
> 
> if __name__ == "__main__":
>myclass = TempConverter(32, 'f', 'c')
>myclass.convertTemp()
> -- 
> https://mail.python.org/mailman/listinfo/python-list
> 

To answer your specific question, you call a method in the same class by 
calling:  self.methodName   For example:  self.validScale

However, once you fix that, you wind find that the if statement in that method 
is not built correctly.

Also, since the variable self.scale is already set in your __init__ method, 
there is no need to pass it into your function.  You could just use self.scale 
inside that method.

Irv

-- 
https://mail.python.org/mailman/listinfo/python-list


How call method from a method in same class?

2019-04-01 Thread Dave
As classes get more complex, it is good to call a function to do some of 
the processing, and make the code easier to follow.  My question is how 
to do that?  I've attached some silly code to illustrate the point.  The 
error is: name 'validScale' is not defined.  Well, yes it is, but maybe 
not the correct way.  Suggestions?


Dave,

class TempConverter():
""" Temperature Converter converts a tempeature from one scale
to another scale.  For example: 32, F, C will return
0 degrees C
"""

def __init__(self, temperature, scale, newScale):
self.temperature = temperature
self.scale = scale
self.newScale = newScale

def validScale(self, scaleName):
if scaleName.upper == 'F' or 'C' or 'K':
return True
else:
return False

def convertTemp(self):
""" Converts temperature scale if scales valid."""
if validScale(self.scale):
scaleValid = True
if validScale(self.newScale):
newScaleValid = True
if scaleValid and newScaleValid:
print('Scale converted')
else:
msg = "There was and error with the scales entered.\n"
msg = msg + "You entered: " + self.scale
msg = msg + ' ' 'and' + self.newScale
print(msg)

if __name__ == "__main__":
myclass = TempConverter(32, 'f', 'c')
myclass.convertTemp()
--
https://mail.python.org/mailman/listinfo/python-list