Ordered Ordinal number methods

2019-02-03 Thread Avi Gross
[NOTE: message is a tad long as it discusses multiple possible solutions and
concerns including code.]

 

The original question was how to do some reasonable translation from
something like the "switch" statement in languages that have it, including C
and R. Other languages use their own variants like cond in LISP. Some have
nothing quite like it. They also differ in many ways such as the ability to
handle arbitrary conditions or bundle multiple conditions to result in the
same result.

 

AS noted, Python deliberately omitted this feature entirely and it is
suggested that one method is to use multiple "elif" clauses. I did a search
to see if some module may play games with that notation to solve the
specific issue relating to how to produce strings from the numbers in the
range of 1:31 used in months on the calendar used in much of the world.
(there are calendars limited to about 29 I use regularly.)

 

Here is a page where a method is shown using that construction:

 

https://codereview.stackexchange.com/questions/41298/producing-ordinal-numbe
rs

 

def ordinal(self, num):

"""

  Returns ordinal number string from int, e.g. 1, 2, 3 becomes 1st, 2nd,
3rd, etc.

"""

self.num = num

n = int(self.num)

if 4 <= n <= 20:

  suffix = 'th'

elif n == 1 or (n % 10) == 1:

  suffix = 'st'

elif n == 2 or (n % 10) == 2:

  suffix = 'nd'

elif n == 3 or (n % 10) == 3:

  suffix = 'rd'

elif n < 100:

  suffix = 'th'

ord_num = str(n) + suffix

return ord_num

 

The above is not my code. It is an example of how someone else solved a
similar problem. It is clearly not a free function but a method. You can
easily modify it and I annotate it below that way as a simple function  to
ask some dumb questions. But first, the IF is followed by a sequence of ELIF
and no ELSE at the end. It works but is not written in a style I might
choose. It does illustrate a sort of way to do cases where a switch might be
used elsewhere. My earlier examples using inline and nested IF statements
realistically could be expanded into something more like this, too.

 

Here is the altered code with comments:

 

def ordinal(num):

"""

  Returns ordinal number string from int, e.g. 1, 2, 3 becomes 1st, 2nd,
3rd, etc.

"""

n = int(num)

if 4 <= n <= 20:

  suffix = 'th'

elif n == 1 or (n % 10) == 1:

  suffix = 'st'

elif n == 2 or (n % 10) == 2:

  suffix = 'nd'

elif n == 3 or (n % 10) == 3:

  suffix = 'rd'

elif n < 100:

  suffix = 'th'

ord_num = str(n) + suffix

return ord_num

 

I do like the way the above function accepts any kind of argument that can
be converted to an int. It does have a serious flaw in that ordinal(100) and
beyond generate an error. It does return 0th on 0 and the slightly odd -1th,
-2th and so on.

 

My approach was to look for patterns and note we cared only as a first
approximation at numbers ending with 1,2,3 as special and even then, only if
the preceding column was a 1. The teens are an exception. The above uses a
different paradigm using inequalities so anything between 4 and 20
(inclusive) is noted as a "th" then a slightly redundant check for ending in
1 is checked as the sole exception of 11 has already been handled earlier.

 

Now is the following redundant or efficient?

 

elif n == 1 or (n % 10) == 1:

 

The reality is that "1 % 10 " also matches n being 1. The OR though is a
short-circuit so in the case that n == 1, the mod operator and comparison is
skipped.

 

Going on, a similar check is made for numbers ending in 2 and then 3. The
last condition requires the number to be less than 100. Strictly speaking,
the 100th would also be fine. And, as noted in another message, simply
taking any positive number modulo 100 gets the same result so 103 would
follow the rule for 3 and become 103rd.

 

But if you really wanted to emulate a more strict model, a set of elif with
exact integers would be reasonable using 31 conditions.

 

if num == 1: suff = "st"

elif num == 2: suff = "nd"

. # 3 through 30

elif num == 31: suff = "st"

 

That is horrible code and in the worst case does 31 comparisons.

 

Not sure if the "in" operator is cheap enough for this version:

 

if num in [1,21,31]: suff = "st"

elif num in [2,22]: suff = "nd"

elif num in [3,23]: suff = "rd"

else: suff = "th"

That has fewer comparisons albeit the "in" operator does additional
searches. And, it does not scale up well as continuing to 100 means adding
items like 32 and 33 and 41 to the lists.

 

I already showed ways to make a dictionary version but there seem to be an
indefinite number of variations on how to solve ANYTHING in python despite
the founding lie that it is designed to do everything ONE way when possible.


 

I thought to use functions in the dictionary instead, but as these are
called without any known way to include arguments, I see no advantage in
making 4 functions that eac

Re: Number methods

2007-01-21 Thread Ziga Seilnacht
Nick Maclaren wrote:
> I can't find any description of these.  Most are obvious, but some
> are not.  Note that this is from the point of view of IMPLEMENTING
> them, not USING them.  Specifically:

The Python equivalents of these methods are described in the
reference manual:
http://docs.python.org/ref/numeric-types.html

More details can be founf in various PEPs:
http://www.python.org/dev/peps/

> Does Python use classic division (nb_divide) and inversion (nb_invert)
> or are they entirely historical?  Note that I can very easily provide
> the latter.

Python uses classic divison by default. True divison is used only when
the division __future__ directive is in effect. See PEP 238 for
details:
http://www.python.org/dev/peps/pep-0238/

The nb_invert method is used for the implementation of the bitwise
inverse unary operator (~). I don't think that it is deprecated. See:
http://docs.python.org/lib/bitstring-ops.html for details.

> Is there any documentation on the coercion function (nb_coerce)?  It
> seems to have unusual properties.

It is used for old style Python classes and extension types that
don't have Py_TPFLAGS_CHECKTYPES in their tp_flags. See:
http://docs.python.org/ref/coercion-rules.html
and
http://www.python.org/dev/peps/pep-0208/
for details.

Ziga

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


Number methods

2007-01-17 Thread Nick Maclaren

I can't find any description of these.  Most are obvious, but some
are not.  Note that this is from the point of view of IMPLEMENTING
them, not USING them.  Specifically:

Does Python use classic division (nb_divide) and inversion (nb_invert)
or are they entirely historical?  Note that I can very easily provide
the latter.

Is there any documentation on the coercion function (nb_coerce)?  It
seems to have unusual properties.

Thanks for any hints.


Regards,
Nick Maclaren.
-- 
http://mail.python.org/mailman/listinfo/python-list