Best way to start

2009-04-06 Thread Avi
Hi,

What is a good way to learn Python?

Do you recommend going by a book (suggestions welcome) or learning
with tutorials? Both?

Thanks in advance,
Avi
--
http://mail.python.org/mailman/listinfo/python-list


Re: Best way to start

2009-04-06 Thread Avi
A BIG Thanks to Chris and Andrew for suggestions.

This is an awesome place.

namekuseijin: haha...got a friend hooked to Python on chat? hilarious!
--
http://mail.python.org/mailman/listinfo/python-list


Floor value in math operators

2009-04-08 Thread Avi
Hi,

This will be a very simple question to ask all the awesome programmers
here:

How can I get answer in in decimals for such a math operator:

3/2

I get 1. I want to get 1.5

Thanks in advance,
Avi
--
http://mail.python.org/mailman/listinfo/python-list


Re: Floor value in math operators

2009-04-09 Thread Avi
On Apr 9, 8:26 am, David Smith  wrote:
> AggieDan04 wrote:
> > On Apr 8, 12:08 pm, David Smith  wrote:
> >> Avi wrote:
> >>> Hi,
> >>> This will be a very simple question to ask all the awesome programmers
> >>> here:
> >>> How can I get answer in in decimals for such a math operator:
> >>> 3/2
> >>> I get 1. I want to get 1.5
> >>> Thanks in advance,
> >>> Avi
> >> I'm going to assume your operands are variables instead of numeric
> >> literals.  Why not consider doing a type conversion to float or Decimal
> >> and then perform the division?
>
> > Because float(x) and Decimal(x) fail for complex numbers and lose
> > precision if x is a rational or a multi-precision float.
>
> The OP didn't ask for anything complicated or high precision -- just
> wanted to divide two integer values and get a float/Decimal output.
>
> --David

Wow! I am overwhelmed by how much support I have at my finger tips. I
was hesitant to ask such a silly question and was worrying of being
ridiculed.

Clearly, I have gained a lot by reading everyone's responses.

Thanks!
Avi
--
http://mail.python.org/mailman/listinfo/python-list


Scrap Posts

2009-04-09 Thread Avi
Hey Folks,

I love this group and all the awesome and python savvy people who post
here. However I also see some dumb posts like 'shoes' or something
related to sex :(

What can we do about crap like this? Can we clean it up? Or atleast
flag some for removal.

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


Re: Teething troubles with Python on a Mac

2008-08-03 Thread Avi
> Apart from the initial installation of Python itself, I
> never use an installer to install a Python package if I
> can avoid it. I wouldn't trust it to install into the right
> Python version.

On that: how would I go about updating the system Python, then?  Or is
that going to be stuck at whatever it is, and Mac users are expected
to run two simultaneous Python installations?  I'm not entirely
comfortable with having a separate MacPython (I used to do so, but it
caused so many issues with installing new packages that I gave up on
it) and would prefer to just update system Python.

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


Re: Local variable definition in Python list comprehension

2022-09-01 Thread Avi Gross
Dumb question. Your y is purely a function of x. So create an f(x) where
you want your y. It probably can even be anonymous inline. I mean your
return values of (x, y) would be (x, f(x)) ...

On Thu, Sep 1, 2022, 5:04 PM Chris Angelico  wrote:

> On Fri, 2 Sept 2022 at 06:55, James Tsai  wrote:
> >
> > 在 2022年9月1日星期四 UTC+2 18:34:36, 写道:
> > > On 9/1/22, James Tsai  wrote:
> > > >
> > > > I find it very useful if I am allowed to define new local variables
> in a
> > > > list comprehension. For example, I wish to have something like
> > > > [(x, y) for x in range(10) for y := x ** 2 if x + y < 80], or
> > > > [(x, y) for x in range(10) with y := x ** 2 if x + y < 80].
> > > >
> > > > For now this functionality can be achieved by writing
> > > > [(x, y) for x in range(10) for y in [x ** 2] if x + y < 80].
> > > You can assign a local variable in the `if` expression. For example:
> > >
> > > >>> [(x, y) for x in range(10) if x + (y := x**2) < 30]
> > > [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16)]
> >
> > Yeah this works great but like [(x, y) for x in range(10) for y in
> [x**2]] I written before, is kind of a hack. And if initially I do not need
> an "if" condition in the list comprehension, this becomes less convenient.
> I still can write
> > >>> [(x, y) for x in range(10) if (y := x**2) or True]
> >
> > But I wonder if Python could have a specific syntax to support this.
> >
>
> But why would you need to assign to y in that example? If you're using
> it more than once, you can use :=, and if you aren't, you don't need
> to. But do be aware that := does not create a comprehension-local name
> binding, but a nonlocal instead.
>
> > No but very often when I have written a neat list/dict/set
> comprehension, I find it very necessary
> > to define local variable(s) to make it more clear and concise. Otherwise
> I have to break it down
> > to several incrementally indented lines of for loops, if statements, and
> variable assignments,
> > which I think look less nice.
>
> Well, if it's outgrown a list comp, write it on multiple lines. Like I
> said, not everything has to be a one-liner.
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: What to use for finding as many syntax errors as possible.

2022-10-09 Thread Avi Gross
Anton

There likely are such programs out there but are there universal agreements
on how to figure out when a new safe zone of code starts where error
testing can begin?

For example a file full of function definitions might find an error in
function 1 and try to find the end of that function and resume checking the
next function.  But what if a function defines local functions within it?
What if the mistake in one line of code could still allow checking the next
line rather than skipping it all?

My guess is that finding 100 errors might turn out to be misleading. If you
fix just the first, many others would go away. If you spell a variable name
wrong when declaring it, a dozen uses of the right name may cause errors.
Should you fix the first or change all later ones?



On Sun, Oct 9, 2022, 6:11 AM Antoon Pardon  wrote:

> I would like a tool that tries to find as many syntax errors as possible
> in a python file. I know there is the risk of false positives when a
> tool tries to recover from a syntax error and proceeds but I would
> prefer that over the current python strategy of quiting after the first
> syntax error. I just want a tool for syntax errors. No style
> enforcements. Any recommandations? -- Antoon Pardon
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for -- else: what was the motivation?

2022-10-09 Thread Avi Gross
Smallest code blocks first may be a more modern invention.

Some would argue for a rule related to efficiency of execution. When you
have multiple blocks as in an if-else or case statement with multiple
choices, that you order the most common cases first. Those shorten
execution more often than the rarer cases especially the ones that should
never happen.

There are obvious exceptions like the default having to be last, albeit
some languages allow the default to be inserted anywhere visually even if
the code sort of runs last.

But negating a condition so smaller code appears first may have some cost.
I mean if !function() may be slower as the negating is an extra step. But
it may be even slower if the inversion is done using a wrapper function
that simply inverts the return value from the other function.

I think sometimes a comment placed carefully that explains the code and
logic in concise form is a simpler approach that can be followed by a big
chunk then little chunk without loss of readability.

In the original example the else part can be mentioned before the loop as a
sort of reminder.

In my experience, the size of code often varies within a project so a
smaller chunk may grow as requirements change, such as adding debug or
logging, and large chunks can shrink as common parts of the code get
extracted into functions.

So not a rule but realistically not always a bad idea to write code in a
way that draws the attention of readers along the main path of execution
and perhaps not showing all the checking for odd cases first. I mean as an
example if the argument is of type text then do stuff, else if a number
else if a symbol else if empty  ...

On Sun, Oct 9, 2022, 1:18 AM Chris Angelico  wrote:

> On Sun, 9 Oct 2022 at 16:05, Axy via Python-list 
> wrote:
> >
> >
> > On 09/10/2022 05:47, Chris Angelico wrote:
> > > On Sun, 9 Oct 2022 at 15:39, Axy via Python-list <
> [email protected]> wrote:
> > >> Got it, thanks!
> > >>
> > >> Actually the reason I never used "else" was the violation of the rule
> of
> > >> beauty "shortest block first". With if--else you can easily follow
> this
> > >> rule by inverting "if" expression, but with for--else you can't. The
> > >> loop body of the simplest example is already three lines, in real life
> > >> things are much worse.
> > >>
> > > That's not a rule I've ever been taught; how important is it?
> > >
> > > ChrisA
> >
> > It gets important if the lifetime of your project is more than three
> > months and is extremely important if more than 10 years. But, it depends.
>
> Yes, I'm aware that code readability becomes irrelevant for
> short-duration projects. Beside the point. I'm wondering how important
> it really is to have the shortest block first.
>
> > I also might be wrong in terminology, anyway, there are many rules that
> > make programmer's life easier, described in the literature from the old
> > good "How to write unmaintainable code" to "The Art of Readable Code".
> > And I hope there are a lot of recent books on this subject I did not
> > track and read yet.
>
> Also not really a justification for "shortest block first". Wanting
> some elaboration on that. What's the value in it?
>
> Given that for-else is an excellent, if rarely-used, construct, I
> would say that, *at least*, it is worth setting aside this rule for
> that particular situation. It is also generally worth using fewer
> commas than I just did. Take my advice with a grain of salt.
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for -- else: what was the motivation?

2022-10-09 Thread Avi Gross
Since many languages allow placing multiple statements on one line or
spreading one over many lines, it seems that the number of lines in code
can be adjusted.

If I have a line like:

 Alpha, beta, gamma, delta = 1, 2, 3, 4

Could that be rewritten as 4 or more lines?

I have seen programmers who have taken an elegant pipeline I have built
apart and made it into many lines of code reassignment the value of each
step to the same or different variables and other ways of lengthening or
obscuring my intent.

So although size may matter, so can sighs.

On Sun, Oct 9, 2022, 4:24 AM Peter J. Holzer  wrote:

> On 2022-10-09 05:37:59 +0100, Axy via Python-list wrote:
> > Actually the reason I never used "else" was the violation of the rule
> > of beauty "shortest block first".
>
> That's a weird rule.
>
> I can see justifications for "most common case first" and "most special
> case first", but ordering the cases in an if/elif/else statement by
> length seems like ordering books by color: It may be pretty, but it
> doesn't make them easy to find.
>
> hp
>
> --
>_  | Peter J. Holzer| Story must make more sense than reality.
> |_|_) ||
> | |   | [email protected] |-- Charles Stross, "Creative writing
> __/   | http://www.hjp.at/ |   challenge!"
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for -- else: what was the motivation?

2022-10-09 Thread Avi Gross
Chris, I was not arguing that at all.

I was saying some rationales about how to order  choices exist based on
ideas like efficiency or other considerations.  Sometimes people are
mistaken as something may take constant time as implemented. And yes, many
rules have countless exceptions. For example, if something is expected to
rarely or never happen, code within that branch may not be needed to be
optimized in any way as long as it works in the remote chance it is called.

I think what was suggested here is more about code readability
considerations and for some of us, making us stand on our heads to puzzle
things out is harder than ordering longer items ...

On Sun, Oct 9, 2022, 12:30 PM Chris Angelico  wrote:

> On Mon, 10 Oct 2022 at 03:22, Avi Gross  wrote:
> >
> > Smallest code blocks first may be a more modern invention.
> >
> > Some would argue for a rule related to efficiency of execution. When you
> > have multiple blocks as in an if-else or case statement with multiple
> > choices, that you order the most common cases first. Those shorten
> > execution more often than the rarer cases especially the ones that should
> > never happen.
> >
>
> Seems fairly dubious and full of special-cases. If you want to follow
> that rule, it should be easy enough to still permit for-else clauses.
> It's an extremely weak argument against for-else.
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for -- else: what was the motivation?

2022-10-09 Thread Avi Gross
Fair enough, Chris. There may be some overlap with the size of code for the
most common cases but sometimes the opposite as those may be more complex
to deal with.

A reality for many programmers today is to not micromanage too early as
things are often fast enough and any tweaking is best done only in critical
areas. The emphasis may be on the programmer experience in writing fast
code with fewer errors. Perhaps secondary but often important is making the
code maintainable and in my experience that can often be best done by
choosing meaningful names and brief selective comments than by worrying
about the size of blocks of code.

But others obviously preach what they think works for them even when it may
constrain others more than it helps.

I have seen people suggest that all variables have short names like a3 but
that does not mean it improves anything other than the size of the code and
parsing it. The loss in readability and so on probably is worse.


On Sun, Oct 9, 2022, 12:53 PM Chris Angelico  wrote:

> On Mon, 10 Oct 2022 at 03:46, Avi Gross  wrote:
> >
> > Chris, I was not arguing that at all.
>
> Maybe not intentionally, but you did lend a lot of weight to that argument
> :)
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: What to use for finding as many syntax errors as possible.

2022-10-09 Thread Avi Gross
Antoon,  it may also relate to an interpreter versus compiler issue.

Something like a compiler for C does not do anything except write code in
an assembly language. It can choose to keep going after an error and start
looking some more from a less stable place.

Interpreters for Python have to catch interrupts as they go and often run
code in small batches. Continuing to evaluate after an error could cause
weird effects.

So what you want is closer to a lint program that does not run code at all,
or merely writes pseudocode to a file to be run faster later.

Many languages now have blocks of code that are not really be evaluated
till later. Some code is built on the fly. And some errors are not errors
at first. Many languages let you not declare a variable before using it or
allow it to change types. In some, the text is lazily evaluated as late as
possible.

I will say that often enough a program could report more possible errors.
Putting your code into multiple files and modules may mean you could
cleanly evaluate the code and return multiple errors from many modules as
long as they are distinct. Finding all errors is not possible if recovery
from one is not guaranteed.

Take a language that uses a semicolon to end a statement. If absent usually
there would be some error but often something on the next line. Your
evaluator could do an experiment and add a semicolon and try again. This
might work 90% of the time but sometimes the error was not ending the line
with a backslash to make it continue properly, or an indentation issue and
even spelling error. No guarantees.

Is it that onerous to fix one thing and run it again? It was once when you
handed in punch cards and waited a day or on very busy machines.

On Sun, Oct 9, 2022, 1:03 PM Antoon Pardon  wrote:

>
>
> Op 9/10/2022 om 17:49 schreef Avi Gross:
> > My guess is that finding 100 errors might turn out to be misleading. If
> you
> > fix just the first, many others would go away.
>
> At this moment I would prefer a tool that reported 100 errors, which would
> allow me to easily correct 10 real errors, over the python strategy which
> quits
> after having found one syntax error.
>
> --
> Antoon.
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for -- else: what was the motivation?

2022-10-09 Thread Avi Gross
Peter,

There can be excellent reasons to undo a pipeline like I described. I often
write it carefully in smaller chunks while debugging and make it more
elegant later ...

But someone amused me by explaining they were going to let people believe
the code was written by them so it had to fit their style and abilities.
That meant removing most of my comments, renaming some variables, taking
out code that checked things like whether a file existed before opening it
and of course no pipelines. It had to be downgraded and had I known, I
could have easily given them code written as if it was in some poorer
language.

Python has idioms often used in making pipes of a sort but in languages
with other forms, such as R, debugging is not that difficult as you can
insert functions in middle of a pipeline that print what you want but
return the data structure they were fed for the next step in the pipeline.
When done, remove the lines with such entries or change the function
definition or something like that.

Objects used as pipelines do not do this as easily as you may need to add
methods ...


On Sun, Oct 9, 2022, 1:17 PM Peter J. Holzer  wrote:

> On 2022-10-09 12:34:22 -0400, Avi Gross wrote:
> > I have seen programmers who have taken an elegant pipeline I have built
> > apart and made it into many lines of code reassignment the value of each
> > step to the same or different variables and other ways of lengthening or
> > obscuring my intent.
>
> I have certainly done that (not with your code, AFAIK). The problem with
> those beautiful one-liners is that they are really hard to debug. So if
> I can't convince myself that they are correct just by reading them I
> have to split them over multiple lines so I can add breakpoints or log
> messages. Of course I could put it together again afterwards, but I
> would argue that if I didn't understand it the first time it's probably
> better to leave it in its more verbose and debuggable state.
>
> Of course I have also done the opposite: Taken some messy and
> complicated code and simplified it into a simple generator expression.
> In fact I would say that I code tends to be shorter after I fixed a bug
> than before.
>
>
> > So although size may matter, so can sighs.
>
> :-)
>
> hp
>
> --
>_  | Peter J. Holzer| Story must make more sense than reality.
> |_|_) ||
> | |   | [email protected] |-- Charles Stross, "Creative writing
> __/   | http://www.hjp.at/ |   challenge!"
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: What to use for finding as many syntax errors as possible.

2022-10-09 Thread Avi Gross
I will say that those of us  meaning me, who express reservations are not
arguing it is a bad idea to get more info in one sweep. Many errors come in
bunches.

If I keep calling some function with the wrong number or type of arguments,
it may be the same in a dozen places in my code. The first error report may
make me search for the others places so I fix it all at once. Telling me
where some instances are might speed that a bit.

As long as it is understood that further errors are a heuristic and
possibly misleading,  fine.

But an error like setting the size of a fixed length data structure to the
right size may result in oodles of errors about being out of range that
magically get fixed by one change. Sometimes too much info just gives you a
headache.

But a tool like you described could have uses even if imperfect. If you are
teaching a course and students submit programs, could you grade the one
with a single error higher than one with 5 errors shown imperfectly and
fail the one with 600?

On Sun, Oct 9, 2022, 1:53 PM Antoon Pardon  wrote:

>
>
> Op 9/10/2022 om 19:23 schreef Karsten Hilbert:
> > Am Sun, Oct 09, 2022 at 06:59:36PM +0200 schrieb Antoon Pardon:
> >
> >> Op 9/10/2022 om 17:49 schreef Avi Gross:
> >>> My guess is that finding 100 errors might turn out to be misleading.
> If you
> >>> fix just the first, many others would go away.
> >> At this moment I would prefer a tool that reported 100 errors, which
> would
> >> allow me to easily correct 10 real errors, over the python strategy
> which quits
> >> after having found one syntax error.
> > But the point is: you can't (there is no way to) be sure the
> > 9+ errors really are errors.
> >
> > Unless you further constrict what sorts of errors you are
> > looking for and what margin of error or leeway for false
> > positives you want to allow.
>
> Look when I was at the university we had to program in Pascal and
> the compilor we used continued parsing until the end. Sure there
> were times that after a number of reported errors the number of
> false positives became so high it was useless trying to find the
> remaining true ones, but it still was more efficient to correct the
> obvious ones, than to only correct the first one.
>
> I don't need to be sure. Even the occasional wrong correction
> is probably still more efficient than quiting after the first
> syntax error.
>
> --
> Antoon.
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for -- else: what was the motivation?

2022-10-16 Thread Avi Gross
Interesting idea, Anton.

I would be interested in hearing more detail on how it would work.

Although much of programming has been centered on the Latin alphabet and
especially English, that may change. I can imagine a customized compiler or
interpreter that uses key words in the local language instead of for or
while or if or else or even import.

If a region of UNICODE was set aside, would it have to be as a sort of
additional ALT or shift key for anything, or just English characters or
would it be for abstract symbols that would be mapped to and from a long
list of reserved key words that may vary by locale?

A serious problem I have been noting is the interactions between
typographical paradigms never expected to interact. I mean special
characters allowed or expected that clash. An example in Python and many
other languages is regular expressions. When using a string of characters,
you may have to deal with the rules for evaluating a string of that type
and double up backslash characters or be carefully as a dollar sign or
curly brace might invoke a side effect and interpolate something into it.
But for languages that allow RE to be entered without a string as in /.../
you have to write it differently.

I noted other ways in which naming conventions and even sort of keywords
need special care. Consider a Javascript program in a browser that can read
and manipulate HTML and CSS. The rules for names in JS do not allow hyphens
while others often do. So the programmers making the structures in the DOM
had to twist things. To access something like font-type you ask for font
Type as an example by changing the identifier to camel case.

I sometimes have programs that combine R and Python somewhat
interchangeably and it highlights places the naming does not match. R
allows periods as parts of names as in my.data and almost anything
including spaces if you use grave accent quotes such as `one [identifier`
so it is perfectly valid to have a function call like `[`(x, 5) to mean
x[5] albeit explaining why that is useful is beyond the scope. Similarly
you can make all kinds of in-line functions between percent signs as in %*%
or %specialized computation% and you sort of make your own keywords albeit
Chris and others may rightly suggest they are something else rather than
the first level of syntax.

My point is that your idea may need to support keywords for disparate ideas
and languages.

On Sun, Oct 16, 2022, 6:20 AM Antoon Pardon  wrote:

> Op 16/10/2022 om 00:50 schreef [email protected]:
> > This has been discussed so often precisely because I swear NO CHOICE of
> keyword would satisfy everybody! Most languages start with designated
> keywords and some reserve a few for later use. But then things can get
> frozen in place to avoid breaking existing programs or break older
> compilers/interpreters.
> >
> > Some languages use techniques to extend themselves more harmlessly such
> as creating a singleton object that has content that can be regular data as
> in math.pi, or functions/methods or new ides like "Symbols" that allow all
> kinds of extensions to the language in a fairly harmless way as no older
> program would likely have used features that did not exist.
> >
> > That might not easily solve this problem. But I wonder if reserving some
> kind of prefix might help, so anything like extension.0nNoBreak could be
> added to a loop as a final clause and be treated as a non-key keyword of
> sorts.
>
> My idea would be to reserve different unicode blocks for the keywords
> and the identifiers. e.g. We could reserve the mathematical alphanumeric
> block for keywords and all other letters and numbers for identifiers.
> Doing so would allow extenting the keywords without breaking programs
> that already use that combination as an identifier.
>
> Python could slowly transition in this direction by first allowing the
> current keywords to be in this block. Every new keyword would only be in
> that unicode block. If would then be possible to write python code with
> this convention but it wouldn't be obligatory. After some time the
> python developers could decide to make it obligatory.
>
> I doubt this will idea will get from the ground, but I think it would
> allow for a smoother transition into new concepts, as it is no longer a
> strugle searching for a keyword that will break as little programs as
> possible.
>
> --
> Antoon Pardon.
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-20 Thread Avi Gross
There is no guarantee that argv is consulted earlier in the program than
other modules will use it for communication.

Consider a case where a program does look at argv but later wants to call
another program using some or all of the components of argv and now there
are added components there. That could lead to all kinds of problems.

Some languages have global objects available that you can add to, sort of
like a dictionary object and as long as you add keys guaranteed  to be
unique,  can be used carefully to coordinate between parts of your program.
Of course, you may also need to use techniques that ensure atomic
concurrency.

Reusing argv is a hack that should not be needed.


On Sat, Nov 19, 2022, 4:37 PM Thomas Passin  wrote:

> On 11/19/2022 4:28 PM, Thomas Passin wrote:
> > On 11/19/2022 3:46 PM, Michael F. Stemper wrote:
> >> On 18/11/2022 04.53, Stefan Ram wrote:
> >>>Can I use "sys.argv" to pass information between modules
> >>>as follows?
> >>>
> >>>in module A:
> >>>
> >>> import sys
> >>> sys.argv.append( "Hi there!" )
> >>>
> >>>in module B:
> >>>
> >>> import sys
> >>> message = sys.argv[ -1 ]
> >>
> >> I just tried and it appears that one can append to sys.argv. However,
> >> it seems like an incredibly bad idea.
> >
> > For that matter, you can just directly add attributes to the sys module,
> > no need to use sys.argv:
> >
> >  >>> import sys
> >  >>> sys._extra = 'spam'   # Not an exception
> >  >>> print(sys._extra)
> > spam
> >
> > Probably not the best idea, though.  Better to use some module that you
> > control directly.
>
> This could be one of those things of which Raymond Chen (The Old New
> Thing) asks "what if everyone did this?".  Imagine if every
> (non-standard-library) module misused sys or sys.argv like this.  The
> result could be chaotic.
>
> Best to put all your own stuff into modules that you yourself control.
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


dealing with infinite generators

2018-12-02 Thread Avi Gross
[SPECULATION ALERT]

I found it interesting as people discussed  how one gets the length of
something set up to follow the iterator protocol and especially anything
that is effectively infinite.

It is possible in python to set a value of "inf" using methods like this:

>>> x = float("inf")
>>> x
inf
>>> x+x
inf
>>> x-x
nan
>>> x*x
inf
>>> x**x
Inf

There is also a "-inf" but length somehow stubbornly seem to remain
non-negative.

So if you made an object that iterates say prime numbers in sequence or
powers of 2 or anything known to be infinite mathematically, if not
practically, and wanted to know the length of the object you could have a
method like this in the class definition:

 def  __len__(self) : return(float("inf"))

There would be no need to count the contents. As stipulated, the count would
take an infinite amount of time, give or take epsilon.

Similarly, if you had some iterator like range(1,100,2) that is large
but not infinite, you could set it up so it calculates how many potential
entries it might have when created using simple modular arithmetic, then
save that in a variable. The __next__() method could decrement that variable
and the __len__() method would return that variable. Again, no need to
count.

Now there may well be iterables for which this is not simple or even doable.
If the iterable starts with a list of strings containing all the words in a
book in order and returns one unique word each time by popping the first off
the list then removing any copies, then the length is not known unless you
remove all duplicates at the time you instantiate the instance. But that
sort of reduces it to a list of unique strings and if the point is to quit
iterating long before the list empties, you already did all the work.

Realistically, much python code that looks like:
  for f in iterable:

often does not need to know the length ahead of time.

The other related topic was how to deal with an unpacking like this:

a, b, *c = SOMETHING

If something may be an infinite iterator, or perhaps just a large one, would
you want c instantiated to the rest all at once?

One idea is to not get c back as a list but rather as a (modified) iterator.
This iterator can be expanded or used later in the obvious ways, or simply
ignored.

In newer versions of python the yield statement in a generator can accept a
value from the calling routine. I can imagine having a version of an
iterator that will be called for the first time and return a value, then
some time later, one of the next() calls would include a message back saying
that this call should result in getting back not a value but another
iterator that would continue on. I mean if you asked for:

a, b, *c = range(1,1000, 2)

a would get 1
b would get 3
c would not get  [5, 7, 9 ... 999] as it does now.
c would get something like this:

>>> repr(range(5,1000, 2))
'range(5, 1000, 2)'
>>> type(range(5,1000, 2))


Or perhaps get back the results of iter(range(...)) instead.

How would the unpacking operation know what you wanted? My guess is there
are multiple possible ways with anyone complaining no matter what you
choose. But since * and ** are taken to mean unpack into a list or dict, I
wonder if *** is available as in:

a, b, ***c = range(1,1000, 2)

And there are often other solutions possible like making the unpacking
happen with a function call that takes an extra argument as a flag instead
of the above method, or just setting some variable before and/or after that
line to control how greedy the match is, sort of.

Clearly many existing iterators may not be easy to set up this way. The
range() function is particularly easy to modify though as the internals of
the generator function keep track of start, stop, step as shown below:

>>> initial = range(1,10,2)
>>> initial.start, initial.stop, initial.step
(1, 10, 2)

So if asked to return a new iterating object, they can do a computation
internally of what the next result would have been and say it is 7, they
would return range(7,10,2) and presumably exit.

Just some speculation. Adding new features can have odd side effects if you
go to extremes like infinities.


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


RE: dealing with infinite generators

2018-12-03 Thread Avi Gross
Morten,

 

I did not mean that programming languages don’t already have lots of infinities 
on board. There are plenty of infinite loops that have no terminating 
conditions and the process continues until it is actively killed. There are 
recursive function calls that may miss the call to stop because .001 is not 
exactly equal to zero and so on.

 

The issue here is not really new.

 

Any language allows you to create a loop that calls some function repeatedly 
and will only stop when the function returns nothing or perhaps throws an error.

 

The issue is that python has paradigms that are effectively somewhat hidden 
loops. A list comprehension is a hidden loop as are its cousins like a 
dictionary comprehension and of course generators in general. But unlike 
explicit loops, these constructs may not easily allow you to specify additional 
code. Yes, you probably can using various techniques. But in real loops you can 
set flags and increment variables and test for these conditions.

 

I don’t see any easy way to ask that this terminate after a while perhaps by 
including a modified iterator as the last entry:

 

[ p for p in primes_generator() ]

 

[ p for p in primes_generator() if p < 1000 ]

 

Even if you extended this to check for primes larger than 1,000 it would keep 
running and just not add additional values. Infinite CPU use and no return to 
the user of what they asked for.

 

But for the unpacking, example:

 

a, b, c = iterator

 

I do see how it might make sense to use a notation like ***c, as discussed. 

 

Actually, you made me thing about whether the iterator protocol might be 
amended to deal with infinities.

 

The list comprehension for example takes an “if” clause. I suspect it could 
also be expanded to take a “max” clause after which it stops generating new 
values. Or, since iterators are objects, you might be able to set a value by 
setting iterator.max=99 and have the protocol look for and enforce it so you 
only get the first 99 bottles of beer off the wall.

 

I am curious as to what happens in python if it is trying to expand an iterator 
and runs out of memory. I can imagine it stopping and throwing an exception but 
would it unwind whatever it was trying to do or leave a mess?

 

Because python has lots of flexibility and can potentially add any number of 
dunder hooks to objects, I wonder if there can be a way to designate something 
as potentially infinite when iterated. Any python facet that implements the 
iterator protocol might then be warned and choose not to run the protocol an 
infinite number of times, or perhaps at all. You might have to handle such 
objects more carefully using iter() and next() yourself in your own carefully 
crafted loop that does exit in finite time.

 

Just thinking. If more recent versions of python have done something I am not 
aware of, I would love to know.

 

From: Morten W. Petersen  
Sent: Monday, December 3, 2018 7:14 AM
To: [email protected]
Cc: [email protected]
Subject: Re: dealing with infinite generators

 

On Mon, Dec 3, 2018 at 8:11 AM Avi Gross mailto:[email protected]> > wrote:

[SPECULATION ALERT]

I found it interesting as people discussed  how one gets the length of
something set up to follow the iterator protocol and especially anything
that is effectively infinite.

[...]

Just some speculation. Adding new features can have odd side effects if you
go to extremes like infinities.

 

Well I guess one can't argue with that. 😁

 

-Morten


-- 

Videos at https://www.youtube.com/user/TheBlogologue
Twittering at http://twitter.com/blogologue

Blogging at http://blogologue.com
Playing music at https://soundcloud.com/morten-w-petersen

Also playing music and podcasting here: 
http://www.mixcloud.com/morten-w-petersen/

On Google+ here https://plus.google.com/107781930037068750156

On Instagram at https://instagram.com/morphexx/

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


RE: Why Python don't accept 03 as a number?

2018-12-07 Thread Avi Gross
[[READERS DIGEST CONDENSED ANSWER: use int("string") ]]

Since we all agree python will not make notations like "05" work
indefinitely, and the need expressed is how to solve a symbolic puzzle (see
message below) then it makes sense to look at alternate representations.

I have a question first. How are you solving your puzzles? 

ab + aa + cd == ce

Why does 05 ever even appear in your solution?

Are you generating all possible answers by setting each variable to one of 0
to 9 then the second to any of the remaining nine choices then the third to
the remaining 8 and so on? For any method like that, you can presumably make
each component like

ab = 10*a + b

in the loop.

Similarly for aa and cd and ce. If the equality above is true, you found the
solution and break out. If there can be multiple solutions, note the
solution and keep going. But note for the 5 variables above, you are testing
10*9*8*7*6 combinations.

Another idea is to use strings like "05" as bizarrely, the function int()
seems to be an ex eption that does NOT care about leading whitespace or
zeroes:

>>> int("05")
5
>>> int("  0005")
5

And even handles all zeroes:

>>> int("00")
0

You can also use lstrip() with an argument to remove zeros:

>>> a = eval("05".lstrip("0"))
 
>>> a
 
5

If you are in a situation where you only want to remove leading zeroes if
the following character is a digit and not "o" or "b" or "x", use regular
expressions or other techniques.

I will just toss in the possible use of the SymPy module to do actual
symbolic computations to solve some of these. Perhaps a tad advanced.


-Original Message-
From: Python-list  On
Behalf Of [email protected]
Sent: Friday, December 7, 2018 11:25 PM
To: [email protected]
Subject: Re: Why Python don't accept 03 as a number?

Ian at 2018/12/8 UTC+8 AM11:28:34 wrote:
> What is it exactly that you're trying to accomplish with this? Perhaps 
> there's a better way than using eval.

This problem comes from solving a word puzzle,
ab + aa + cd == ce
Each character will be translate to a digit and evaluate the correctness,
03 + 00 + 15 == 18

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

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


RE: Why Python don't accept 03 as a number?

2018-12-08 Thread Avi Gross
Jach,

Just for fun, I looked at the  puzzle you asked about and solved it several
ways without running into your 03 problem at all. There are more efficient
solutions than total brute force.

Anyone not interested, stop here, please. After my explanations, I show a
python program then the output it produces.

The comments in the python program (below) explain the solution classes but
let me suggest a little algebra simplifies the problem so fewer brute force
iterations are needed.

The simplistic algorithm can be written as a single list comprehension with
(in this case) 5 "for" clauses and one "if" clause.

You are solving for: ab + aa + cd == ce

So 
for all digits possible for a
for all remaining digits possible for b each iteration
for all remaining digits possible for c each iteration
for all remaining digits possible for d each iteration
for all remaining digits possible for e each iteration
if the condition applies.

Clearly the above is deeply nested with 10!/5! Iterations or 30,240.

But a little algebra simplifies the solution so c drops out of the equation
as shown below in the comments.
The test becomes:  21*a + b + d - e == 0

You can apply that as the condition using four loops. You get 32 solutions
and for each you can let c be any of 10 possibilities for 320 total
solutions, if I did it right. The number of iterations is now only 5,040 and
you are evaluating fewer terms with c gone. The full test would have been
(10*a +b )+ (10*a + a) + (10*c + d) == (10*c + e)

BUT a tad more analysis shows that all solutions require "a" to be zero. If
a >=1 then 21*a must be >= 21.
But b and c cannot be more than 9+8 which is 17 and subtracting e makes it
no larger. So "a" MUST be zero.

So the solution can be done with only three loops for b, d, and e. 720
iterations.

The commented code is below. It can be done in as little as two lines of
code if the list comprehension is done in one line but why make it hard to
read.

If there is a flaw in my reasoning or the program below, please point it
out. You said there were 192 solutions. I found 320.
And, there are more efficient solutions possible but overkill for this
application.

Avi

### START CODE ##
# GOAL: find all solutions of a puzzle
# ab + aa + cd == ce
# Where each of the letters a through e
# are UNIQUE values ranging from 0 to 9

# Make the equation simpler
# expand ab to 10*a + b
# expand aa to 10*a + a
# expand cd to 10*c + d
# add to get 21*a + b + 10*c + d
# expand ce to 10*c + e
# simplify 21*a + b + 10*c + d = 10*c + e
# the 10*c on both sides cancel.
# RESULT: 21*a + b + d - e = 0
# the value of c is not relevant and
# you can solve without e and then add back
# all ten possibilities later.

# Method:
# Use a set of digits.
# Use a list comprehension with four loops.
# Each loop chooses all available values
# for a,b,d,e by subtracting the set
# of digits already in use at the time from all digits.

digits = set(range(10))

matches = [ (a, b, d, e)
for a in digits
for b in (digits - {a})
for d in (digits -{a,b})
for e in (digits -{a,b,d})
if ( 21*a + b + d - e == 0)
]

print("SOLVING FOR: 21*a + b + d - e == 0")
print(f"matches found in batches of 10: {len(matches)}")

for (a,b,d,e) in matches:
solution =  {'a' : a,
'b' : b,
'c' : 'any digit',
'd' : d,
'e' : e
 }
print(solution)

# Note the result shows all solutions have 'a' being zero.
# That was obvious from the equation as there were 21 of them
# and if a was 1 in 21*a + b + d - e = 0
# then clearly band d cannot be more than 9+8 so no solution
# unless a == 0.
# So you can solve this easier using the above techique by just
# solving b + d - e = 0

matches = [ (b, d, e)
for b in digits
for d in (digits -{b})
for e in (digits -{b,d})
if ( b + d == e)
]

print("\nSOLVING FOR: b + d == e")
print(f"matches found in batches of 10: {len(matches)}")

for (b,d,e) in matches:
solution =  {'a' : '0',
'b' : b,
'c' : 'any digit',
'd' : d,
'e' : e
 }
print(solution)

### END CODE ##
### BEGIN OUTPUT ##
SOLVING FOR: 21*a + b + d - e == 0
matches found in batches of 10: 32
{'a': 0, 'b': 1, 'c': 'any digit', 'd': 2, 'e': 3}
{'a': 0, 'b': 1, 'c': 'any digit', 'd': 3, 'e': 4}
{'a': 0, 'b': 1, 'c': 'any digit&#

RE: Program to keep track of success percentage

2018-12-08 Thread Avi Gross
Tim,

This may be a bit awkward.

I am not sure a question on the python list expects to get a one-liner, let 
alone in an unrelated language like AWK. Unless you install other environments 
like Cygwin, AWK does not tend to be available of platforms like Windows. Ditto 
for PERL and other languages or tools you want to use this way.

There are times people appreciate something sophisticated or clever or even 
innovative.

My personal take on this question is of someone who does not necessarily know 
what they need to do, let alone in python. And they did not specify how the 
data is supplied or whether it is a one-time thing.

The two numbers needed could be supplied on the command line and gotten using 
argv or gotten using two input statements or read from a file or stdin. Or they 
could be asking for a cumulative set of wins/losses to be contiuously evaluated 
and as soon as the threshold of 31% is attained, print a message. OR, there 
could be a previously agreed upon number of games, such as 164, and you get 
win/loss criteria some way and you want the percentage of wins divided by the 
164 to be 31%. 

My GUESS is they are getting a stream of win/win/loss/win/loss/... type of 
data, maybe one per line of text, maybe as 0 versus 1, but who knows. If we 
knew exactly, it might lead to trivial solutions. For example, if they had a 
series of 0/1 you could do a sum() and a count() and divide. 

But what if the scenario was to provide a score like 5 - 3 using whatever 
notation. Now you need to figure out if your side won and perhaps deal with 
ties before counting and dividing.

Too many scenarios are possible but the simple answer is more like someone else 
said.

Count the number of wins, or keep track of it.
Count the total you need.
Divide one by the other and compare it to 0.31 or 31 depending on your 
calculation method.

Your solution in AWK assumes  lots of things. You assume the data is either on 
stdin or comes from automatically opening file names on the command line to 
generate a stream of lines. You assume a win is any line containing one or more 
lower or upper case instances of the letter W. You let AWK count lines and 
store that in NR and assume anything without a W is a loss. You print a running 
commentary and  only at the end of input state if they exceeded 31%.

Now that is quite possibly a way to go. But the data may not be set up that way 
or they may want to quit as soon as the threshold is reached or there may be 
blank lines or a notation for a tie. Some of those may not be one-liners. Yours 
would read much better if spaced out, but you might have written it this way 
when you were 😉

But, as mentioned, this is a python board. Would you care to do the same thing 
as a brief program in that language.

If we had that pesky := operator, maybe. 

Just kidding.

-Original Message-
From: Python-list  On 
Behalf Of Tim Chase
Sent: Saturday, December 8, 2018 4:00 PM
To: Musatov 
Cc: [email protected]
Subject: Re: Program to keep track of success percentage

On 2018-12-08 10:02, Musatov wrote:
> I am thinking about a program where the only user input is win/loss. 
> The program let's you know if you have won more than 31% of the time 
> or not. Any suggestions about how to approach authoring such a 
> program? Thanks. --

Can be done with an awk one-liner:

awk '/[wW]/{w+=1}{printf("W: %i L: %i %i%%\n", w, NR-w, w * 100/NR)}END{if (w * 
100/NR > 31) print "More than 31% winning"}'

-tkc



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

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


RE: Why Python don't accept 03 as a number?

2018-12-08 Thread Avi Gross
[DISCLAIMER: less about python than analysis of a puzzle]

Richard,

Thank you for pointing out that c in the puzzle is constrained. That
explains why my 320 answers are too many. It cannot be 0 as "a" is always
zero and it cannot be the three other values that b,d,e are using at the
time. So my earlier solution should say c is any of six available choices. 

So 6 * 32 is 192 solutions.

Your analysis requires considering a carry from the right column into the
left. I skipped that by converting something like ab to 10*a+b.

This all began with someone trying to enter 03 which suggests they may have
been starting to look at it your way. As a logic puzzle to do those with
pencil and paper, your analysis is spot on. There is additional info to be
gleaned by looking at adding columns. I chose a perspective on more brute
force methods and whittled it down to less forceful. Given that c was
removed from the equation, though, and that only 6 of 10 options are
available for any given time, I would need another pass at the answers and
for each solution for the others (b,d,e if we agree a is always 0) I would
need to make six entries with c set successively to digits-set(0,b,d,e} or
something like that.

I note that programming some of the kinds of analysis some of these puzzles
use is not as easy in programming languages as a more brute-force approach
that computers are better at than humans. 

-Original Message-
From: Python-list  On
Behalf Of Richard Damon
Sent: Saturday, December 8, 2018 5:30 PM
To: [email protected]
Subject: Re: Why Python don't accept 03 as a number?

On 12/8/18 12:40 PM, Avi Gross wrote:
> You are solving for: ab + aa + cd == ce

Actually, an even quicker analysis for this particular problem is:

from the 10s digits, a + a + c + carryin = c Thus a and carryin must both be
0 (carryin can not be negative, nor any of the variables)

thus the final solution space is:

b + d = e
a = 0
c any other digit (6 possible values for every combo of b, d, e)

if b is <= 4, there are 8-b possible values of d that will have a legal
value of e.
b = 1, we get d = 2, 3, 4, ... 7, 8
b = 2, we get d = 1, 3, 4, ... 6, 7 (8 would generate carry) b = 3, we get d
= 1, 2, 4, 5, 6 b = 4, we get d = 1, 2, 3, 5

if b >= 5 we get 9-b possible values of d (we no longer have to omit the
possible value of b  = d)

So the number of possible answers are:

(7+6+5+4+4+3+2+1)*6 = 192

(your 320 was you gave c 10 possible values, but you need to remove the
duplicates).
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: Why Python don't accept 03 as a number?

2018-12-10 Thread Avi Gross
READERS DIGEST CONDENSED QUESTION: How expensive is eval("123 + 456 == 975") 
versus other ways?

The discussion started by Jach has spread away from discussing how python deals 
with numbers starting with leading zeroes such as "03". I note there are many 
ID numbers like social security that have a leading zero so if converted to an 
int for storage reasons, ...

The TOPIC I want to discuss is the concerns about Jach wanting to use "eval()". 
Besides security concerns, I want to know if it is particularly expensive.

It was suggested that you might solve a range of problems like puzzles asking 
you to substitute unique digits for letters. Some of  these puzzles are  
normally solved with logic a step at a time but the techniques used may require 
a specific order and may not be easy to program for a more general case so can 
it be solved using what might be termed brute force. I mean try EVERYTHING that 
might work, including some that might not.

A particular example was: SEND + MORE = MONEY.

Jach's suggestion was to take every possible combination of digits and make the 
substitutions for the letters in that puzzle: then do something like this:

>>> eval ("9567+1085==10652")
True
>>> eval("123+456==975")
False

So, although better algorithms exist, no doubt, I considered what it would take 
to do this without an eval. I came up with the following as an outline.

Accept the puzzle as a string with any number of items to the right or left of 
an "=" as long as they only have whitespace and plus signs in addition to 
alphabetic characters. So "AE + DF = CE + AB + AA" would be fine. This model 
does not include doing subtraction or other things, just a simple model like 
that, for now.

You can easily remove whitespace, force everything to one case, split it into a 
left/right on "=" and then split those into lists on "+.

You now have two lists of alphabetic strings that ultimately must become lists 
of integers and then the sums can be compared.

To get the number of unique letters in the puzzle, N, you throw all the list 
items as individual characters into a set. Clearly, for this kind of puzzle, 
there cannot be more than ten unique letters or there can be no unique mapping 
for 0-9.

I would then "generate" all possible combinations of digits 0-9 of length N. 
There are an amazing number of ways to do that ranging from taking a 
range(10**N) and converting it to a string then a list of numeral characters 
then tossing out any that have any duplicates, to creating a recursive function 
that passes along what has been used so far to the next call. Since many of 
these problems only need ONE solution, the generator would only iterate as many 
times as needed and no giant lists of numbers or strings need be in memory at 
any time.

For each tuple returned  by the generator, you can iterate on the set of unique 
letters and use string functions to substitute the digits, or perhaps do this 
all at once. You would do this to all the items in what I call the left list as 
well as all the items on the right list. These would not be "numeric" so using 
int() on each item  would work EVEN with leading zeroes. Seems safe enough.

Finally, with no eval needed, you take the sum of the numbers in a list of the 
left and compare to the sum on the right and if equal, you present the solution 
in whatever way works. If no more solutions are needed, you quit. I might write 
this part as a generator too, that can be called once or to completion.

Yes, this is brute force. Using range(1,000,000) (no commas in real use) would 
be a million iterations when there are six unique characters in the puzzle and 
as many as 10 billion if all ten are in use. If you use nested loops like I 
showed a while ago (albeit to make arbitrary ones for many sizes could require 
multiple functions or use of an eval on one built by hand) you can cut down the 
number of iterations as the nested loops count down with each one doing one 
less than the one before it. Same goes for the recursive function call method 
as it passes along what numerals  have already been used. There may already be 
a permutation function that does this efficiently in C.

The above description includes parts that may also be used in the eval 
situation. The main difference may be that my method uses int() and perhaps 
some string functions. So, does eval just divert the attention of the 
interpreter as may happen with importing a module, or does it invoke a second 
copy of the interpreter as may happen with some multitasking methods? I would 
guess the former. But it may also have to first compile the text into byte 
code. However, a full eval is like using a sledgehammer when a thumbtack might 
be enough. Then again, it is already sitting there so a little extra use might 
be cheap.

So a main reason for my variant might still be to avoid taking any chances on 
rogue code. Mind you, in the above I would remove everything except [a-zA-Z=+] 
including parentheses and 

03 digression by brute force

2018-12-11 Thread Avi Gross
SYNOPSIS: One way to solve math puzzle by brute force. (message sent earlier 
disappeared)

 

Quick note. Jack started by asking why python does not like decimal numbers 
with leading zeroes. When asked to explain, he said he was trying to solve word 
problems using python. Someone mentioned problems like solving SEND + MORE = 
MONEY and I decided to quickly write a function that would solve anything of 
that sort that only has addition on either side of the equals.

 

What amused me was that I had 25 solutions to the above when I was told there 
would be one. Closer examination showed that 24 of those had the ‘M’ in MONEY 
set to zero which the logicians claimed was not a sensible solution.

 

This solution is one of a list of 25 dictionaries returned, printed with 
pprint.print:

 

{' SYNOPSIS': 'PUZZLE: SEND+MORE=MONEY with SOLUTION #1: 7429+0814=08243',

'D': '9',

'E': '4',

'M': '0',

'N': '2',

'O': '8',

'R': '1',

'S': '7',

'Y': '3'}

 

Note M == 0

 

The lone normal answer is:

 

{' SYNOPSIS': 'PUZZLE: SEND+MORE=MONEY with SOLUTION #25: 9567+1085=10652',

'D': '7',

'E': '5',

'M': '1',

'N': '6',

'O': '0',

'R': '8',

'S': '9',

'Y': '2'}

 

Apparently, unless you tell the program to skip any attempts where M is not 1, 
it finds these. I will spare the rest but include the code if you wish to try 
it. I called the function this (perhaps odd) way:

 

puzzle = "SeND+ MoRe =MoNeY???"

solution25 = math_word_puzzle_solver(puzzle)

 

And it returned a list of the 25 dicts.

 

So I tried this puzzle:

 

puzzle = "SeND + MoRe = oNeY"

 

I guessed (wrongly) that by removing the offending M in MONEY, it would find 
only the other 24 solutions with the M in MORE being 0.

 

Not quite. That got 108 solutions! M was just about anything:

 

[d['M'] for d in solution108 ]

   

['6', '2', '5', '3', '6', '2', '5', '3', '7', '1', '6', '2', '7', '6', '2', 
'1', '5', '3', '7', '1', '5', '2', '5', '2', '7', '0', '7', '0', '4', '3', '7', 
'0', '8', '0', '4', '3', '8', '0', '8', '0', '6', '2', '5', '1', '6', '0', '5', 
'1', '6', '0', '5', '1', '7', '0', '4', '3', '7', '0', '7', '6', '1', '0', '7', 
'0', '4', '1', '5', '0', '6', '4', '2', '0', '6', '0', '6', '0', '3', '1', '5', 
'0', '5', '0', '3', '2', '2', '1', '2', '1', '2', '1', '3', '0', '2', '1', '3', 
'0', '3', '1', '2', '0', '2', '0', '3', '0', '3', '0', '2', '1']

 

My main point though is that a leading zero can appear including in bank 
account numbers, social security numbers and so on. But I accept that 
historically python is as it is. As I mentioned, some functions like int() can 
deal with them.

 

I attach my code in case anyone is interested in seeing the whole output or 
trying it on other puzzles. The code uses no exec() or eval() and should be 
safe 😊

 

CODE

 

# Module created to solve a specific kind of math word problem.

 

# FIND all solutions to a puzzle by systematically

# replacing LETTERS with NUMERALS till an equation is True

 

# Accepts string like "SEND + MORE = MONEY"

 

# Measure time elapsed, optional:

def math_word_puzzle_solver(puzzle):

"""USAGE: math_word_puzzle_solver(puzzle)"""

"""Solve a puzzle by brute force"""

"""of the form SEND + MORE = MONEY"""

"""with arbitrary sums on either side of"""

"""the equation."""

  

# NOTE: comments illustrate what happens to the test case only.



# Assuming the user typed in garbage, will restrict characters and 
normalize.

# Remove whitespace and most other things except +/=, make uppercase, etc.

 

puzzle = puzzle.upper()

retain = set('ABCDEFGHIJKLMNOPQRSTUVWXYZ=+')

puzzle = ''.join(filter(retain.__contains__, puzzle))

 

# puzzle := 'SEND+MORE=money'

 

# Split into left/right on the equals sign:

 

left_text, right_text = puzzle.split('=')

 

# left_text  := 'SEND+MORE'

# right_text :=  'MONEY' (or 'ONEY')

 

# Split each side into a list on "+" and in the test case

# only the left side has more than one:

 

left_list = left_text.split('+')

right_list = right_text.split('+')

 

# At this point we have:

# left_list: ['SEND', 'MORE']

# right_list: ['MONEY']

 

# Combine everything in both lists to make a set with unique letters.

 

letter_set = { letter

   for word in (left_list + right_list)

   for letter in word }

 

# Letter_set := {'M', 'O', 'R', 'Y', 'N', 'S', 'E', 'D'}

 

letter_count = len(letter_set)

 

# letter_count := 8

 

# Make an iterator to deliver one combination at a time 

# of the n-tuple of n digits at a time from 0-9 with no replacement

# and luckily that problem is solved by using the itertools module:

 

import itertools

 

# We want all permutations taken letter_count at a time

# so the iterator will return an 8-tuple in this example looking like:

#('0'

zeroed out

2018-12-11 Thread Avi Gross
Joe,

All numbers start with zero, and even an infinite number of them! LOL!

All kidding aside, I note that some data that is stored in a fixed width has 
zeroes padding it all the way to the right. If you store the number 3 in binary 
as a byte, it tends to look like 0011. Depending on how integers are 
stored, something similar can happen for longer stretches. But with decimals, 
we tend to not bother showing the empty areas that represent 0 times ever 
higher powers of 10.

But on the right, zeroes are required as otherwise you have no idea what the 
other numerals mean. 5900 is not 59.  Yes, you can write 59e2 or 5.9e3. Yet on 
the other side of the decimal point, it is reversed. You need 0's on the left 
but on the right only if you want to show significance.

But there are limits. Most programs do not support indefinite precision 
arithmetic. Too many digits including zeroies tend to be ignored.

Python integers though, see boundless:

>>> 2**80
1208925819614629174706176
>>> _**10
666801443287985427407985179072125779714475832231590816039625781176403723781763207152143220087155429074292991059343324044501654119365080363356052330830046095157579514014558463078285911814024728965016135886601981690748037476461291163877376
>>> _**10
1737662031938094565999824459494356270619397861001172505471732865032623760224580084650943336301208543380031943621630075979872254724835986408433356854417101939662741313385571925863990067892927145547675001947961279645969066059766058736658595806001619985565113685309604009071992534506041686227703502285271246267285386268054188334701076510916419199007254159946899201122191709070235613544840470257137346516087775445798461110010594821321809566894441083157854016421880441787886298535922284673317305198107635595779448820162864939086315031011211661095716822957694703795145311052399652092453140826655185793355112915252303733164866977865323352062741492408134892018287738543530418555987093906754309603810722704323839135427021302024301866373218623310688617767802110828569845060500248953943201394358684846438433680024960899560464199640198775868455302077489943945015055881469790826298713660881217637905553645132439842440041476360402191364434103777980116087227171313236217001593357864456019476016940251078882930170581785626471754610263843434388748614065167671583732790323210962621265516202550518578946320794439190575688682966752055301472437224530087878609170056344407910709900900338023035646198926037727398602328144407608278340682447170349984464291558779014638475805166354777533602182917103341104379697704219051965786176280422614748075085278062866268677842432851421790544407006581148631979148571299417963950579210719961422405768071335213324842709316205032078384168750091017964584060285240107161561019930505687950233196051962261970932008838279760834318101044311710769457048672103958655016388894770892065267451228938951370237422841366052736174160431593023473217066764172949768821843606479073866252864377064398085101223216558344281956767163876579889759124956035672317578122141070933058555310274598884089982879647974020264495921703064439532898207943134374576254840272047075633856749514044298135927611328433323640657533550512376900773273703275329924651465759145114579174356770593439987135755889403613364529029604049868233807295134382284730745937309910703657676103447124097631074153287120040247837143656624045055614076111832245239612708339272798262887437416818440064925049838443370805645609424314780108030016683461562597569371539974003402697903023830108053034645133078208043917492087248958344081026378788915528519967248989338592027124423914083391771884524464968645052058218151010508471258285907685355807229880747677634789376


-Original Message-
From: Python-list  On 
Behalf Of Joe Pfeiffer
Sent: Wednesday, December 12, 2018 12:04 AM
To: [email protected]
Subject: Re: 03 digression by brute force

"Avi Gross"  writes:

> SYNOPSIS: One way to solve math puzzle by brute force. (message sent 
> earlier disappeared)
>
>  
>
> Quick note. Jack started by asking why python does not like decimal 
> numbers with leading zeroes. When asked to explain, he said he was 
> trying to solve word problems using python. Someone mentioned problems 
> like solving SEND + MORE = MONEY and I decided to quickly write a 
> function that would solve anything of that sort that only has addition 
> on either side of the equals.
>
>  
>
> What amused me was that I had 25 solutions to the above when I was 
> told there would be one. Closer examination showed that 24 of those 
> had the ‘M’ in MONEY set to zero which the logicians claimed was not a 
> sensible solution.

What amuses me is the solution to the problem that started the whole thread had 
at least one number with a leading 0.
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: Smarter algo, was Re: 03 digression by brute force

2018-12-14 Thread Avi Gross
REAL SUBJECT: Analysis of alternate algorithms.

Peter & Jach and anyone interested,

As Peter said in his altered subject line, Jack changed directions from 
tweaking an algorithm to trying something quite different.

Reminder of the problem. 

Horizontal View:
SEND + MORE = MONEY

Vertical View:
  SEND
+MORE
...
MONEY

Hard to be precise as I am sticking to plain text in my message. The three 
words above are meant to be right adjusted.

When solving it horizontally, Jach and I used variants of a brute force 
approach. Substitute all possible combinations. He did it in-line and used 
eval. I did it by making lists of items on both sides and summing the int() of 
each component and comparing. We tried both our algorithms and his was slower 
and he profiled that the cause was that eval() was much more expensive as were 
his use of regular expression functions. For comparison, mine used int() and 
string manipulation functions and sets and dictionaries.

But the real puzzle is meant to be solved in a more vertical way by humans 
using logic. I won't do that here but note we have 4 equations going down but 8 
unknowns. And the equations are not unique.

The rightmost column (I will call it the first as our arithmetic proceeds from 
right to left) is meant to represent ONES and provides the equation:

(D+E== Y) or (D+E == Y + 10)

Worse, for the next column, you either get a "1" carried from the previous 
addition or not and either pass a "1" along to the next column or not. 4 
Possibilities.

(N+R==E) or (N+R+1==E) or (N+R==E+10) or (N+R+1==E+10)

Getting a headache yet?

For a human, they need a way to come up with additional info in terms of 
constraints.

There is a guiding inequality that looks like this:

S is not the same as any of the others. Anytime you solve for another, the list 
of possible values for S shrinks.
Ditto for each other variable.
Or, since anything plus 0 is itself, then D and E adding up to Y (with no 
possible carry) cannot be 0.

But getting a computer to do this might be a bit harder than blunt-force 
searches. So let's see why Jach's new algorithm was faster.

The code I am analyzing can be viewed in the archives and will not be entered 
again:

https://mail.python.org/pipermail/python-list/2018-December/738454.html

So what did Jach try in his newer version? It is what I call a vertical 
approach but one a computer can do easier than a human can or would. I see it 
is a very specific algorithm that hard codes in these variables as global 
entities that are altered by a set of nested functions. S, E, N, D, M, O, R, Y. 
There are approaches that might be better such as passing a dictionary 
partially filled out from one function to the next as the only one that prints 
the solution is the final function call.

So his is not a general solution.

What interests me as a probable reason this is faster is the number of 
situations it tries. The earlier versions asked itertools.permutations() to 
provide all unique combinations of ten tokens in eight positions. So there were 
10 choices for the first and 9 for the second and so on adding up to 10!/2! or 
1,814,400  different combinations tried. That approaches 2 million.

Jack broke the problem down into evaluating the units column with a loop like 
this:

itertools.permutations(range(10), 3)

That is 720 possibilities. He then doubled that to 1,440 to consider a carry. 
Only if the selected values for the three variables in contention (plus a 
carry) does he go on to call to evaluate the tens column.

It then shrinks a bit more as he no longer gets the permutations of all 10 
digits. He subtracts the three values that might work for the units, so he is 
asking for permutations of 7 digits, two at a time. That is 42, doubled again 
to 84 for carry purposes. And this function is not called 1,440 times, but 
quite a bit fewer. 

So, similarly, of those 84 loops for tens, he only sometimes calls to evaluate 
hundreds. As mentioned, the set of 10 digits shrinks some more and this 
continues upward to functions that evaluate hundreds and thousands  and finally 
the one evaluating ten thousands pretty much prints out an answer it finds. 

So overall iterations can be shown to drop. We could add code to measure how 
many times each function is called and come up with an exact value for this 
built-in problem. I did and the functions were called this many times:

>>> counting
{'unit': 1, 'ten': 72, 'hundred': 290, 'thou': 183, '10thou': 196}
>>> sum(counting.values())
742

But I also see the permutation function was called 542 times. Most of those 
runs though were fairly trivial as the combined number of items issued back 
were only 7,390 as compared to nearly two million in the earlier version. 
Overall, this is much faster.

Range() is probably a highly efficient built-in written in C, but it can 
totally be eliminated in this code as it is a constant. You can write 
{1,2,2,3,4,5,6,7,8,9} or [0,1] instead of calculating ranges.

Natu

RE: clusters of numbers

2018-12-15 Thread Avi Gross



-Original Message-
From: Avi Gross  
Sent: Saturday, December 15, 2018 11:27 PM
To: 'Marc Lucke' 
Subject: RE: clusters of numbers

Marc,

There are k-means implementations in python, R and other places. Most uses 
would have two or more dimensions with a goal of specifying how many clusters 
to look for and then it iterates starting with random existing points to 
cluster things near those points and then near the centers of those clusters 
until things stabilize.

Your data is 1-D. Something simpler like a bar chart makes sense. But that may 
not show underlying patterns.

I am more familiar with doing graphics in R but you can see a tabular view of 
your data:

data
  1   2   3   5   6   7   8  10  11  12  14  15  16  17  19  20  21  23  24  25 
 26  29  35  43 
124 116  97  95  89  74  57  73  48  49  38  35  20  33  21  19  14   5   4   4 
  3   1   1   1

There are clear gaps and a bar chart (which I cannot attach but could send in 
private email) does show clusters visibly.

But those may largely be an artifact of the missing info.

If you tell us more, we might be able to provide a better statistical answer. I 
assume you know how to get means and so on.

   varsn mean   sd median trimmed  mad min max range skew kurtosis   se
X11 1021 7.82 6.01  67.12 5.93   1  4342 1.04 1.23 0.19

Yes, the above is hard to read as I cannot use tables or a constant width font 
in this forum.

I ran a kmeans asking for 3 clusters:

1 16.512097
2  1.919881
3  7.433486

The three clusters had these scores in them:

Cluster 1: 5  6  7  8 10 11
Cluster 2:  1 2 3
Cluster 3: 12 14 15 16 17 19 20 21 23 24 25 26 29 35 43

If I run it asking for say 5 clusters:

Centers:

1  6.295238
2 11.432692
3  1.48
4  3.00
5 18.478261

And here are your five clusters:

5 6 7 8
10 11 12 14
1 2
3
15 16 17 19 20 21 23 24 25 26 29 35 43

If you ran this for various numbers, you might see one that makes more sense to 
you.  Or, maybe not.

We culd tell you what functions to use but if you search using keywords like 
python (or another language) followed by k-means or kmeans you can fid out what 
to install and use. In python, you would need Numpy and probably SciPy as well 
as the sklearn modules with the Kmeans function in sklearn.clusters. Note you 
can fine tune the algorithm multiple ways or run it several times as the 
results can depend on the initial guesses. And you may want to be able to make 
graphics showing the clusters, albeit it is 1-D.

Good luck.


-Original Message-
From: Python-list  On 
Behalf Of Marc Lucke
Sent: Saturday, December 15, 2018 7:55 PM
To: [email protected]
Subject: clusters of numbers

hey guys,

I have a hobby project that sorts my email automatically for me & I want to 
improve it.  There's data science and statistical info that I'm missing, & I 
always enjoy reading about the pythonic way to do things too.

I have a list of percentage scores:

(1,11,1,7,5,7,2,2,2,10,10,1,2,2,1,7,2,1,7,5,3,8,2,6,3,2,7,2,12,3,1,2,19,3,5,1,1,7,8,8,1,5,6,7,3,14,6,1,6,7,6,15,6,3,7,2,6,23,2,7,1,21,21,8,8,3,2,20,1,3,12,3,1,2,10,16,16,15,6,5,3,2,2,11,1,14,6,3,7,1,5,3,3,14,3,7,3,5,8,3,6,17,1,1,7,3,1,2,6,1,7,7,12,6,6,2,1,6,3,6,2,1,5,1,8,10,2,6,1,7,3,5,7,7,5,7,2,5,1,19,19,1,12,5,10,2,19,1,3,19,6,1,5,11,2,1,2,5,2,5,8,2,2,2,5,3,1,21,2,3,7,10,1,8,1,3,17,17,1,5,3,10,14,1,2,14,14,1,15,6,3,2,17,17,1,1,1,2,2,3,3,2,2,7,7,2,1,2,8,2,20,3,2,3,12,7,6,5,12,2,3,11,3,1,1,8,16,10,1,6,6,6,11,1,6,5,2,5,11,1,2,10,6,14,6,3,3,5,2,6,17,15,1,2,2,17,5,3,3,5,8,1,6,3,14,3,2,1,7,2,8,11,5,14,3,19,1,3,7,3,3,8,8,6,1,3,1,14,14,10,3,2,1,12,2,3,1,2,2,6,6,7,10,10,12,24,1,21,21,5,11,12,12,2,1,19,8,6,2,1,1,19,10,6,2,15,15,7,10,14,12,14,5,11,7,12,2,1,14,10,7,10,3,17,25,10,5,5,3,12,5,2,14,5,8,1,11,5,29,2,7,20,12,14,1,10,6,17,16,6,7,11,12,3,1,23,11,10,11,5,10,6,2,17,15,20,5,10,1,17,3,7,15,5,11,6,19,14,15,7,1,2,17,8,15,10,26,6,1,2,10,6,14,12,6,1,16,6,12,10,10,14,1,6,1,6,6,12,6,6,1,2,5,10,8
 
,10,1,6,8,17,11,6,3,6,5,1,2,1,2,6,6,12,14,7,1,7,1,8,2,3,14,11,6,3,11,3,1,6,17,12,8,2,10,3,12,12,2,7,5,5,17,2,5,10,12,21,15,6,10,10,7,15,11,2,7,10,3,1,2,7,10,15,1,1,6,5,5,3,17,19,7,1,15,2,8,7,1,6,2,1,15,19,7,15,1,8,3,3,20,8,1,11,7,8,7,1,12,11,1,10,17,2,23,3,7,20,20,3,11,5,1,1,8,1,6,2,11,1,5,1,10,7,20,17,8,1,2,10,6,2,1,23,11,11,7,2,21,5,5,8,1,1,10,12,15,2,1,10,5,2,2,5,1,2,11,10,1,8,10,12,2,12,2,8,6,19,15,8,2,16,7,5,14,2,1,3,3,10,16,20,5,8,14,8,3,14,2,1,5,16,16,2,10,8,17,17,10,10,11,3,5,1,17,17,3,17,5,6,7,7,12,19,15,20,11,10,2,6,6,5,5,1,16,16,8,7,2,1,3,5,20,20,6,7,5,23,14,3,10,2,2,7,10,10,3,5,5,8,14,11,14,14,11,19,5,5,2,12,25,5,2,11,8,10,5,11,10,12,10,2,15,15,15,5,10,1,12,14,8,5,6,2,26,15,21,15,12,2,8,11,5,5,16,5,2,17,3,2,2,3,15,3,8,10,7,10,3,1,14,14,8,8,8,19,10,12,3,8,2,20,16,10,6,15,6,1,12,12,15,15,8,11,17,7,7,7,3,10,1,5,19,11,7,12,8,12,7,5,10,1,11,1,6,21,1,1,10,3,8,5,6,5,20,25,17,5,2,16,14,11,1,17,10,14,5,16,5,2,7,3,8,17,7,19,12,6,5,1,3,12,43,11,8,11,5,19

RE: Smarter algo, was Re: 03 digression by brute force

2018-12-16 Thread Avi Gross
I appreciate the information by " BlindAnagram " 
below. I myself claim to be from erehwon at times.

But to be clear, there are issues raised here where someone wants an easy 
solution for the real world like "I have to build a webserver that searches a 
database" and they would prefer an answer telling them of a set of modules they 
can import that can do 90% of the work once you fill in some things on your own.

I am not clear on why Jach is working on this. Personally, I just like solving 
puzzles and consider it fun (in moderation) to think about the ideas behind a 
solution, alternates, ways to improve, and so on.

So  I wanted to balance the wasteful brute force aspects of a solution with 
ways to cut down the expense per iteration. In particular, I chose not to use 
the regular expression routines or eval. The first reference you supplied is a 
nice solution but does use those. It needs minor changes as it is written in an 
enhanced python 2.6 and I choose not to look back 😉

And best, it offers an oodle of similar puzzles. The weirdest perhaps was this:

('AN + ACCELERATING + INFERENTIAL + ENGINEERING + TALE + ' +
'ELITE + GRANT + FEE + ET + CETERA == ARTIFICIAL + INTELLIGENCE')

I mention that for a reason. In a private exchange with Jach, I noted that a 
generalization of his method would need to allow for more possible carries than 
just 0 and 1 that rise with the number of items being added. In the above, 
there are 10 numbers being added on the left and two on the right. Granted the 
rules do not allow all the letters to be 9.  So the maximum addition is not 
usually 90 + carry. But it can be in the 40's or even higher depending on the 
specific digits involved. In the worst case, you might have 10 copies in a 
column of the same letter whose value might be 9. So the algorithm would need 
to plan on a larger set of carry choices just in case. At some point, it might 
be less efficient than the horizontal solutions such as the ones Jach and I 
made first or the one you shared below.

-Original Message-
From: Python-list  On 
Behalf Of BlindAnagram
Sent: Saturday, December 15, 2018 7:41 AM
To: [email protected]
Subject: Re: Smarter algo, was Re: 03 digression by brute force

<<>>

There are quite a few Python based solvers for alphametics around on the net, 
for example:

http://code.activestate.com/recipes/576615-alphametics-solver/

There is also a long discussion here on ways of doing this:

https://enigmaticcode.wordpress.com/2016/06/22/solving-alphametics-with-python/


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


Fastest first

2018-12-16 Thread Avi Gross
I have a serious question about what is already available out there in a
herpetologists dream  pythonland.

 

SHORT VERSION: a way to automatically run multiple algorithms in parallel
and kill the rest when one returns an answer.

 

I know I can write this by hand. But it looks like the kind of thing that
would come in handy.

 

MOTIVATION: I recently was discussing alternate GENERAL  ways to solve a
puzzle. Depending on the nature of the input, it seems likely that some
methods will run faster while for other scenarios another might win. It may
not be possible to determine easily which to use so I wonder why not use ALL
of them but stop when an answer arrives.

 

I know how to use all kinds of multitasking in python ranging from threads
running in the same process to multiple external processes that can
communicate with the parent or each other to processes running on different
machines over the internet. You can obviously start algorithm A then B and
as many more as you want in each case. When a (final) solution is reached,
you can send it back to the consolidator (such as a parent) and it can
presumably easily kill local threads by thread number or processes by
process ID. Remote executions might be handled by sending suicide messages
through sockets.

 

Since some algorithms may take orders of magnitude longer than others and
may not ever terminate, letting them continue might be wasteful. But even if
they all share the same CPU, the winner might be slowed down relative to
running alone but perhaps not by much. If they share the same process, the
slowdown for N running together might be I the neighborhood of taking N
times as long. It may be less or more.  If run as another independent
process on a machine which has many other processes running, it may degrade
performance by only a few percent. When running on other machines, no real
impact except the overhead of communications.

 

I am pretty sure there are already many variations out there. When google
searches what has to be a gigantic partially indexed mass of data, I think
it farms out bits of the work to multiple processes and probably processors
as no ONE of them can sift through much of that data in real time. Much of
the search may be done in computer memories. So a search may spawn a massive
attempt and results that come back are consolidated and displayed. Perhaps
after a second or two, no additional data is wanted. It will happily page
the first billion pages it found.

 

What would be nice is to load a module, give it a list of functions to call
and ask to be given an answer with a guarantee that no functions (or
processes)  are still in the running. In real life, this could be complex if
some of your functions invoked a similar method to farm out their work. You
would be killing trees.

 

An example is what happens if you ask for a translation from text written in
an unknown language (I mean Hungarian versus English versus French as an
example.) One solution is to try a list of translators in sequence and if
they return nonsense, try the next. But if you tried them in parallel and
one came back with a 98% probability that it recognized the language because
it found places with a “zs” combination and found characters like an o with
an umlaut and another o with single/double accents, and regognized a few
words like “születésnapot” you can pretty much rule out English and French.
You might have a similar approach with multiple variations on SPAM detectors
and call a halt when any one says it seems safe, or vice versa.

 

I would call this a KILL the stragglers survival of the fittest … strategy.

 

 

 

 

 

 

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


RE: Complex 'compare'

2018-12-18 Thread Avi Gross
Frank,

I am not commenting on your specific code, just asking a question.

If you have two tuples of the same size it does seem that python evaluates
them in the order you want just by doing something like this example I made
with a 2-tuple:

>>> (1, 2) > (2,1)
False
>>> (1, 2) > (1,1)
True
>>> (1, 1) > (1,1)
False

So if you take your database entries and re-order them so the keys you want
to sort by are in order from left to right, and you don't include any that
you don't want to sort by, the above technique may work well enough. Of
course, you may want to re-establish the order and contents afterward.

Of course if you have some None, that messes things up:

>>> (1, 1) > (1,None)
Traceback (most recent call last):
  File "", line 1, in 
(1, 1) > (1,None)
TypeError: '>' not supported between instances of 'int' and 'NoneType'

Unless, of course, they are both None.

>>> (1, None) > (1,None)
False

For python 2.x there was a cmp() function that might have met your needs. It
was removed in 3.x 

https://docs.python.org/3.0/whatsnew/3.0.html

" The cmp() function should be treated as gone, and the __cmp__() special
method is no longer supported. Use __lt__() for sorting, __eq__() with
__hash__(), and other rich comparisons as needed. (If you really need the
cmp() functionality, you could use the expression (a > b) - (a < b) as the
equivalent for cmp(a, b).)"

But as noted this does not work with your None. 

Final comment meant as humor. The following will not work even though it is
complex!

>>> (1 + 2j, 1 - 2j) > (1 + 3j,2 +4j)
Traceback (most recent call last):
  File "", line 1, in 
(1 + 2j, 1 - 2j) > (1 + 3j,2 +4j)
TypeError: '>' not supported between instances of 'complex' and 'complex'

And the reason is obvious as complex numbers have two dimensions so you
might need to compare something like their magnitude as in the length of a
vector ...

-Original Message-
From: Python-list  On
Behalf Of Frank Millman
Sent: Tuesday, December 18, 2018 5:50 AM
To: [email protected]
Subject: Complex 'compare'

Hi all

I want to compare two tuples. They each represent a row in a database, and
each element represents a column, so I will use that terminology.

I need to know if one row is greater than or less than the other. The sort
sequence can be complex - one or more columns, each of which can be sorted
ascending or descending.

Below is the function I have come up with. Can anyone see any problem with
it, or suggest a better way to do it?

I have taken one short cut. If all sort columns compare equal, it will
return True, which is wrong. In practice I ensure that one of the sort
columns will be the primary key, so the two rows should never be equal.

Thanks

Frank Millman

def compare(source_row, target_row, order, compare_type):

# source_row - the row I want to compare - some sort columns could
contain None
# target_row - the row I want to compare it with - no sort columns will
contain None
# order - a list of 2-part tuples defining the sort sequence - the
column number, and True if descending else False
# compare_type - either 'gt' or 'lt'

def compare_col(source_col, target_col, desc, compare_type):
if compare_type == 'gt':
if desc:
return True if source_col is None else source_col <
target_col
else:
return False if source_col is None else source_col >
target_col
elif compare_type == 'lt':
if desc:
return False if source_col is None else source_col >
target_col
else:
return True if source_col is None else source_col <
target_col

for pos, desc in order:
source_col = source_row[pos]
target_col = target_row[pos]
if compare_col(source_col, target_col, desc, compare_type):
return True
if source_col != target_col:
return False
# if we get here they are equal -
#compare the next column in the sort sequence
return True


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

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


RE: Complex 'compare'

2018-12-18 Thread Avi Gross
Frank,

Thanks for explaining.

It looks like you might want a shortcut compare done in an iterative or
recursive way that returns as soon as a discrepancy happens in the direction
you are comparing. If they are equal, you fall off the end.

A pythonic way is to use a loop as in:

>>> flag = True
>>> for alpha, beta in zip(first, second):
if (alpha < beta):
flag = False
break

The above is not the full code, just an example. In that loop you would need
to check for None or anything else. You need to determine if the match was
found or if it is less than versus greater than so you can continue your
binary search.

There are many tricks (ahem, techniques) people use. Some compare functions
that need to return a trinary answer will return 1 for Greater than, -1 for
Less than and 0 for equal. The function calling it can use techniques to
branch based on that such as using the return code to index a dictionary
containing keys -1,0, and 1 and a value that is the function to call to
fetch the next item above or below. 

Another method could be to have the function return a tuple of results. If
you return (found, comparison) as in:

(found, comparison) = function(...)

Then if the two are equal, return True in the first variable and if it is
False, examine the second variable to see if it is True or False.

And, of course, you can just do two comparisons in the first place. One for
"==" to find if you found it and the other for a test to see if you need to
search before or after the current cursor.

The quality test might work well in a try statement. Something like this
works fine:

>>> (1,1, None) == (1,1,None)
True

And it seems resistant to many errors because it is testing equality and
objects of different types are often by definition not equal.

>>> (1,1, None) == (1,1,None)
True
>>> (1,1, 2) == (1,1,None)
False
>>> (1,1, "two") == (1,1,2)
False
>>> (1,2) == (1,2,3)
False

If you want to make sure some other errors do not creep in, place it in a
try/catch statement as any error would also be a false.

Just some thoughts.




-Original Message-
From: Python-list  On
Behalf Of Frank Millman
Sent: Tuesday, December 18, 2018 6:39 AM
To: [email protected]
Subject: Re: Complex 'compare'

"Chris Angelico"  wrote in message
news:CAPTjJmpLuyFf04AT+34VraJ5itDvNySVJspEv=ddwdsmmsf...@mail.gmail.com...
>
> On Tue, Dec 18, 2018 at 9:52 PM Frank Millman  wrote:
> > I need to know if one row is greater than or less than the other. 
> > The sort sequence can be complex - one or more columns, each of 
> > which can be sorted ascending or descending.
> >
> > Below is the function I have come up with. Can anyone see any 
> > problem with it, or suggest a better way to do it?
>
> I'm not sure what the difference is between "compare_type" and "desc".
> You have four options here:
>
> * gt, desc
> True if source_col is None else source_col < target_col
> * gt, not desc
> False if source_col is None else source_col > target_col
> * lt, desc
> False if source_col is None else source_col > target_col
> * lt, not desc
> True if source_col is None else source_col < target_col
>
> The way this is currently coded, these come in two perfect pairs.
>

Yes, now that you point it out, there is definitely scope for shortening the
code, as that is effectively duplication.

My main concern was whether my algorithm had any flaws in it. I will keep
testing to look for corner cases.

I can assume total ordering. The background is that I want to find the
position of a row in a table according to some sequence. I can't read in the
entire table, as it could contain millions of rows. So I create a
server-side cursor in the desired sequence, and then perform a binary search
on it. So far it is working well.

Thanks

Frank


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

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


RE: random choice from dictionary

2018-12-23 Thread Avi Gross
There are quite a few places the new pythonic way of doing things requires
extra steps to get an iterator to expand into a list so Abdul-Rahmann
probably is right that there is no easy way to get a random key from a
standard dictionary. Other than the expected answers to make a customized
dictionary or function that provides the functionality at the expense for
potentially generating a huge list of keys in memory, I offer the following
as an alternative for large dictionaries and especially if they have large
keys.

The following is a function that iterates over the dictionary one key at a
time and when it reaches a random one, it returns the key without further
evaluation. On the average, it takes N/2 iterations for N keys. Asking to
make a list(data) may be efficient in terms of time and indexing is fast but
space is used maximally unless it just points to existing storage.

Here is one way to do the function. Some might use an emum instead.

def rand_key(data):
"""Get a random key from a dict without using all of memory."""
import random
randy = random.randrange(len(data))
this = 0
for key in data:
if (this == randy):
return(key)
this += 1

Here is a sample showing it running:

>>> import string
   
>>> data= { key : value for (key, value) in zip(string.ascii_uppercase,
string.ascii_lowercase) }
   
>>> data
   
{'A': 'a', 'B': 'b', 'C': 'c', 'D': 'd', 'E': 'e', 'F': 'f', 'G': 'g', 'H':
'h', 'I': 'i', 'J': 'j', 'K': 'k', 'L': 'l', 'M': 'm', 'N': 'n', 'O': 'o',
'P': 'p', 'Q': 'q', 'R': 'r', 'S': 's', 'T': 't', 'U': 'u', 'V': 'v', 'W':
'w', 'X': 'x', 'Y': 'y', 'Z': 'z'}
>>> rand_key(data)
   
'X'
>>> rand_key(data)
   
'P'
>>> rand_key(data)
   
'D'
>>> rand_key(data)
   
'G'
>>> rand_key(data)
   
'H'
>>> data[rand_key(data)]
   
'x'
>>> data[rand_key(data)]
   
'w'
>>> data[rand_key(data)]
   
'n'
>>> data[rand_key(data)]
   
'h'

Of course it depends on what you want to do. If getting random keys
repeatedly, it would be best to do things like make another dictionary with
the new key being integers from 0 to the length and the new values to be the
old keys. You can then look up a random index to get a random key.

>>> dataindex = { index: key for (index, key) in enumerate(data)}
   
>>> dataindex
   
{0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E', 5: 'F', 6: 'G', 7: 'H', 8: 'I', 9:
'J', 10: 'K', 11: 'L', 12: 'M', 13: 'N', 14: 'O', 15: 'P', 16: 'Q', 17: 'R',
18: 'S', 19: 'T', 20: 'U', 21: 'V', 22: 'W', 23: 'X', 24: 'Y', 25: 'Z'}
>>> dataindex[11]
   
'L'
>>> import random
   
>>> dataindex[random.randrange(len(dataindex))]
   
'Y'
>>> dataindex[random.randrange(len(dataindex))]
   
'O'

Again, depending on your needs, some solutions may be worth extra code, some
may not.


-Original Message-
From: Python-list  On
Behalf Of Abdur-Rahmaan Janhangeer
Sent: Sunday, December 23, 2018 1:17 AM
To: Python 
Subject: random choice from dictionary

greetings,

just a check, is this:

random.choice(list(data.keys()))

the only way to get a random key from a dictionary? if not any plan to a
more convenient naming?

yours,

--
Abdur-Rahmaan Janhangeer
http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius


Garanti
sans virus. www.avast.com

<#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: random choice from dictionary

2018-12-23 Thread Avi Gross
I did say some would use enumerate but I was rushing to go to my nephews 
wedding and my enum became emum which is meaningless 😊

If the goal is to make a relatively efficient algorithm and the index made by 
enumerate is not needed, then I judged that the overhead of enumerate(data) 
returning two values to be unpacked each time through the loop might be more 
than having a single counter. Of course enumerate likely is considered more 
pythonic 😊

Similarly, the suggestion to use islice (although the name is also 
unfortunately reminiscent of is lice) may be a good one. But it basically does 
what my function did, perhaps as fast and perhaps not. My impression is it 
iterates using next() a number of times then stops. It is so simple, there 
might be no need for my function. The request was to find an nth item and you 
can feed (the random) n directly into islice.

Just for amusement, I already get a random word a day in my email from two 
dictionary sources in English as well as quite a few in other languages. I not 
only get the word as a key, but also a translation and even an example sentence 
with translation.

But I doubt the words are chosen randomly and they are not likely to be from a 
python dictionary.😊

-Original Message-
From: Python-list  On 
Behalf Of MRAB
Sent: Sunday, December 23, 2018 4:21 PM
To: [email protected]
Subject: Re: random choice from dictionary

On 2018-12-23 19:52, Avi Gross wrote:
> There are quite a few places the new pythonic way of doing things 
> requires extra steps to get an iterator to expand into a list so 
> Abdul-Rahmann probably is right that there is no easy way to get a 
> random key from a standard dictionary. Other than the expected answers 
> to make a customized dictionary or function that provides the 
> functionality at the expense for potentially generating a huge list of 
> keys in memory, I offer the following as an alternative for large 
> dictionaries and especially if they have large keys.
> 
> The following is a function that iterates over the dictionary one key 
> at a time and when it reaches a random one, it returns the key without 
> further evaluation. On the average, it takes N/2 iterations for N 
> keys. Asking to make a list(data) may be efficient in terms of time 
> and indexing is fast but space is used maximally unless it just points to 
> existing storage.
> 
> Here is one way to do the function. Some might use an emum instead.
> 
> def rand_key(data):
>  """Get a random key from a dict without using all of memory."""
>  import random
>  randy = random.randrange(len(data))
>  this = 0
>  for key in data:
>  if (this == randy):
>  return(key)
>  this += 1
> 
[snip]
You might as well use 'enumerate' there:

def rand_key(data):
 """Get a random key from a dict without using all of memory."""
 import random
 randy = random.randrange(len(data))
 for this, key in enumerate(data):
 if this == randy:
 return key

Or you could use 'islice':

def rand_key(data):
 """Get a random key from a dict without using all of memory."""
 import itertools
 import random
 randy = random.randrange(len(data))
 return list(itertools.islice(data, randy, randy + 1))[0]
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: Fastest first

2018-12-24 Thread Avi Gross
or example, not exact details or designs.

I simply think such a utility may already have been built out there, as well as 
many variations. Just as an example, someone recently mentioned to me that 
there is a module with a function called islice() that might do exactly what 
was wanted. So, of course, I read about everything else in that module: 
https://docs.python.org/2/library/itertools.html

And I found quite a variety of other functions to create combinations of 
iterables and ways to combine them to make even more. Others have already 
considered what might be of use and many are being shared. And many are well 
debugged so unless I am trying to deliberately figure out how to do something 
by myself (which I admit I often do) this is a good way to go.

So although I am happy to discuss ways to do this kind of task, I am really 
asking if this is a common enough way of looking at solving problems that many 
solutions have already appeared including some that are out there and ready.

Clearly though, some such solutions would be quite specific to particular 
methods of dividing up tasks such as using processes versus threads or even 
distributing computation across the cloud. Some might be even more dynamic and 
allow some of the processes running to throw additional ones into the mix as 
variants of their methods.

I will stop here even if it means I have to kill myself. 😉

Avi
-Original Message-
From: Python-list  On 
Behalf Of Stefan Behnel
Sent: Monday, December 24, 2018 9:46 AM
To: [email protected]
Subject: Re: Fastest first

Avi Gross schrieb am 17.12.18 um 01:00:
> SHORT VERSION: a way to automatically run multiple algorithms in 
> parallel and kill the rest when one returns an answer.

One (somewhat seasonal) comment on this: it doesn't always have to be about 
killing (processes or threads). You might also consider a cooperative 
implementation, where each of the algorithms is allowed to advance by one 
"step" in each "round", and is simply discarded when a solution is found 
elsewhere, or when it becomes unlikely that this specific algorithm will 
contribute a future solution. This could be implemented via a sequence of 
generators or coroutines in Python. Such an approach is often used in 
simulations (e.g. SimPy and other "discrete event" simulators), where exact 
control over the concurrency pattern is desirable.

Stefan

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

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


RE: Why doesn't a dictionary work in classes?

2018-12-25 Thread Avi Gross
אורי,

Your indentation did not make it through. So the first thing to guess is what 
you are asking python to do.

It is often good to not just supply the code but point out what you are trying 
to do as well as explain the small difference you made in your code that made 
it work so we can zoom in on that.

It looks like you want to create a class but then you do nothing that follows 
up. If we indent further lines, it looks like you are creating constant values. 
The class is not initialized, there are no methods, etc.

Your class definition though brings in parent classes that presumably supply 
what you need so you are merely extending it by supplying a form of sorts, 
right?

" class User(ValidateUserPasswordMixin, PermissionsMixin, Entity, 
AbstractBaseUser):"

I have no idea where those parent classes are defined and since they are the 
same in both the failing case and the working case, that should not matter. But 
if I have no access to that, I cannot easily replicate your code. I can try 
running some lines at the global level and I note some errors there:

What are the naked underscores doing in this:

GENDER_CHOICES = (
(GENDER_FEMALE, _("Female")),
(GENDER_MALE, _("Male")),
(GENDER_OTHER, _("Other")),
)

You seem to be making an odd tuple of tuples. Is the first tuple supposed to 
join the numerical representation of 1, with the character representation of 
"Female" to make (1,"Female") and the other two tuples something similar? You 
already declared similar (but all lowercase) strings above. So what is this odd 
notation for:
_("Female")

If that section fails, then GENDER_CHOICES does not get created. Did you not 
get an error message for that?

But moving on to  your error message about not finding the dictionary in what 
shows up here as one merged line:

" GENDER_VALID_VALUES = [choice[0] for choice in GENDER_CHOICES] GENDERS_DICT = 
{GENDER_FEMALE: GENDER_FEMALE_STRING, GENDER_MALE:
GENDER_MALE_STRING, GENDER_OTHER: GENDER_OTHER_STRING} ALL_GENDERS = 
[GENDERS_DICT[gender] for gender in GENDER_VALID_VALUES]"

I see it as being better formatted as something like this:

GENDER_VALID_VALUES = [choice[0] for choice in GENDER_CHOICES]
GENDERS_DICT = {GENDER_FEMALE: GENDER_FEMALE_STRING,
GENDER_MALE: GENDER_MALE_STRING,
GENDER_OTHER: GENDER_OTHER_STRING}
ALL_GENDERS = [GENDERS_DICT[gender] for gender in GENDER_VALID_VALUES]

The first line wants to make a list and it looks like you want a list of the 
first character in Male, Female and Other.

I assume you want to create a dict on the second line(s) looking like this: {1: 
'female', 2: 'male', 3: 'other'}

I will not debate with you the choice of 3=2+1 as there are multiple variations 
on what you call other out there.

The last line, is trying to make a list of values from the dictionary just 
created. The error message you show suggests the dictionary creation failed on 
the lines above it.

So what is different in the version that worked?

GENDER_VALID_VALUES = [choice[0] for choice in GENDER_CHOICES] 
GENDERS_DICT = {GENDER_FEMALE: GENDER_FEMALE_STRING, 
GENDER_MALE: GENDER_MALE_STRING, 
GENDER_OTHER: GENDER_OTHER_STRING}

User.ALL_GENDERS = [User.GENDERS_DICT[gender] for gender in 
User.GENDER_VALID_VALUES]

What you might have pointed out is that the last line was changed. It gives an 
expanded name to the variables you used. It is not clear due to the indentation 
problem if you ran this inside the class definition or outside.

Your variable names are all upper case and do not seem likely to cause 
confusion with the other parent classes but what about AbstractBaseUser? Is it 
possible that you may be trying to access a name defined in both contexts and 
need to carefully spell out which one you want here?

Sorry for the length of my message. I needed to work my way through piece by 
piece. As always, I might have done it differently so half the task is trying 
to think more like the writer.

אבי


-Original Message-
From: Python-list  On 
Behalf Of 
Sent: Tuesday, December 25, 2018 7:46 AM
To: [email protected]
Subject: Why doesn't a dictionary work in classes?

Why does this not work:

class User(ValidateUserPasswordMixin, PermissionsMixin, Entity,
AbstractBaseUser):
GENDER_UNKNOWN = 0
GENDER_FEMALE = 1
GENDER_MALE = 2
GENDER_OTHER = 3
GENDER_MAX_VALUE_PLUS_ONE = 4

GENDER_FEMALE_STRING = 'female'
GENDER_MALE_STRING = 'male'
GENDER_OTHER_STRING = 'other'

GENDER_CHOICES = (
(GENDER_FEMALE, _("Female")),
(GENDER_MALE, _("Male")),
(GENDER_OTHER, _("Other")),
)
GENDER_VALID_VALUES = [choice[0] for choice in GENDER_CHOICES] GENDERS_DICT = 
{GENDER_FEMALE: GENDER_FEMALE_STRING, GENDER_MALE:
GENDER_MALE_STRING, GENDER_OTHER: GENDER_OTHER_STRING} ALL_GENDERS = 
[GENDERS_DICT[gender] for gender in GENDER_VALID_VALUES]

(it throws an exception: `NameError: name 'GENDERS_DICT' is not defined`)


dangerous class neighborhood

2018-12-27 Thread Avi Gross
 and do the calculation and yet return the
value of C needed. Less efficient but .

 

I apologize for the length but assure you I normally would say much more.

 

Avi

 

 

 

 

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


RE: dangerous class neighborhood

2018-12-27 Thread Avi Gross
Sometimes when I post something I get back comments and evaluate them and
learn quite a bit. I then reply and debate every little point and it can
continue for a few rounds.

I don't seem to be in that mood today so let me simply restate my entire
post in a few sentences with no examples, no lectures, no advice on what
anyone else can do and very little for anyone to bother replying to. Here
goes:

Sometimes when I run up against a wall and find that a solution to a problem
does not work because things may not work as I expected, I pause. I
reconsider what I actually need to get done. Then I look to see if I can
come up with other ways to do it that will work while still getting the
important parts done. Failing that, I ask if perhaps there is another tool,
such as another programming language that is a better fit for the task. And,
if the work needed seems excessive, I ask if perhaps the problem does not
really need to be solved by me and I move on.

-Original Message-
From: Python-list  On
Behalf Of Chris Angelico
Sent: Thursday, December 27, 2018 5:11 PM
To: Python 
Subject: Re: dangerous class neighborhood

On Fri, Dec 28, 2018 at 8:47 AM Avi Gross  wrote:
> Question 2: Do you want the variables available at the class level or 
> at the instance level?

For constants, definitely put them on the class. They'll be available on
instances as well ("for free", if you like). For mutables, obviously you
need to decide on a case-by-case basis.

> Question 3: Which python variations on syntactic sugar, such as list 
> comprehensions, get expanded invisibly in ways that make the problem 
> happen by asking for variables to be found when no longer in the 
> visible
range?

The oddities with comprehensions were tackled partly during the discussion
of PEP 572. If you want to know exactly why this isn't changing, go read a
few hundred emails on the subject. A lot of the main points are summarized
in the PEP itself:

https://www.python.org/dev/peps/pep-0572/

> There may be matters of efficiency some would consider but some of the 
> examples seen recently seemed almost silly and easy to compute. The 
> people asking about this issue wanted to define a bunch of CONSTANTS, 
> or things that might as well be constants, like this:
>
>
>
> def Foo():
>
> A = ("male", "female", "other")
>
> B = [ kind[0] for kind in A ]# First letters
> only
>
> # And so on making more constants like a dictionary 
> mapping each string to a number or vice versa.
>
>
>
> All the above can be evaluated at the time the class is defined but 
> unintuitive scope rules make some operations fail as variables defined 
> in the scope become unavailable to other things that SEEM to be 
> embedded in the same scope.

If you write simple and Pythonic code, these will almost always work
perfectly. The recent thread citing an oddity worked just fine until it was
written to iterate over range(len(x)) instead of iterating directly.

> If they are ONLY to be used within an instance of Foo or invoked from 
> within there, there may be a fairly simple suggestion. If you already 
> have a __init__ method, then instantiate the variables there carefully 
> using the self object to reference those needed.

But why? __init__ should initialize an instance, not class-level constants.
A Python class is not restricted to just methods, and there's no reason to
avoid class attributes.

> Create a function either outside the class or defined within. Have it 
> do any internal calculations you need in which all internal variables 
> can play nicely with each other. Then let it return all the variables 
> in a tuple like
> this:
>
> def make_sexual_constants():
>
> A = .
>
> B = .
>
> C = f(A,B)
>
> D = .
>
> def Foo():
>
> (A, B, C, D) = make_sexual_constants():

Lovely. Now you have to define your variables once inside the function, then
name them a second time in that function's return statement, and finally
name them all a *third* time in the class statement (at least, I presume
"def Foo():" is meant to be "class Foo:"). A mismatch will create bizarre
and hard-to-debug problems.
What do you actually gain? Can you show me real-world code that would truly
benefit from this?

> Can we agree that the class Foo now has those 4 variables defined and 
> available at either the class level or sub-class or instance levels?
> But the values are created, again, in a unified safe environment?

Unified? No more so than the class statement itself. Safe? Definitely not,
because of the mandatory duplication of names.

> As noted in section 3, it would be good to know what python features

RE: dangerous class neighborhood

2018-12-27 Thread Avi Gross
 neighborhood

On Fri, Dec 28, 2018 at 2:27 PM Avi Gross  wrote:
>
> Sometimes when I post something I get back comments and evaluate them 
> and learn quite a bit. I then reply and debate every little point and 
> it can continue for a few rounds.
>
> I don't seem to be in that mood today so let me simply restate my 
> entire post in a few sentences with no examples, no lectures, no 
> advice on what anyone else can do and very little for anyone to bother 
> replying to. Here
> goes:
>
> Sometimes when I run up against a wall and find that a solution to a 
> problem does not work because things may not work as I expected, I 
> pause. I reconsider what I actually need to get done. Then I look to 
> see if I can come up with other ways to do it that will work while 
> still getting the important parts done. Failing that, I ask if perhaps 
> there is another tool, such as another programming language that is a 
> better fit for the task. And, if the work needed seems excessive, I 
> ask if perhaps the problem does not really need to be solved by me and I
move on.

So your entire original post can be summed up as "I don't understand Python,
and I don't care"? Why did you post it then? I was under the impression that
you wanted to learn what was going on.

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

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


RE: dangerous class neighborhood

2018-12-27 Thread Avi Gross
Short answer to a short question.

 

What does a dot (dot dot) mean in pseudocode?

 

NOTHING and EVERYTHING.

 

Longer answer:

 

I think what you see may not be what I wrote. I used three dots in a row (an 
ellipsis) to mean that something is left out to be filled in with something 
appropriate.

 

A = …

B = …

 

That was meant to mean that it does not really matter exactly what code is 
used. Set A equal to SOMETHING and set B equal to something.

 

As it happens, there are computer languages where that is valid code. Python 
turns out to be one of them!

 

 

>>> A=...

>>> A

Ellipsis

 

In python you can often use “pass” in some contexts like:

 

>>> if 1: pass

>>> def name():

Pass

 

These don’t do anything except serve as a placeholder and should be replaced 
later. There are cases where you can write something like this:

 

>>> x = 5

>>> if x > 7:

pass

else:

print(x)

 



5

 

But although that works, you could simply use a NOT or invert the condition to 
say:

 

>>> if not (x > 7):

print(x)

 



5

>>> if (x <= 7):

print(x)

 



5

 

Well “…” can also be used in modern versions of python although it may not be 
novice-level material. It can serve as a placeholder in things like this:

 

>>> def name(x,y,z): pass

 

>>> name(1,2,3)

>>> name(1,3)

Traceback (most recent call last):

  File "", line 1, in 

name(1,3)

TypeError: name() missing 1 required positional argument: 'z'

>>> name(1,...,3)

 

You can see the third positional argument is still the third in this example:

 

>>> def name(x,y,z): print(x,z)

 

>>> name(1,...,3)

1 3

 

So what is the middle argument in this case?

 

>>> def name(x,y,z): print(x,y,z)

 

>>> name(1,...,3)

1 Ellipsis 3

>>> name(...,...,3)

Ellipsis Ellipsis 3

>>> name(...,...,...)

Ellipsis Ellipsis Ellipsis

 

I suspect that generally the intent is to eventually fill in the missing 
argument.

 

Here is a related anomaly. The single underscore has multiple uses but one is 
to say you are throwing away something.

 

>>> a, _, c = (1, "who cares", 3)

>>> a

1

>>> _

'who cares'

>>> c

3

 

But what I used the same variable name multiple times?

 

>>> _, _, c = (1, "who cares", 3)

>>> _

'who cares'

>>> c

3

 

To be fair, any variable used repeatedly in that context keeps only the 
rightmost assignment. But there is an idiom of using just an underscore to mean 
you don’t care about that and want something else whose name may be made 
meaningful.

 

>>> _, _, LastName = ("John", "J.", "Doe")

>>> LastName

'Doe'

 

So, my apologies. I won’t use … even in pseudocode.

 

 

From: Abdur-Rahmaan Janhangeer  
Sent: Friday, December 28, 2018 12:30 AM
To: Avi Gross 
Cc: Python 
Subject: Re: dangerous class neighborhood

 

btw what does

 

A = .

 

above means? the dot?

Abdur-Rahmaan Janhangeer
http://www.pythonmembers.club <http://www.pythonmembersclub>  | 
https://github.com/Abdur-rahmaanJ
Mauritius

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


RE: dangerous class neighborhood

2018-12-28 Thread Avi Gross
[REAL SUBJECT: an assortment of nothings]

 

Python tricks?

 

Speaking from a tutorial forum, tricks can catch people trying to learn.

 

I am not sure of the history of the ellipsis object. 

 

>>> dir(...)

['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', 
'__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', 
'__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', 
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', 
'__subclasshook__']

 

Would you believe it is syntactically valid to use 4 periods in a row by asking 
for the contents like this:

 

>>> __class__



 

My impression is that the main initial use for the ellipsis was as a 
placeholder in a numpy multidimensional array so you can specify which axis you 
want to get all of:

 

https://python-reference.readthedocs.io/en/latest/docs/brackets/ellipsis.html

 

I don’t want to start yet another discussion but there seem to be a range of 
ways to say you want something without quite saying what you want. We have 
mentioned the “pass” argument. We also have the naked colon as in:

 

new = old[ : ]

 

The above will make a shallow copy of a list. It is not really a new symbol but 
what happens when you take from:to and remove the from and the to and allow the 
defaults to take over. It gets murky as often underneath it all there are 
hidden objects like the slice:

 

>>> alpha = list(range(10))

>>> alpha

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

 

So you can explicitly index with a slice object or use the colon notation to 
get the same thing:

 

>>> alpha[1:5]

[1, 2, 3, 4]

>>> alpha[slice(1,5)]

[1, 2, 3, 4]

>>> alpha[1:10:2]

[1, 3, 5, 7, 9]

>>> alpha[slice(1,10,2)]

[1, 3, 5, 7, 9]

>>> alpha[5:]

[5, 6, 7, 8, 9]

>>> alpha[slice(5,)]

[0, 1, 2, 3, 4]

>>> alpha[slice(5,None)]

[5, 6, 7, 8, 9]

>>> alpha[:]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> alpha[slice(,)]

SyntaxError: invalid syntax

>>> alpha[slice(None)]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

 

Note the placeholder is now the item called “None”

 

The ellipsis can be used here but causes errors.

 

And there are more subtle placeholders with meanings like DOES not exist. Numpy 
has a “nan” and Pandas has NaN and a missing date is NaT and beneath it all 
there are names for a missing int versus float versus who knows what.

 

These can be subtle ideas for a newcomer, even for people who come from 
languages that don’t have the distinctions. For that matter, there are ways to 
say something is infinite which is not the same as saying the maximum value you 
can store in N bits.

 

But I express some caution on calling some of these things tricks. Yes, of 
course they can be tricky. What they often are may well be considered 
additional functionality by way of abstractions. Clearly a key word like “pass” 
may be easier to understand than some of the others.

 

 

From: Abdur-Rahmaan Janhangeer  
Sent: Friday, December 28, 2018 3:46 AM
To: Avi Gross 
Cc: Python 
Subject: Re: dangerous class neighborhood

 

thanks, the 3 dots are more explicit, thought was another py trick

 

yours,

Abdur-Rahmaan Janhangeer
http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ
Mauritius

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


RE: graded randomness

2018-12-28 Thread Avi Gross
Abdur-Rahman

I am sure various modules available have ready-made solutions and I see
others have replied to your question. The usual disclaimers apply. This is
an academic discussion and not a statement of the right or only way to do an
abstract task.

So just a thought. You seem interested in a GENERAL situation where you have
N situations with each having a specific probability and the probabilities
sum to 1.0. If that is right, you are creating a partition where you can
make a data structure listing N ordered items along with their individual
probability. Given such a list, you can create another item that is a
cumulative sum.

In your example, your individual probabilities for ['green', 'red', 'blue']
are [0.4, 0.4, 0.2] but the use of lists is just for illustration. You might
use a Numpy array as they have a cumulative sum function:

import numpy as np
np.cumsum([0.4, 0.4, 0.2])
Returns:
array([0.4, 0.8, 1. ])

or viewed vertically:

np.cumsum([0.4, 0.4, 0.2]).reshape(3,1)
array([[0.4],
   [0.8],
   [1. ]])

Again, we are talking about a GENERAL solution but using this example to
illustrate. To get a weighted probability now, you use the random module (or
anything else) to generate a random number between 0 and 1. You search in
the cumulative sum data structure to find the right range. A random value
less than 0.4 should direct you to using green. If above that but less than
0.8, use red. Else, use blue.

To do this properly, you can decide what data structures makes this easy to
do. Maintaining three independent lists or arrays may not be optimal. 

The main idea is to find a way to segment your choices. So consider a
different common example of rolling a pair of (six sided) standard dice. You
know there are 6**2 possible outcomes. There is only one way to get a sum of
2 by rolling a one and another one. So the probability is 1/36 or .0277...
and you can calculate the probabilities of all the other sums with a 7 being
the most common roll at .1667. In this example your choices are rolls of 2
through 12 or 11 choices. The same logic applies. Generate 11 data measures
and a cumulative sum. Just as illustration, I show code using a Pandas
DataFrame object.

import numpy as np
import pandas as pd
diceSumText = np.array(["two", "three", "four", "five", "six", "seven",
"eight", "nine", "ten", "eleven", "twelve"])
diceSumVal = np.array(range(2,13))
diceProbability = np.array([1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]) / 36
diceProbCumSum = np.cumsum(diceProbability)

Now combine those:

mydata = pd.DataFrame({"Text": diceSumText, "Value": diceSumVal, "Prob":
diceProbability, "Cum": diceProbCumSum})
print(mydata)

  Text  Value  Prob   Cum
0  two  2  0.027778  0.027778
1three  3  0.06  0.08
2 four  4  0.08  0.17
3 five  5  0.11  0.28
4  six  6  0.138889  0.416667
5seven  7  0.17  0.58
6eight  8  0.138889  0.72
7 nine  9  0.11  0.83
8  ten 10  0.08  0.916667
9   eleven 11  0.06  0.97
10  twelve 12  0.027778  1.00

Again, you can do something any number of ways. This is just one. And in
this format the indentation is not great. 

But it lets you write an algorithm that finds the highest 'index" that still
is below the random number chosen and then select either the text or value
that fits in that partition. Not to repeat, there are many other ways so
feel free to innovate. 


-Original Message-
From: Python-list  On
Behalf Of Abdur-Rahmaan Janhangeer
Sent: Friday, December 28, 2018 2:45 PM
To: Python 
Subject: Re: graded randomness

well i wanted that to improve the following code:

https://www.pythonmembers.club/2018/12/28/reviving-bertrand-russell-through-
python/

that one i used the random list technique

Abdur-Rahmaan Janhangeer
http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius

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

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


RE: the python name

2019-01-02 Thread Avi Gross
Challenge: Can we name any computer language whose name really would suggest it 
was a computer language?

Oh, if you say C is named as being the successor to some form of B, then R (as 
you mentioned) is the successor by some form of backwards reasoning to S as it 
started as not quite S or at least not as expensive. FWIW, T was already in use 
as a dialect of Scheme which was a dialect of LISP ...

And I was there when we were naming C++ as a slightly improved and incremented 
C. Yes, D was considered as well as odd names like Add-One-To-C. Oddly C# was 
not considered. 😊

So, Ada. First female programmer, at least on paper?

A Programming Language? APL.

The endless list goes on. I looked at one such list below and I thought I had 
learned quite a few but apparently a small fraction of what was.

https://en.wikipedia.org/wiki/List_of_programming_languages

I think the name is the least important aspect of a computer language.

-Original Message-
From: Python-list  On 
Behalf Of Dennis Lee Bieber
Sent: Wednesday, January 2, 2019 7:02 PM
To: [email protected]
Subject: Re: the python name

On Wed, 2 Jan 2019 19:41:36 +, "Schachner, Joseph"
 declaimed the following:


>The name "Python" may not make sense, but what sense does the name Java make, 
>or even C (unless you know that it was the successor to B), or Haskell or 
>Pascal or even BASIC?  Or Caml or Kotlin or Scratch?  Or Oberon or R? Or 
>Smalltalk, or SNOBOL?
>

Which was a derivative of BCPL (so one could claim a successor of C 
should be named P), ?, mathematician, beginners all-purpose symbolic 
instruction code. R? maybe a subtle implication to be better/in-front-of S.
SNOBOL is the ugly one, since the SN come from "string", and the BO from the 
middle of "symbolic".



-- 
Wulfraed Dennis Lee Bieber AF6VN
[email protected]://wlfraed.home.netcom.com/ 

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

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


RE: the python name

2019-01-03 Thread Avi Gross
[NOTE: Not a serious post, just a response to a complaint about python as a 
name and computer language names in general.]

On further thought, it seems that a name that reminds some people that it is a 
computer language would be in hexadecimal and start with 0X. But that restricts 
the remainder of the name to numerals plus {A,B,C,D,E,F} so something like 
0XFACE or 0XDEAF or 0XFADE so how about:

0XFACADE

Clearly the language is just a façade behind whose face are other 
representations we are normally deaf to heading down towards binary.

You can, of course, use the usual password tricks where zero can stand for oh, 
one for el and so on. That extends the words you can make. And of course some 
digits can expand with 2 becoming two or even to/too and 4 becoming fore.

PYTHON by this weird measure is horrible as every single letter is above F.  
AnAC0nDA is much better.

ADA works!

And the cure for JAVA might be DECAF in a CAFÉ.

Better suggestions about what a computer language name should look like are 
welcome. I am thinking a bit outside the box that a solution might be in a box. 
I am thinking of a binary matrix containing 0/1 in a 2d-pattern that spells out 
something  or perhaps has two sections side by side where the background 
letters on each side are all of the same digit while the foreground using the 
other digit spells out itself, or perhaps the opposite. This is an ASCII 
message environment so I won't show a sample. Not THAT would be a name, albeit 
a long one.

Back to seriousness. I do not understand any suggestions that the python 
language will go away any time soon. It will continue to evolve and sometimes 
that evolution may introduce incompatibilities so earlier versions may have to 
stop being supported. In many recent polls I keep seeing Python getting an 
increasing share of programs written for all kinds of purposes. Of course, 
there will be competition from other languages and new ones will arise.  I also 
see no reason any one person needs to steer the evolution indefinitely. 
Unrestricted growth is bad but as the world advances, some growth is a good 
idea. Bad analogy, but snakes do tend to shed their skin periodically as they 
grow.






-Original Message-
From: Larry Martell  
Sent: Wednesday, January 2, 2019 8:08 PM
To: Avi Gross 
Cc: Python 
Subject: Re: the python name

On Wed, Jan 2, 2019 at 8:04 PM Avi Gross  wrote:
>
> Challenge: Can we name any computer language whose name really would suggest 
> it was a computer language?

COBOL (Common Business-Oriented Language) FORTRAN (Formula Translation)
PL/1 (Programming Language 1)
ALGOL (Algorithmic Language)

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


RE: the python name

2019-01-03 Thread Avi Gross
Ok, this gives me a chance to say something actually python related.

Why did I mention Anaconda? Because python is also the name of a snake and
some people considered it appropriate to name their pet project that
includes python, as the name of another snake:

https://www.anaconda.com/

For people with my interests, this distribution of python is bundled with
other optional components with some focus, as I see Chris mentioned, on Data
Science users. I like having lots of tools available and included are many
modules I would otherwise download as much of my interest is in science and
statistical tools and especially on machine learning. Also thrown in is the
R environment which I have been using for years as these seem to be the two
major languages used by many, often both together. 

I am not here to evangelize but there are some other nifty tools and in
particular, the Jupiter notebook allows my style of interactive programming
that I was used to doing in ways through functionality in R Studio. Every
language generally needs a purpose and python was designed to do many things
well but initially was not equipped with data structures and methods that
were designed early into R. Over the years, I have seen much convergence as
python added the modules like numpy and pandas and sklearn and so on that
allow much simpler manipulation than creating lists of lists of lists to
hold data. R has added much, including way too many different ways to do
object-oriented. I want to be able to do some of both using their strengths
including both at the same time. Python has modules like rpy2 that allow a
slaved R interpreter to work with programs back and forth. R has a package
called reticulate that allows a different way to intersperse code using
anaconda python. And, there are other ways where a third party such as a
markdown processor allows both in chunks. No need to say more as it is of
little interest to many.

So back to the silly topic about names, just briefly. I am sure there are
many other puns of sorts used in naming conventions among python users.
There are seemingly endless uses of phrases from the Month Python comedies
such as "shrubbery" and clearly also snake analogies. Chris one-upped me
with an excellent riposte on some others making a bit of a joke about snakes
shedding skin. Not clear on what python would shed when being replaced by
C++ but I can live with that. As I see it, python is a very sophisticated
backbone with lots of flexibility that you may need to graft arms and legs
to if you want to rise above the ground level.

[[Please forget I said that, whatever it means.]]

-Original Message-
From: Python-list  On
Behalf Of Grant Edwards
Sent: Thursday, January 3, 2019 3:29 PM
To: [email protected]
Subject: Re: the python name

On 2019-01-03, Gene Heskett  wrote:

> Do I miss-remember that there was an anaconda language at sometime in 
> the past? Not long after python made its debute? I've not see it 
> mentioned in a decade so maybe its died?

About 20 years ago, the RedHat Linux (way before RHEL) installer (which was
written in Python) was called Anaconda.

-- 
Grant Edwards   grant.b.edwardsYow! What UNIVERSE is
this,
  at   please??
  gmail.com

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

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


RE: the python name

2019-01-03 Thread Avi Gross
Neil,

You convinced me.

I meant the content and usefulness of a programming language need not be
correlated strongly with the name given and especially not the shortened
name it commonly goes by.

But if you mean how hard is it to use a web search engine to find things,
indeed. The perfect name would be something so unique nobody else would use
it.

By that standard, searching for R or C is a tad excruciating. The choice of
other keywords can help as well as tricks like searching for [R] instead of
plain R. 

So, yes, python also finds snakes. Guess what pandas finds? [Before anyone
asks, it is not a programming language but is a part of extended python.]
You start wondering if you are searching in a zoo.

But I suspect a name like X69Y-22C might be a great name to search for but
not very interesting.

When I look at names of computer languages I see a few patterns.

Some pick a name to honor Blaise PASCAL, Haskell  Curry, Alan Turing or Ada
Lovelace. Many are a condensation of a phrase with some computational
meaning like List Processing, Algorithmic Language, Common Business Oriented
language, Formula Translator? (I recall using the What For version).
Programming Language 1, A Programming Language, Program Logic and so on.

Some have the creator(s) names embedded, such as AWK with one letter per
author.

Quite a few seem to be terse enough for a single letter. Besides C, R and S,
and their variants such as C++ and C# and S+, there was a D, an E and a T
and a J and an M and another musical note in F# and of course the Q from its
own dimension. 

I used to think I had studied and even used quite a few programming
languages over the years but staring at these lists makes me realize I never
even heard of so many of them.


-Original Message-
From: Python-list  On
Behalf Of DL Neil
Sent: Thursday, January 3, 2019 11:54 PM
To: 'Python' 
Subject: Re: the python name

On 3/01/19 2:03 PM, Avi Gross wrote:
> Challenge: Can we name any computer language whose name really would
suggest it was a computer language?
> 
> I think the name is the least important aspect of a computer language.


Perhaps not.

If you subscribe to the wider StackOverflow Driven Design philosophy (SODD),
then it would be a kindness to choose the language's name so as to be (close
to) unique when entered as a search key.

Thus the OP's original assumption/confusion between a programming language
and a serpent; Java and a large island; right down to C, R, etc which are
too short to be usable search terms in most engines.

--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list

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


What can python replace?

2019-01-03 Thread Avi Gross
All this talk about language names makes me ask what can evolved languages like 
python replace?

 

I mean clearly a language like ancient BASIC which had GOTO and GOSUB verbs may 
not be anything worth considering.

 

But if there was a language that broke though as a functional programming 
language, could it easily be replaced by a multi-purpose language like python 
that arguably does that well too? What about one that focused on an 
object-oriented approach? Note that these are just buzz words and the 
implementation choices are often far from the same. But I suspect there are 
languages with a fairly simple and narrow toolset, that could be easily 
translated into fairly equivalent python if you also supplied some 
modules/libraries that could be linked in to supply functionality and translate 
some protocols that differ such as wrapping a function call with arguments that 
are in a different order so they call properly. 

 

The above is far from easy in some ways, of course. I won’t supply my endless 
examples, but will say that some features are different enough like whether you 
short-circuit “A or B and C” where A,B,C are arbitrary expressions with 
potential side effects, so a translation from another language that does not 
might require:

 

resultA = A

resultB = B

resultC = C

 

And now that you have forced all three to be evaluated, you can do “resultA or 
result and result” where not re-evaluating some does not matter.

 

I know there is no way to vote any languages off the team. I suspect in real 
life many companies, projects, etc., have already migrated to new development 
environments over the years. Do we know of examples that have literally 
migrated to python including not just new code but existing code?

 

One interesting side to this might be part of a consideration of how a language 
like python can decide on changes and new features. If told that users of some 
language just need a few more tweaks and python would then meet their needs, is 
that a good reason?

 

I really would not want to see features like GOTO restored 😊

 

 

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


RE: the python name

2019-01-04 Thread Avi Gross
William,

Although I used FORTRAN ages ago and it still seems to be in active use, I am 
not clear on why the name FORMULA TRANSLATOR was chosen. I do agree it does 
sound more like a computer language based on both the sound and feel of FORTRAN 
as well as the expanded version.

It seems to have been designed as a mathematical extension of sorts that 
allowed you to evaluate a mathematical formula efficiently. I mean things like 
quadratic equations. But there is overlap with what other languages like COBOL 
or BASIC did at the time.

What gets me is the vagueness of the words looked at by ME today. Any modern 
computing language can do what standard FORTRAN does, albeit perhaps more 
slowly as I know some languages do some of their math using libraries from 
FORTRAN. But do we use the word TRANSLATOR quite that way much anymore? Heck, 
do we use FORMULA in the same way?

My most recent use of formula has been in the R language where there is a 
distinct object type called a formula that can be used to specify models when 
doing things like a regression on data. I am more likely to call the other kind 
using words like "equation". Python has an add-on that does symbolic 
manipulation. Did FORTRAN have any of these enhanced objects back when created, 
or even now?

As I joked in an earlier message, I remember using a version of FORTRAN called 
WATFOR. Yes, there was a WATFIV. 



-Original Message-
From: Python-list  On 
Behalf Of William Ray Wing via Python-list
Sent: Friday, January 4, 2019 11:06 AM
To: Python 
Cc: William R. Wing 
Subject: Re: the python name

On 3/01/19 2:03 PM, Avi Gross wrote:
> Challenge: Can we name any computer language whose name really would suggest 
> it was a computer language?
> I think the name is the least important aspect of a computer language.

I’d like to propose that classic FORTRAN (FORmulaTRANslator) came/comes close.

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

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


RE: Type hinting of Python is just a toy ?

2019-01-04 Thread Avi Gross
You can play mathematical reduction games and declare the only type of
variable needed is a memory location but who cares?

The reality is that well designed data structure can allow you to think
about a problem in a way that leads to easy solutions. True, you can store
something like an employee record with N fields in an amazing number of
ways. It can be a simple or nested list construct, or an instance of some
class or a dictionary, perhaps nested, or it can be a newly minted object
like a NamedTuple or it can even be stored in N unrelated variables. But
some representations appeal to some people and some perhaps to others and
some depend on the situation. There tends to be room for multiple ways.

Anyone ever use a version of LISP where the dominant or even only data
structure was nested lists. I shudder at memories of having to use weird
functions like CAADDR which effectively did the equivalent of multiple
instances of CAR and CDR to dig deeply into such a mess. Why would anyone
want to use that representation on a regular basis.

Python thought it had all the primitive data types in the base. What more do
you need than strings, numbers, and several variants on a list? Throw in
dictionaries, and clearly you can write anything? Heck, throw in
classes/objects and you can make anything else?

Well, it seems that over the years people have felt the need to make so much
more and then set it aside for reuse. I use what amounts to a restricted
list all the time. A numpy array forces all entries to be of the same type.
Not necessarily pythonic but when you are used to a language where there is
no simpler data type consisting of a single int or a single character and
everything is of indefinite length so the above is just a vector of length
1, you start wanting that to represent things like columns of data. When you
are used to something that is a 2D representation, you may want something
like a matrix or DataFrame and so on. True, these can be built easily using
1D components in a list along with algorithms on how to calculate where the
nth item will be stored. But to program more the way you think and be able
to ignore lower-level details, more is needed. 

And, in the same vein, you may want to add a layer of logic or restrictions
around those basic types such as requiring them to be non-negative. You may
want to handle a concept like infinity which simply cannot be an aspect in a
truly primitive type.

It takes some Gaul to say all variables can be divided into three parts
(just kidding.)

Of course having too many choices can freeze new learners and old ones
alike. Research on human psychology shows that people in a 401K plan or IRA
(several of many U.S. tax-advantaged plans) that offers too many choices
often results in people making no choice (getting a low interest account by
default perhaps) or putting a small amount I MANY of them since they have no
idea what makes sense and have trouble with decisions.

But any good programming language needs a decent number of choices.
Arguments that a tuple is just a restricted list so why do you need it are
more reductionist than practical. There are quite a few reasons to have both
and repercussions of your choice.



-Original Message-
From: Python-list  On
Behalf Of Joel Goldstick
Sent: Friday, January 4, 2019 9:04 AM
Cc: Python 
Subject: Re: Type hinting of Python is just a toy ?

On Fri, Jan 4, 2019 at 7:50 AM Chris Angelico  wrote:
>
> On Fri, Jan 4, 2019 at 8:06 PM iamybj--- via Python-list 
>  wrote:
> >
> > In fact, there is only 3 types in all prigramming languages.
> > Primitive type: int, string, bool, char
> > Complex type: struct or class
> > Array Type: int[10], string[100], struct[1000]
> >
> > These 3 type can represent all thins in the world.
>
> Why do you need three types? REXX has just one type: the string.
> Structures, classes, arrays, mappings, etc are all implemented with a 
> special type of variable, the "stem".
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list

I don't normally comment on this type of thread, but I believe the OP is
showing an example of the dunning-kruger effect
https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect

Not teasing, really.

--
Joel Goldstick
http://joelgoldstick.com/blog
http://cc-baseballstats.info/stats/birthdays
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: the python name

2019-01-04 Thread Avi Gross
Gene,

It is simple in Python:

if "IV" in "FIVE":
print("Roman 4 is 5!")

prints:

Roman 4 is 5!

Just a stupid coincidence that the spelling in current English for the
numeral Five happens to have the silly one-less than 5 notation of the Roman
numerals IV. 

Maybe someone with my perverted sense of humor found it amusing to change
the nomenclature so WAT remains the same in WATFOR and in WATFIV but they
did not retain the FOR and make WATFORIV which might be harder to pronounce.

Now if they had named the language pithon or python instead of python, we
might be having marathon sessions evaluating digits of pi or eating dessert.

Time to stop posting before ...

-Original Message-
From: Python-list  On
Behalf Of Gene Heskett
Sent: Friday, January 4, 2019 4:20 PM
To: [email protected]
Subject: Re: the python name

On Friday 04 January 2019 13:22:03 Ian Kelly wrote:

> On Fri, Jan 4, 2019 at 10:59 AM Dennis Lee Bieber
 wrote:
> > On Fri, 4 Jan 2019 01:12:42 -0500, "Avi Gross"
> > 
> >
> > declaimed the following:
> > >language, Formula Translator? (I recall using the What For  
> > >version).
> >
> > WATFOR => WATerloo FORtran
>
> And then there was WATFIV, which stands for WATerloo Fortran IV.
> Because 5 == IV.

Not what I was taught 75 years ago. Thats a brand new definition of fuzzy
logic. :(

Cheers, Gene Heskett
--
"There are four boxes to be used in defense of liberty:
 soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)
Genes Web page <http://geneslinuxbox.net:6309/gene>
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: the python name

2019-01-04 Thread Avi Gross
Oops. They autocorrected the word piethon below so it makes no sense. I
meant a pie-eating-marathon or whatever. 

-Original Message-
From: Python-list  On
Behalf Of Avi Gross
Sent: Friday, January 4, 2019 6:55 PM
To: [email protected]
Subject: RE: the python name

Gene,

It is simple in Python:

if "IV" in "FIVE":
print("Roman 4 is 5!")

prints:

Roman 4 is 5!

Just a stupid coincidence that the spelling in current English for the
numeral Five happens to have the silly one-less than 5 notation of the Roman
numerals IV. 

Maybe someone with my perverted sense of humor found it amusing to change
the nomenclature so WAT remains the same in WATFOR and in WATFIV but they
did not retain the FOR and make WATFORIV which might be harder to pronounce.

Now if they had named the language pithon or python instead of python, we
might be having marathon sessions evaluating digits of pi or eating dessert.

Time to stop posting before ...

-Original Message-
From: Python-list  On
Behalf Of Gene Heskett
Sent: Friday, January 4, 2019 4:20 PM
To: [email protected]
Subject: Re: the python name

On Friday 04 January 2019 13:22:03 Ian Kelly wrote:

> On Fri, Jan 4, 2019 at 10:59 AM Dennis Lee Bieber
 wrote:
> > On Fri, 4 Jan 2019 01:12:42 -0500, "Avi Gross"
> > 
> >
> > declaimed the following:
> > >language, Formula Translator? (I recall using the What For 
> > >version).
> >
> > WATFOR => WATerloo FORtran
>
> And then there was WATFIV, which stands for WATerloo Fortran IV.
> Because 5 == IV.

Not what I was taught 75 years ago. Thats a brand new definition of fuzzy
logic. :(

Cheers, Gene Heskett
--
"There are four boxes to be used in defense of liberty:
 soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)
Genes Web page <http://geneslinuxbox.net:6309/gene>
--
https://mail.python.org/mailman/listinfo/python-list

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

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


RE: the python name

2019-01-04 Thread Avi Gross
I don't go back to the beginning of FORTRAN. My comment was not that FORTRAN
was badly named when it was among the first to do such things. I am saying
that in retrospect, almost any language can do a basic subset of arithmetic
operations. And there is nothing in principle that necessarily stops any
modern language code from being optimized by translators to be even more
rapid than the original versions of FORTRAN. If anything, I can well imagine
algorithms using parallel architectures from performing some operations way
faster. True, many languages tend to add overhead but that is not
necessarily required.

As some have said here, many things these days are fast enough not to need
ultimate optimization.

Having said that, there is no reason why code used over and over should not
be optimized. Functions in higher-level languages can be written using the
language and then can be replaced if there is a great enough improvement and
they do not need some of the interactive features the language might offer. 

Someone mentioned that in principle all data types can be stored in a
string. Python does have a concept of converting many, but not all data
structures into a byte form that can be written to files and restored or
sent to other processes including on other machines. Of course entire
programs written in text can be shipped this way to some extent. But when
your data is a long list of real numbers that you want to find the standard
deviation of, then converting it into a compact C/C++ array (or something
similar in Fortran) and calling a function in that language that works fast
on that, may be a good way to go. Why interpret a step at a time when one
pass generates the data that can be processed in tighter loops and a result
returned?

-Original Message-
From: Python-list  On
Behalf Of Dennis Lee Bieber
Sent: Friday, January 4, 2019 1:17 PM
To: [email protected]
Subject: Re: the python name

On Fri, 4 Jan 2019 11:34:24 -0500, "Avi Gross" 
declaimed the following:

>
>Although I used FORTRAN ages ago and it still seems to be in active use, I
am not clear on why the name FORMULA TRANSLATOR was chosen. I do agree it
does sound more like a computer language based on both the sound and feel of
FORTRAN as well as the expanded version.
>
>It seems to have been designed as a mathematical extension of sorts that
allowed you to evaluate a mathematical formula efficiently. I mean things
like quadratic equations. But there is overlap with what other languages
like COBOL or BASIC did at the time.
>

FORTRAN predates BASIC by a decade.

COBOL was never meant to be an in-depth number cruncher language
(original data type is packed BCD). Writing a quadratic equation in it
probably takes two or three pages (as I recall, the COMPUTE verb was a later
addition, so everything would have been long sentences: 
DIVIDE C BY B GIVING TMP1. MULTIPLY TMP1 BY 2. SUBTRACT TMP1 FROM A GIVING
RESULT1. ADD TMP1 TO A GIVING RESULT2. 
vs
COMPUTE TMP1 = (C / B) * 2. COMPUTE RESULT1 = A - TMP1. COMPUTE RESULT2 = A
+ TMP1. )

>What gets me is the vagueness of the words looked at by ME today. Any
modern computing language can do what standard FORTRAN does, albeit perhaps
more slowly as I know some languages do some of their math using libraries
from FORTRAN. But do we use the word TRANSLATOR quite that way much anymore?
Heck, do we use FORMULA in the same way?

Meanings change... "COMPUTER" means "one who computes" -- those poor
overworked engineers with slide-rules creating ballistic tables for
battleships.

"Translator" still applies -- in the sense of taking one language
(source) and producing the equivalent meaning in another language
(assembler, and then translating that to pure machine binary). "Formula"
has likely been superceded by "algorithm" (cf ALGOL)

>
>My most recent use of formula has been in the R language where there is a
distinct object type called a formula that can be used to specify models
when doing things like a regression on data. I am more likely to call the
other kind using words like "equation". Python has an add-on that does
symbolic manipulation. Did FORTRAN have any of these enhanced objects back
when created, or even now?

No body had symbolic manipulation when FORTRAN was created. At the
time, the goal was to produce a higher order language that the scientists
could write without having to /know/ the computer assembly/machine code,
with the hope that it could be portable at the source level. Users were
charged by the minute for CPU time, and operating systems were lucky to be
able to handle more than one program in parallel. Batch systems were the
norm -- where a program would run until it either finished, or it ran out of
CPU time (as specified on a LIMIT in the job control deck). One would turn
in a deck of cards to be spooled in the job queue, and come bac

RE: the python name

2019-01-05 Thread Avi Gross
Dennis,

Yes, I remember seeing proofs that a bare-bones Turing Machine with an
infinite bidirectional tape can solve anything done by a classical computer.
I also suggest that in many cases, such a device is a way to transform any
problem that can be solved decently into one that can now be solved in
indefinite and sometimes effectively infinite, time. I wrote my thesis on a
variant of such an automaton.

But many things that are theoretically doable remain far from practical.
There are often shortcuts both in hardware and software that allow simpler
solutions using finite resources for reasonable amounts of data processed.

I recall an example from a version of mathematical LISP that I will rewrite
in python for illustration:

def is_greater(left, right):
if left <= 0 : return False
if right <= 0 : return True
return is_greater(left - 1, right - 1)

That is a beautiful mathematical way of looking at it. Given two
non-negative numbers, keep subtracting one from both sides until one is 0 or
less. At that point, you know. The original version did not use subtraction
but rather an abstract function to return a predecessor. Nice and abstract.
Too abstract.

Yes, this does not handle equality well. Easy enough to amend. But the POINT
is that comparing a trillion to a quadrillion may take some time and without
tail recursion may exhaust the stack long before it completes.

Yet for an amazing number of case, a shorter solution is as simple as
placing left in register A and right in register B and issuing a command
that compares them bitwise or something and returns a True/False in register
A as a bit, or whatever the details. Or, for big numbers, many other
techniques that are still simple and fast enough can be done such as
converting the number into a long string of decimals and comparing one at a
time till they diverge.

So for practical matters, Turing machines are no more than a debating point.
Yes, a language without exponentiation can solve a large set of problems
using repeated multiplication but how easily with it raise the
transcendental number e to the [product of the transcendental number pi
times the odd square root of -1] and get a result of -1?

Heck, who needs multiplication? Repeated addition might do, to a point?

Or, go back to the Turing machine where you, well, why bother?

In the real world, the path to progress in the PRESENT often uses
improvements that let you program at increasing levels of abstraction and
allows underlying details to be handled for you with some confidence. So
even though many programming constructs do an implicit goto when viewed at
machine language levels, they are usually somewhat hidden when viewed as
loops or exception handling. Heck, we now often hide loops.

-Original Message-
From: Python-list  On
Behalf Of Dennis Lee Bieber
Sent: Saturday, January 5, 2019 1:46 PM
To: [email protected]
Subject: Re: the python name

On Fri, 4 Jan 2019 22:59:40 -0500, "Avi Gross" 
declaimed the following:

>was badly named when it was among the first to do such things. I am 
>saying that in retrospect, almost any language can do a basic subset of 
>arithmetic operations. And there is nothing in principle that 
>necessarily stops any

CF: https://en.wikipedia.org/wiki/Turing_completeness

Pretty much ANY computer language can be used to do any computation -- it
may be more difficult in some, but it won't be impossible. The hypothetical
Turing machine would, in one way, be the ultimate in symbolic manipulation
given the basics consist of test/move/store...



-- 
Wulfraed Dennis Lee Bieber AF6VN
[email protected]://wlfraed.home.netcom.com/ 

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

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


RE: the python name

2019-01-05 Thread Avi Gross
nt tradeoff.

Python is a mixture of new and old. Some argue a few decades is not old
given hold FORTRAN is. True. But people considering building a completely
new language today might make different choices. But it might take decades
before that language had a chance to be as widely used as python and clearly
python periodically adjusts to new ideas and evolves. But as we see in the
way version 2.x is being gradually let go, not all change can be done
without some sacrifice of the old way which was not designed in ways that
are quite easy to keep alongside the new. Python is not alone. PERL also has
a schism and clearly C has many offspring that are in some ways above
C-level.

END OF DIGRESSION.

-Original Message-
From: Python-list  On
Behalf Of Chris Angelico
Sent: Saturday, January 5, 2019 5:43 PM
To: Python 
Subject: Re: the python name

On Sun, Jan 6, 2019 at 9:34 AM Avi Gross  wrote:
> I recall an example from a version of mathematical LISP that I will 
> rewrite in python for illustration:
>
> def is_greater(left, right):
> if left <= 0 : return False
> if right <= 0 : return True
> return is_greater(left - 1, right - 1)

Possibly:
if left <= 0: return is_greater(-right, -left)

Otherwise it will give incorrect results for, eg, is_greater(-10, -11)

But your point is taken.

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

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


RE: the python name

2019-01-06 Thread Avi Gross
[Can we ever change the subject line?]
{REAL SUBJECT: degrees of compilation.}
Peter wrote:

"...
Hoever, this is the Python list and one of the advantages of Python is that we 
don't have to compile our code. So we need a different excuse for fencing on 
office chairs ;-).
..."

I understand what he means, but python does sometimes do a half-compilation to 
byte code if the compiled version does not exist or the file being read is 
newer. And, if it cannot write a file, it compiles it in memory each and every 
time. This half-digested format may not be considered a compile down to the 
level of machine code, obviously.

I have no idea of relative run  times for the compiles as so much depends on 
the contents of files and their sizes and the underlying language/compilers. 
Compiling a project with an endless numbers of pieces can take a very long 
time. When you are just doing one file now and then, not so much. I suspect 
that the common method of spreading out a program into many small files can 
have an impact on the time it takes.

I won't share my own war stories of how to compile in what now seem primitive 
environments on overloaded machines where you often figured out your mistakes 
on paper before the compiler quit and showed you officially 😊

What is the purpose of compiling? Superficially, it is to catch serious errors. 
So if there are serious errors, or perhaps to put it mildly, places where the 
compiler can't figure out exactly what you, the programmer, meant, it often can 
quit early. Only when it finds nothing wrong does it need to finish to the end. 
Sometimes parts of what you may not necessarily consider the compiler can be 
done selectively or even externally.

I mean you can use tools to tune up your code in ways that search not so much 
for obvious errors but for potential errors or possibly poor technique that 
generate warnings or hints. If you add some of this functionality in the normal 
compile, you slow it down. Similarly, there are aspects that optimize the code 
in some ways that are good to have in final production code ready to ship but 
may not be needed every time you compile.

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


RE: Compilation (was: the python name)

2019-01-06 Thread Avi Gross
guage of that
component into reams of hard to penetrate troff including lots of variables
and arithmetical calculations. As you describe, there was a sort of
translation from a higher-level language to somewhat lower-level and then to
even lower levels down to something like the printer language that applied.

When we finally got screens with pixels and programs that generated a decent
(not perfect) WYSIWYG, we started printing less often. Nowadays, some people
using Word Processing never actually need to print.

Well, the imperfect analogy ends. Moving on.

-Original Message-
From: Python-list  On
Behalf Of Peter J. Holzer
Sent: Sunday, January 6, 2019 5:25 PM
To: [email protected]
Subject: Compilation (was: the python name)

On 2019-01-06 15:09:40 -0500, Avi Gross wrote:
> [Can we ever change the subject line?]

Feel free.

> {REAL SUBJECT: degrees of compilation.} Peter wrote:
> 
> "... Hoever, this is the Python list and one of the advantages of 
> Python is that we don't have to compile our code. So we need a 
> different excuse for fencing on office chairs ;-). ..."
> 
> I understand what he means, but python does sometimes do a 
> half-compilation to byte code if the compiled version does not exist 
> or the file being read is newer.

This is compilation, but it isn't a separate phase. We don't invoke a
"python compiler" to produce an "executable" which we then "execute". We
invoke the interpreter on the source code, which compiles the source code as
needed (so in the literal sense it is a just in time compiler, although this
isn't what we usually mean by that term). 

And because this happens in principle every time we start a python program
(yes, there is a cache, but that is incidental) the compiler must be fast
and primitive and basically unnoticable.


> What is the purpose of compiling? Superficially, it is to catch 
> serious errors.

I strongly disagree with this. The purpose of compiling is to translate from
one language into another. Typically, the source language is more
programmer-friendly, higher level and the target language is more
machine-friendly, lower level. But there are exceptions.

Finding errors is mostly a consequence of this function. If the compiler
cannot parse the source code or doesn't have enough information to generate
code in the target language, it cannot fulfill its function and has to bail
out.

There are programs with the primary purpose of finding errors: We call these
linters, static analysers, etc.

(From your other mails I guess that you almost certainly remember the Unix
distinction between cc and lint.)

Of course sometimes these are functions are conflated. Since an optimizing
compiler has to analyse variable usage anyway for efficient register
allocation it can also warn you about unused variables at
(almost) no extra cost. So it makes sense to put that warning into the
compiler (I'm less sure if it's a good idea to make this an error, as in
Go). Or the compiler might even get quite expensive checking capabilities,
as the authors think that programmers are more likely to look at the output
of the tool they have to use than to invoke a separate, optional tool.

hp

-- 
   _  | Peter J. Holzer| we build much bigger, better disasters now
|_|_) || because we have much more sophisticated
| |   | [email protected] | management tools.
__/   | http://www.hjp.at/ | -- Ross Anderson <https://www.edge.org/>

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


RE: Working with graphs - Kevin Bacon game - WOT

2019-01-09 Thread Avi Gross
[HUMOR ALERT]

Others have given answers that are on topic so mine is not needed. I was
amused by the understandable spelling error about doing the unusual variant
of a Breath First Search when it is clear they meant Breadth.

But it may apply in this case. The Keven Bacon Game is a variation on
calculating the Erdős number. It relates to finding people who were in a
film alongside Kevin Bacon and presumably were at some point in close enough
proximity to share some component of Breath. They are the closest degree you
can get to Kevin without being him. Anyone in a film with one of those
people but not directly in a film with Kevin is of a second degree and so
on. Still others get the third degree and I won't question that.

There are several problems with an approach based on breath. The first is
that movies are often made in which the participants work in different areas
and never meet. Simply being in the same film does not guarantee that level
of closeness. And, I have seen convincing arguments that suggest the
likelihood we have all shared the recycled breath of historical figures and
very possibly have incorporated atoms that once resided within their bodies
into our own. I will spare you the calculations except to say that in some
ways we are all one. We have all breathed air that includes minor amounts
once in not only a particular Pharaoh in Egypt but also from just about
anyone in his kingdom that lived a moderately long life -- no matter where
on earth we live.

A modern figure like Kevin Bacon gets around and certainly if you live in an
area like parts of California he lived in, you may be very close in a Breath
First search but without much Depth.

And, yes, pythons breathe the same air we do, as do python programmers, just
to bring this back to whatever it is we are supposed to waste our breath
"talking" about here.

-Original Message-
From: Python-list  On
Behalf Of [email protected]
Sent: Wednesday, January 9, 2019 4:54 AM
To: [email protected]
Subject: Working with graphs - Kevin Bacon game

I am working on Kevin Bacon game.

I have "movies.txt" text file that looks like:

Apollo 13 (1995);Bill Paxton;Tom Hanks;Kevin Bacon Begyndte ombord, Det
(1937);Aage Schmidt;Valso Holm Bersaglio mobile (1967);Dana Young;Bebe Drake
Bezottsovshchina (1976);Yelena Maksimova;Lev Prygunov Dark, The
(1979);Angelo Rossitto;William Devane etc,...

So in first row we have movie name, and in other rows we have actors for
that movie.

I am trying to make Kevin Bacon game with breath-first search.

My source code (Python 3.X):



class cvor:
__slots__ = ('ime','susjed')


def kreiranjeCvora(ime):
n = cvor()
n.ime = ime
n.susjed = []
return n

def pronadiCvor(cvorlist, ime):
for n in cvorlist:
if n.ime == ime:
return n


def ucitajGraf(file):  
graph = []
for line in file:
imeGlumaca = []
mojaLinija = line.split(";")
imeFilma = mojaLinija[0]
for i in range (1,len(mojaLinija)):
imeGlumaca.insert(len(imeGlumaca), mojaLinija[i])   

cvorFilm = pronadiCvor(graph, imeFilma)
if cvorFilm == None:
cvorFilm = kreiranjeCvora(imeFilma)
graph.append(cvorFilm)
for glumac in imeGlumaca:
glumacCvor = pronadiCvor(graph,glumac)
if glumacCvor == None:
glumacCvor = kreiranjeCvora(glumac)
graph.append(glumacCvor)
glumacCvor.susjed.append(cvorFilm)
cvorFilm.susjed.append(glumacCvor)
return graph


def main():
f = open("movies.txt")
graf = ucitajGraf(f)
print (graf)

main()


My problem is that when I print graph with "print (graph)" I am getting:

"[<__main__.cvor object at 0x01475275EBE0>, <__main__.cvor object at
0x01475275EEF0>, <__main__.cvor object at 0x01475275EFD0>,
<__main__.cvor object at 0x01475275EE80>, <__main__.cvor object at
0x01475275EB70>, <__main__.cvor object at 0x01475275ED68>,..."

And I know why but I don't know how to fix it and get "name" there.

What would be the best way to perform breath-first search between two
entered names?
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: How to find files with a string

2019-01-09 Thread Avi Gross
Anton,

OVERVIEW: SET vs DICT

Some of us have less experience decoding Cyrillic error messages. The part we 
can read suggests the program objected to the way a dictionary was being 
updated. 

ValueError: dictionary update sequence element #0 has length 35; 2 is required

(The Russian said something like: Working with the file system / Searching 
files from the .py folder)

The normal method is to provide something that evaluates to a key/value 
combination. You made an empty dictionary with {} NOT an empty set which is 
only created using the notation set().

Your find_value() function returns a SET containg the filename unconditionally 
this way:
return {fname}

That is not a dictionary entry. It is a set and this is not something you can 
add to a dictionary as it has no key.

Why the 35 above? I would guess it may be seen as a list of 35 charcaters or 
something.

Two more points. Your text says searching for TeNum but the function searches 
for TeNam.

Worse, the function seems to be wrong for the purpose intended. If the goal is 
to search line by line and if found any number of times, return the filename, 
it does not do that. It seems to print the filename when any line matches. No 
idea why you do some other things but the return is unconditional so it should 
return every filename it finds.

-Original Message-
From: Python-list  On 
Behalf Of [email protected]
Sent: Wednesday, January 9, 2019 11:30 AM
To: [email protected]
Subject: How to find files with a string

Hello everyone!

I need to find a file, that contains a string TeNum

I try to 

import os
import sys
def find_value(fname):
value = 0
with open(fname, encoding='cp866') as fn:
try:
for i in fn:
if 'TeNam' in i:
print(fname)
except IndexError:
pass
return {fname}
def main():
dirname = ('H:\\1\\3')
os.chdir(dirname)
res = {}
for i in os.listdir(dirname):
res.update(find_value(i))
print('Filename is: ')
if __name__ == "__main__":
main()

But there are mistakes like
C:\Users\Anton\AppData\Local\Programs\Python\Python36-32\python.exe 
"C:/Users/Anton/PycharmProjects/Работа с файловой системой/Перебор файлов из 
папки.py"
Traceback (most recent call last):
  File "C:/Users/Anton/PycharmProjects/Работа с файловой системой/Перебор 
файлов из папки.py", line 21, in 
main()
  File "C:/Users/Anton/PycharmProjects/Работа с файловой системой/Перебор 
файлов из папки.py", line 18, in main
res.update(find_value(i))
ValueError: dictionary update sequence element #0 has length 35; 2 is required

Process finished with exit code 1

Could you help me to solve this thread?
-- 
https://mail.python.org/mailman/listinfo/python-list

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


RE: How to find files with a string ++

2019-01-09 Thread Avi Gross
[This message comments on three different items being discussed and also on
how to find out what kind of help is actually requested and warranted.]

People don't usually provide enough context in their requests and I see
wildly different attempts to help. When some code is supplied along with
perhaps an error message, some people try to see what may be wrong and
assume they want to use a slightly improved version of the code to solve
whatever their goal is. Others point to where some other code does it
perhaps a very different way such as the code in IDLE. Some tell you to go
elsewhere and use a finished product as below. So, sure, you can just go and
use grep. And some focus on things like efficiency or portability or how
pythonic its is, whatever that means to THEM.

What is missing at times is the question of what do you want to do next or
even before. That may help guide what is wanted.

It is not easy to guess especially since Anton may not be using the data
structures he might if he was more experienced in python. He seems to be
wanting to use a set which may not seem very focused if the file names are
all unique already. Some might use something simpler and ordered like a
list. If his purpose is to do something like show which files do NOT match,
sure he could make a set of all files and subtract this set but that is not
needed as it is quite simple to record just files that don't match in the
first place.

I am left with a few other anomalies that make me think it would be better
to stop and ask what they want in clearer terms because their overall
approach does not lead me to something obvious.

When people post here, there is no way to enforce their telling us their
general goals. It can be anything from a student trying to solve a problem
using very basic methods they are supposed to have covered in class to
someone just trying to get a task done just once and not caring much what
tools is used and hoping someone on this forum has a quick answer.

If someone says they want to code each one of dozens of algorithms they read
about from SCRATCH, that means they are willing to reinvent the wheel. They
may literally not want any comment on any aspect of their code except asking
how to fix the one error they got. In this case, I am not clear if the
answer is to initialize a set rather than a dictionary, or to use a list in
the first place, or if using a dictionary, supply a key. Perhaps they do not
(yet) want to hear their entire function always returns the filename or
maybe it should return an item instead of a set containing an item or ...

I am reading a book about Clean Code and I note that sometimes here we
ignore fairly simple things and fall for a more gimmicky, if brilliant,
attempt to make something non-obvious. The example was one that comes up
regularly, how to see if two items are equal. In this case, the question was
how to tell if a list of N items contained N identical items. A fairly
straightforward answer would be to loop starting with a second item and keep
comparing the current item to the withheld first. Optionally, quit as soon
as a discrepancy was found. It would depend on using a binary "==" on two
items at a time. Others offered more inline solutions that hide a loop, such
as "any" ad many such variations are possible. 

I am not saying they are all good solutions, and many are fairly horrible
such as trying to compare all permutations.. But one suggested solution was
beautiful and elegant (as in short) and boiled down to comparing the list to
its top-level reversal. It is true that anything with N identical copies
will be shown that way but only as a special case as it is a palindrome.
And, it begs the question of how python evaluates "list1 == list2" as that
may be just syntactic sugar for a method similar or different to the
straightforward ones.

I am surprised nobody suggested this one. First in English. Take the
original list. Assuming it is long enough, rotate it a notch so the former
first item is now at the end and the former second item is in front. Compare
the two versions of the list. A palindrome would be ruined by this simple
manipulation assuming you started with three or more. 

Before I present the trivial code, I want to remind everyone this is NOT a
suggested method. I do NOT want to get lectured at as if I suggested it. It
is what I call an academic exercise. It is a minor variant designed to foil
the darn palindrome case. For argument's sake, a list with no items or a
single item would be solved without calling the function below. Something
with two can harmlessly passed to the function but does not need to be. Only
three and above need apply. I have no doubt there are better ways but this
method would allow something small and nice like:

a == sh(a)

Anyway, here is the code followed by the output just for ILLUSTRATION. If
you can show test cases where it fails, feel free. 

def shift_eq(listing):
"""Compare a list to a rotated version."""

RE: dangerous class neighborhood

2019-01-09 Thread Avi Gross
r close to what Chris says, except that I generally did not say what he is 
replying to here. In particular, I would NOT write the code the way I discuss 
unless everything else I tried failed.

So, I am leaving it like that. I differentiate between what is valid use of the 
language and what is a 'best practice' and what works quickly when you hit a 
roadblock and need to get around it NOW using some kind of patch that may even 
be outside the box.

Main point: I haver no beef with Chris, or anyone here. The neighborhood is 
safe again.

-Original Message-
From: Python-list  On 
Behalf Of Chris Angelico
Sent: Thursday, December 27, 2018 5:11 PM
To: Python 
Subject: Re: dangerous class neighborhood

On Fri, Dec 28, 2018 at 8:47 AM Avi Gross  wrote:
> Question 2: Do you want the variables available at the class level or 
> at the instance level?

For constants, definitely put them on the class. They'll be available on 
instances as well ("for free", if you like). For mutables, obviously you need 
to decide on a case-by-case basis.

> Question 3: Which python variations on syntactic sugar, such as list 
> comprehensions, get expanded invisibly in ways that make the problem 
> happen by asking for variables to be found when no longer in the visible 
> range?

The oddities with comprehensions were tackled partly during the discussion of 
PEP 572. If you want to know exactly why this isn't changing, go read a few 
hundred emails on the subject. A lot of the main points are summarized in the 
PEP itself:

https://www.python.org/dev/peps/pep-0572/

> There may be matters of efficiency some would consider but some of the 
> examples seen recently seemed almost silly and easy to compute. The 
> people asking about this issue wanted to define a bunch of CONSTANTS, 
> or things that might as well be constants, like this:
>
>
>
> def Foo():
>
> A = ("male", "female", "other")
>
> B = [ kind[0] for kind in A ]# First letters
> only
>
> # And so on making more constants like a dictionary 
> mapping each string to a number or vice versa.
>
>
>
> All the above can be evaluated at the time the class is defined but 
> unintuitive scope rules make some operations fail as variables defined 
> in the scope become unavailable to other things that SEEM to be 
> embedded in the same scope.

If you write simple and Pythonic code, these will almost always work perfectly. 
The recent thread citing an oddity worked just fine until it was written to 
iterate over range(len(x)) instead of iterating directly.

> If they are ONLY to be used within an instance of Foo or invoked from 
> within there, there may be a fairly simple suggestion. If you already 
> have a __init__ method, then instantiate the variables there carefully 
> using the self object to reference those needed.

But why? __init__ should initialize an instance, not class-level constants. A 
Python class is not restricted to just methods, and there's no reason to avoid 
class attributes.

> Create a function either outside the class or defined within. Have it 
> do any internal calculations you need in which all internal variables 
> can play nicely with each other. Then let it return all the variables 
> in a tuple like
> this:
>
> def make_sexual_constants():
>
> A = .
>
> B = .
>
> C = f(A,B)
>
> D = .
>
> def Foo():
>
> (A, B, C, D) = make_sexual_constants():

Lovely. Now you have to define your variables once inside the function, then 
name them a second time in that function's return statement, and finally name 
them all a *third* time in the class statement (at least, I presume "def 
Foo():" is meant to be "class Foo:"). A mismatch will create bizarre and 
hard-to-debug problems.
What do you actually gain? Can you show me real-world code that would truly 
benefit from this?

> Can we agree that the class Foo now has those 4 variables defined and 
> available at either the class level or sub-class or instance levels? 
> But the values are created, again, in a unified safe environment?

Unified? No more so than the class statement itself. Safe? Definitely not, 
because of the mandatory duplication of names.

> As noted in section 3, it would be good to know what python features 
> may be unsafe in this kind of context. I had an unrelated recent 
> discussion where it was mentioned that some proposed feature changes 
> might not be thread safe. Valid consideration when that may lead to 
> hard-to-explain anomalies.

Uhh. nope, that's nothing but FUD. There is no reason to believe that some 
language features would be "unsafe".

> We now h

RE: How can I find the indices of an array with float values in python?

2019-01-10 Thread Avi Gross
Madhavan,

Others have given you reasonable answers out of the ever so many many many
ways you can do what you asked. I offer a question to consider in case your
needs are different or you have not considered other more pythonic ways.

What do you want to do with your data and is this the best way to do it?

The pythonic way often is to minimize the use of features common in
languages like C and use new paradigms like iteration where no index is
needed. As others show, you can do many things like a list comprehension
with an if, perhaps alongside an enumerate to catch the index too. 

So, you have an array of numbers. (numpy style) and you want a way to
designate a subset of those numbers that meet your criterion. Your criterion
is a compound criterion that needs refining. You want numbers between 0 and
15. Are you including one or both endpoints? Any answers you choose to use
will need to be adjusted depending on your answer.

And, you seem to want not the values, but instead the indices of the array
where  those values are stored. Are you sure that is what you need to go to
the next step? Maybe you do under your currently conceived algorithm and the
solutions provided will give you a second array of indices you can use in an
unspecified way later. But if all you want to do is get a potentially
smaller array containing just the values you want, and perhaps iterate on
them or apply a function such as getting the standard deviation, there is
another set of answers that just makes copies of the array in any way you
want, sometimes in multiple steps.

I choose to illustrate below with what some may consider a tutorial and
ignore. If your needs are met, feel free.

Is a numpy array the best data type for your needs. If you were using a
pandas DataFrame where one column was your numpy array and you had other
columns, then one could be an index of N numbers corresponding to your
requested index. If you used commands to create a second DataFrame with only
those rows that matched your criteria, the resulting DataFrame would
automatically have the index numbers, and perhaps much more.

I am NOT saying the added complications are needed, just that without
knowing your goals, it may be other ways are a better fit.

And note that in numpy (and pandas) there are other ways to index. Yes, you
can provide an array of integers to index with like this:

import numpy as np
# Create an array to play with odd numbers.
odds = np.array(range(1,20,2))
odds

==> array([ 1,  3,  5,  7,  9, 11, 13, 15, 17, 19])

# Show indexing of the array using indices.
three_in = [2, 4, 6]
odds[three_in]

==> array([ 5,  9, 13])

But you can also index by a Boolean (True/False) list of the same size like:
# Show Boolean indices
three_bool = [False, False, True, False, True, False, True, False, False,
False]
odds[three_bool]

==> array([ 5,  9, 13])

Same result. 

Now you seem to want numbers in a range. I show a way in this example to get
everything greater than one number but less than or equal to another. Since
my numbers happen to be in order, ...

# Show how to get numbers in a range.
odds[(odds > 3) & (odds <= 15)]

==> array([ 5,  7,  9, 11, 13, 15])

So if you don't need indices, something like the above gives you the data
itself to use. If your data must keep track of multiple sets of data, and
you need an index to deal with them, I would suggest another data structure.
Here for example, I combine the same vector as above along with a list of my
favorite elements 

# Make a DataFrame with an additional field and index.
import pandas as pd
ind = np.array(range(len(odds)))
elementals = np.array(["Hydrogen", "Lithium", "Boron", 
   "Nitrogen", "Fluorine", "Sodium", 
   "Aluminum", "Phosphorus", "Chlorine", 
   "Potassium"])
dictate = { "indexed" : ind, "protons" : odds, "moniker": elementals }

df = pd.DataFrame(dictate)
df

==>
indexed protons moniker
0   0   1   Hydrogen
1   1   3   Lithium
2   2   5   Boron
3   3   7   Nitrogen
4   4   9   Fluorine
5   5   11  Sodium
6   6   13  Aluminum
7   7   15  Phosphorus
8   8   17  Chlorine
9   9   19  Potassium

In the above, note there is a default index that happens to match what I
chose. The point is that if you wanted a subset including everything in a
row, you do not really need the index:

df[(df.protons > 5) & (df.protons <= 15)]

==>

indexed protons moniker
3   3   7   Nitrogen
4   4   9   Fluorine
5   5   11  Sodium
6   6   13  Aluminum
7   7   15  Phosphorus

But if you did not ever need the index, you can not include it or even
suppress the default one.

My point, as I stop here from giving the entire tutorial, is for you to
think about what you want to do and consider which way to do it and then use
reasonable tools. If you really 

RE: Python read text file columnwise

2019-01-12 Thread Avi Gross



-Original Message-
From: Avi Gross  
Sent: Saturday, January 12, 2019 8:26 PM
To: 'DL Neil' 
Subject: RE: Python read text file columnwise

I am not sure what the big deal is here. If the data is consistently
formatted you can read in a string per line and use offsets as in line[0:8]
and so on then call the right transformations to comvert them to dates and
so on. If it is delimited by something consistent like spaces or table or
commas, we have all kinds of solutions ranging from splitting the line on
the delimiter to using the kind of functionality that reads in such files
into a pandas DataFrame.

In the latter case, you get the columns already. In the former, there are
well known ways to extract the info such as:

[row[0] for row in listofrows]

And repeat for additional items.

Or am I missing something and there is no end of line and you need to read
in the entire file and split it into size N chunks first? Still fairly
straightforward.

-Original Message-
From: Python-list  On
Behalf Of DL Neil
Sent: Saturday, January 12, 2019 4:48 PM
To: [email protected]
Subject: Re: Python read text file columnwise

On 12/01/19 1:03 PM, Piet van Oostrum wrote:
> [email protected] writes:
> 
>> Hello
>>>
>>> I'm very new in python. I have a file in the format:
>>>
>>> 2018-05-31  16:00:0028.90   81.77   4.3
>>> 2018-05-31  20:32:0028.17   84.89   4.1
>>> 2018-06-20  04:09:0027.36   88.01   4.8
>>> 2018-06-20  04:15:0027.31   87.09   4.7
>>> 2018-06-28  04.07:0027.87   84.91   5.0
>>> 2018-06-29  00.42:0032.20   104.61  4.8
>>
>> I would like to read this file in python column-wise.
>>
>> I tried this way but not working 
>>event_list = open('seismicity_R023E.txt',"r")
>>  info_event = read(event_list,'%s %s %f %f %f %f\n');


To the OP:

Python's standard I/O is based around data "streams". Whilst there is a
concept of "lines" and thus an end-of-line character, there is not the idea
of a record, in the sense of fixed-length fields and thus a defining and
distinction between data items based upon position.

Accordingly, whilst the formatting specification of strings and floats might
work for output, there is no equivalent for accepting input data. 
Please re-read refs on file, read, readline, etc.


> Why would you think that this would work?

To the PO:

Because in languages/libraries built around fixed-length files this is how
one specifies the composition of fields making up a record - a data
structure which dates back to FORTRAN and Assembler on mainframes and other
magtape-era machines.

Whilst fixed-length records/files are, by definition, less flexible than the
more free-form data input Python accepts, they are more efficient and faster
in situations where the data (format) is entirely consistent
- such as the OP is describing!


--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: Email blast management?

2019-01-14 Thread Avi Gross
There is an old saying about getting what you paid for. Python can be free
but applications have costs.

Chris makes some valid points when saying there are existing solutions that
may be worth considering.

If someone wants to know about commercial products that do approximately
what they need and provide some level of service, they can buy it. If they
want it for free, they can create whatever they want using their own code
augmented by any free code they are legally allowed to incorporate.

But free is often not quite free. Look at the complaints about Google and
Facebook who try to make a buck (or a billion) by looking at the data you
generate and helping target advertisers or worse? Look at how the data
sometimes gets out, legally or otherwise? Some people now choose to switch
browsers after they keep seeing ads follow them everywhere for items they
once LOOKED AT and did not even buy.

Is there absolute security if you roll your own app, using python or
anything else? I seriously doubt it. Python probably is not ideal in the
sense that your source code is often readable if someone breaks into your
machine. If you were to say encrypt/decrypt some things so items are never
in plaintext on disk, your code may allow them to see what methods are used
and, if you are careless enough, may even expose the key you use.

I was involved in creating and maintaining a fairly early email product
targeted at businesses quite a few years ago. Part of my responsibility at
one point was to READ a subclass of the mail. Messages that made it into the
system but ran into problems would often end up in a junkmail category and
we needed to examine them to find out what went wrong and file modification
requests. In addition, if we could figure out how to "fix" a message and
sent it onward for delivery, we tried. An example of such an error was when
we added a heterogeneous set of machines in the worldwide network of
different types, a message that fit in memory on one might fail when passed
to/through another kind. We had to adjust the maximum size allowed to what
would fit anywhere.

The point is that someone like me with the root password could read
ANYTHING. All logs were equally available so making a list of all email
addresses or a graph showing communication chains was possible. Many
applications may be vulnerable to just one bad employee given such access.
Some may be vulnerable if just one machine in an intranet is corrupted in
some way. Again, this is not just about email but credit card use, browsing
history, etc.

But I suggest that unless you hire very experienced people to roll your own,
you risk being even less secure than with a more trusted commercial product.
Of course, if you want truly unique features, that may be a reason to have
your own.

The above is some thoughts and is not to be attacked as a suggestion to
waste money buying specific products. I am not selling anything just
reflecting on a wider issue. There seems to be very little absolute safety
in the cyber world just as there really isn't in the physical world. You
take your chances but hopefully with some idea of the risks. Someday
anything you encrypt today may become easily readable unless you use fairly
elaborate one-time pads.


-Original Message-
From: Python-list  On
Behalf Of Chris Angelico
Sent: Monday, January 14, 2019 10:25 AM
To: Python 
Subject: Re: Email blast management?

On Tue, Jan 15, 2019 at 12:53 AM Hartmut Goebel 
wrote:
>
> Am 14.01.19 um 12:47 schrieb Chris Angelico:
> > It's a whole lot more respectful than keeping your own database of 
> > email addresses and then having it compromised some day.
>
> This assumes that one would not *keep* a list of customers in in company.
>

Honestly, I have no idea what you're moaning about. We don't have nearly
enough details here to say what would be _the best_ way to do things, but I
stand by my statement that services like MailChimp and Mailman are worth
looking into.

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

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


RE: the python name

2019-01-16 Thread Avi Gross
[HUMOR for the ALERT]

The question that seems to come up too often about the python name is a
distraction. In particular, it is answered fairly prominently in many places
as just being a nonsensical name because a founder once liked a comedic
entity that chose an oddball name, so they did too.

But as languages develop and evolve, sometimes a name change may be a decent
idea. Perhaps version 4.0 should be renamed Guido so we can get more silly
questions.

There once was a trend to name languages after alphabetic symbols like C and
R. I shudder to think of the possibilities opened up as python embraced
Unicode and we now can select from many thousands of such singletons, most
of which nobody knows how to pronounce.

Imagine people developing languages like X and Y and over the years
enhancing them.

An Enhanced or Extended X, naturally, might be renamed EX.

With further Super new features (think super-symmetry in Physics) we would
have a Super Extended X, or SEX in brief.

Naturally, there may be a tendency to suggest that Y has some really neat
features and perhaps you should extend X in the direction of Y in a sort of
merger you might call SEXY.

OK, enough kidding around. But realistically, as I study the history of
Python including not just new features but deprecating and even removing old
features, and sometimes doing major rewrites of internal implementations and
adding brand new methods and ideas and endless modules and so on, I wonder
if my analogy is stretchable. Python may have begun as a snake of sorts able
to do a simple form of locomotion but over the years, it seems to have
re-grown 4 legs to be more like other reptiles and perhaps become like some
ancient dinosaurs and then kept changing as it started to walk on hind legs
and then the front legs morphed into wings so that modern python is not
limited to low-lying ground movement but can run and swim and even fly and
is now more of a bird. Given my current name, dare I say it seems sort of
AVIan?

Nah!





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


Pythonic Y2K

2019-01-16 Thread Avi Gross
I see messages like the following where someone is still asking how to do
something in some version of python 2.X.

I recall the days before the year 2000 with the Y2K scare when people
worried that legacy software might stop working or do horrible things once
the clock turned. It may even have been scary enough for some companies to
rewrite key applications and even switch from languages like COBOL.

What is happening in the python community, and especially in places where
broken software may be a serious problem?

I assume versions of python 2.X will continue to be available for some time
but without any further support and without features being back-ported. 

Conversion of some features seems simple enough but as I have been studying,
I keep running into many areas where the pythons differ and often in subtle
ways that many may not know to change. I won't go into detail, but fixing
the print statement to become the print function is far from enough. Some
things can be made to work in the last versions of 2.7 where the
back-porting allows a smoother transition.

So, is there info out there on what may be problem areas? Are there modules,
for example, that have not been ported and are not available for 3.X and
don't have some similar enough other module that might be used?

This is not just a python problem, of course. PERL is an example where there
seem to be a new and incompatible old version running around.

As a note, I am not complaining that python has evolved in incompatible
ways. Not easy to avoid unless you like stasis. But if enough people keep
avoiding the hints and outright warnings to get more up-to-date, this
Y2-->3K event may be a problem. 


-Original Message-
From: Python-list  On
Behalf Of Grant Edwards
Sent: Wednesday, January 16, 2019 10:46 AM
To: [email protected]
Subject: Re: get the terminal's size

On 2019-01-16, Karen Shaeffer  wrote:

[fixed quoting and formatting]

>> That will tell you the terminal size at the time Python was started.
>>
>> If the terminal size has changed while Python was running, those 
>> environment variables will be wrong.  You need to use the TIOCGWINSZ 
>> ioctl call:
>>
>> http://www.delorie.com/djgpp/doc/libc/libc_495.html
>>
>> And to detect the size changes (so you know _when_ you need to do the 
>> above), you need to attach a signal handler for the WINCH signal.
>
> I'm running a python 3 interpreter on linux. I'm actually ssh'd into 
> the terminal on a headless server. [...] [...] With the python 
> interpreter running on the remote terminal, I have resized the 
> terminal window on my local laptop several times. And each time, the 
> remote python interpreter knows about the change, correctly printing 
> the new size.  I have done nothing with environment variables. I have 
> not used a signal handler for the WINCH signal. It just works.

Yes, we know that works on Python3.  The discussion was about what to do on
Python2.

$ python2
Python 2.7.15 (default, Sep 12 2018, 15:19:18)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import shutil
>>> shutil.get_terminal_size()
Traceback (most recent call last):
File "", line 1, in 
AttributeError: 'module' object has no attribute 'get_terminal_size'
>>>

-- 
Grant Edwards   grant.b.edwardsYow! I'm having a BIG
BANG
  at   THEORY!!
  gmail.com

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

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


RE: Pythonic Y2K

2019-01-16 Thread Avi Gross
Chris,

The comparison to Y2K was not a great one. I am not sure what people did in
advance, but all it took was to set the clock forward on a test system and
look for anomalies. Not everything would be found but it gave some hints.
Similarly, it is trivial today to take a machine and install only the new
python version and try it, albeit many programs may have effects far away
across the internet in some apps and harder to isolate.

But Y2K was going to happen guaranteed. The split between 2.X has been
fairly slow in some ways and with crutches designed to make a transition
smoother. As long as there are people willing to remain behind in what they
consider safe territory, there will be those happy to sell them some things
and probably raise their prices. I recall what happened with TELEX some
years ago. It was awfully slow compared to other methods such as email or
FAX but it had legal standing and clients who had to be reached in places
that had less access and so on. I recall how despite huge drops in message
volume year after year, it remained a very profitable item for my AT&T unit
and continued to be supported as we just kept raising the price for those
still wanting to use it. I was working on newer stuff and just watched
several such parts in amazement including others using what I considered
obsolete protocols. Not obsolete to those customers though.

I empathize with people using software that already works. You know, if it
isn't broken, 

But to continue making it work may require supplying complete solutions as
customers cannot be expected to have older python interpreters sitting
around on their machine. If your application resides within your servers and
only communicates with others of the same ilk, you probably can continue
using it indefinitely. There may be someone still using an ancient PC from
the 80's running Windows 1.0 with a similarly old copy of WordPerfect and a
serial printer attached. But if they want to load a recent version of
Microsoft Office, forget it. Heck, it would not fit on their 20MEG hard
disk. 

I assume there must be tools out there that can look over your code and
point out places where it may not be compatible. But the more I learn, the
more I realize how subtle a problem may be. Some of the back-ported features
for example are not exactly identical in effect. Close, maybe. Things like
changes in Unicode functionality often are papered over and then a valid
statement in one may print a character while in the other it may print a
short int. 

If you ran such a program and it showed minimal issues like just needing to
change print statements into print functions, it might be easier to convince
your boss to upgrade. If the effort looks massive, they may even opt for a
complete rewrite or move to another language that is less likely to keep
changing, or maybe just buy a solution that is not quite tailored to their
needs.

I did have an experience along these lines years ago when a new variation of
C came across.

Years ago I worked on a project at Bell Labs that was mostly in C. As C++
was coming out, I volunteered to do my part using it as I could show why my
application would be object-oriented. I was shocked when they approved and I
set up make files that recognized what code was in C or C++ and compiled and
linked them properly and so on. It worked beautifully and guess what?

We tossed the entire project! This was back in the days when AT&T cared less
about wasting money. Our project had been canceled at higher levels and the
management spent half a year deciding what our next project would be but
felt no need to tell us! So when I offered to do something experimental,
they figured why not! And, yes, eventually we did our new development in
C++. But had they considered it, it would have made more sense to stop
developing something and take the time to retrain the staff with courses
that were available and have us use up some vacation days and be ready for a
new project. 

Bottom line here is I should not be surprised if some people want an answer
on how to keep projects in 2.X going.  But, unless there is a reason, I see
little reason in going along or teaching new programmers on what is in a
sense the less useful version going forward. The main reason to study 2.X,
FOR ME, is to be able to understand it if I encounter it and perhaps be able
to rewrite it.

-Original Message-
From: Python-list  On
Behalf Of Chris Angelico
Sent: Wednesday, January 16, 2019 2:15 PM
To: Python 
Subject: Re: Pythonic Y2K

On Thu, Jan 17, 2019 at 6:04 AM Avi Gross  wrote:
>
> I see messages like the following where someone is still asking how to 
> do something in some version of python 2.X.
>
> I recall the days before the year 2000 with the Y2K scare when people 
> worried that legacy software might stop working or do horrible things 
> once the clock turned. It may even have been scary enough for some 
> companies to rew

Guido (Sarducci)

2019-01-16 Thread Avi Gross
Dennis,

I wish to apologize for introducing any suggestion to name anything as
Guido, let alone any language that springs from a python. Yes, it may be a
stereotypic Italian name related to what you hint at. You probably
recognized it as an allusion to someone who is clearly Dutch and has some
finite relationship with python. The name is ultimately Germanic and used in
many countries.

I, in a Monty Python Spirit, insist I was thinking about the Saturday Night
Live comedic  character from generations ago, Father Guido Sarducci, who
does indeed appear to be Italian. That is the pythonic way to choose a name
although 3.X might well have been named after the Three Stooges.

Again, my apologies. I will try to resume being serious and maybe talk about
mission creep.

Avi

-Original Message-
From: Python-list  On
Behalf Of Dennis Lee Bieber
Sent: Wednesday, January 16, 2019 4:36 PM
To: [email protected]
Subject: Re: the python name

On Wed, 16 Jan 2019 13:46:29 -0500, "Avi Gross" 
declaimed the following:

>[HUMOR for the ALERT]
>

>But as languages develop and evolve, sometimes a name change may be a 
>decent idea. Perhaps version 4.0 should be renamed Guido so we can get 
>more silly questions.
>

So we can make jokes about a mafia hitman (which is where many might
go with the name)

>
>Imagine people developing languages like X and Y and over the years 
>enhancing them.
>
>An Enhanced or Extended X, naturally, might be renamed EX.

Getting too close to REXX (which was something like Restructured
EXtended eXecutor).

>
>With further Super new features (think super-symmetry in Physics) we 
>would have a Super Extended X, or SEX in brief.
>

Computer science already has sexpr
https://en.wikipedia.org/wiki/S-expression



-- 
Wulfraed Dennis Lee Bieber AF6VN
[email protected]://wlfraed.home.netcom.com/ 

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

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


RE: Pythonic Y2K

2019-01-16 Thread Avi Gross
ed into it that it fills multiple 
pages. I would not show most beginners too much of python at first, or just ask 
them to take some things on faith for a while. A language that initially 
claimed to be designed to do things pretty much ONE way has miserably failed as 
I can do almost anything a dozen ways. That is NOT a bad thing. As long as the 
goal is for someone to learn how to do something in any one way, it is great. 
If you want them to be able to read existing code and modify it, it can be a 
headache especially when people abuse language features. And yes, I am an 
abuser in that sense.

-Original Message-
From: Python-list  On 
Behalf Of Larry Martell
Sent: Wednesday, January 16, 2019 10:46 PM
To: Python 
Subject: Re: Pythonic Y2K

On Wed, Jan 16, 2019 at 9:35 PM Avi Gross  wrote:
>
> Chris,
>
> The comparison to Y2K was not a great one. I am not sure what people 
> did in advance, but all it took was to set the clock forward on a test 
> system and look for anomalies. Not everything would be found but it gave some 
> hints.

Clearly you did not live through that. I did and I got over 2 years of real 
work from it. Companies hired me to check their code and find their Y2K 
exposures. Things like a hard coded '19' being added to a 2 digit year. Or code 
that only allocated 2 bytes for the year. I could go on and on. At one client I 
had I found over 4,000 places in their code that needed to be modified. And 
there was no widespread use of VMs that you could easily and quickly spin up 
for testing. It was a real problem but because of many people like me, it was 
dealt with.
Now the next thing to deal with is the Jan. 19, 2038 problem. I'll be
80 then, but probably still writing code. Call me if you need me.
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: Pythonic Y2K

2019-01-16 Thread Avi Gross
Dave,

You have me worried now. Yes, years from now you may need experts who can
handle not just 2.X but specific versions like 2.4. Assuming python keeps
making incompatible changes and is up to version 9.02, you may also have 3.X
experts and 4.X experts and so on.

Of course, by then, some of the experts may be an AI specializing ...

All kidding aside, I have to wonder if future developments may result in new
categories of computer languages that are designed anew in radically
different ways to the point where it may get more people to switch and more
languages to halt further development.

I see Unicode as a potential driver. The number of symbols in languages like
python is fixed by what can be seen on a normal keyboard. That keyboard
needs to change a bit, or some virtual version, to support lots more. When
that happens, we won't be forced to do as much sharing and overloading as we
do now. How many ways is "%" used including within one line of code?

>>> print("%d %s " % (9 % 5, "ways to use %"))
4 ways to use %

Similarly, {} can be used for dictionaries or sets but an empty set
initializes a dictionary only. [] can be used to index lists by number or
dictionaries by key. There are not as many such sets of characters available
and <> is reserved for other uses and parentheses also has an odd role with
tuples as well as keeping things in some order of operations. Imagine adding
a few more matched symbols including some you can define for your own newly
created kinds of data like matrices. Similarly, you could have an
abbreviated way of defining additional operations if you could just use come
common mathematical symbols that are not in ASCII, not to mention some
dingbats.

If a programming language leaped across the ASCII divide (and I am sure some
have, including the languages that used backspace to make overwritten
multi-character operators) I can see ways to make more compact but less
confusing languages. I admit that might confuse some people, especially some
that only really know one language. I am used to multiple languages
including some with rather unique character sets and perhaps may be the only
one willing to use such a language. OK, sort of kidding.

I have seen many forums like this one (and not just about computer
languages) where I encounter true believers that do not welcome any
suggestion that there may be other things out there with some merit or that
their own may change. I welcome change and am interested in different ways
of thinking. This makes it harder for me to quite see the viewpoint that I
associate with stasis. But, to each their own. Perhaps literally.

-Original Message-
From: Python-list  On
Behalf Of DL Neil
Sent: Wednesday, January 16, 2019 11:04 PM
To: Python 
Subject: Re: Pythonic Y2K

On 17/01/19 4:45 PM, Larry Martell wrote:
> On Wed, Jan 16, 2019 at 9:35 PM Avi Gross  wrote:
>>
>> Chris,
>>
>> The comparison to Y2K was not a great one. I am not sure what people 
>> did in advance, but all it took was to set the clock forward on a 
>> test system and look for anomalies. Not everything would be found but it
gave some hints.
> 
> Clearly you did not live through that. I did and I got over 2 years of 
> real work from it. Companies hired me to check their code and find 
> their Y2K exposures. Things like a hard coded '19' being added to a 2 
> digit year. Or code that only allocated 2 bytes for the year. I could 
> go on and on. At one client I had I found over 4,000 places in their 
> code that needed to be modified. And there was no widespread use of 
> VMs that you could easily and quickly spin up for testing. It was a 
> real problem but because of many people like me, it was dealt with.
> Now the next thing to deal with is the Jan. 19, 2038 problem. I'll be
> 80 then, but probably still writing code. Call me if you need me.


Same.

The easy part was finding the hardware, configuring identical systems, and
changing the date-era. Remember that we pre-dated TDD, so we pretty much
re-designed entire testing suites! The most difficult work was with the
oldest systems - for which there was no/little/worthless documentation, and
usually no dev staff with 'memory'.

Then there were the faults in OpSys and systems programs on which we could
supposedly rely - I still have a couple of certificates somewhere, for
diagnosing faults which MSFT had not found... The difficulty of multi-layer
fault-finding is an order of magnitude more difficult than Python debugging
alone!

I'm told there are fewer and fewer COBOL programmers around, and those that
survive can command higher rates as a consequence. Would going 'back' to
that be regarded as "up" skilling?

Does this imply that there might one day be a premium chargeable by Py2.n
coders?

--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: the python name

2019-01-16 Thread Avi Gross
Greg,

Boy am I getting sorry I brought this topic up again. Getting hard to take
seriously.

I am not making fun of the python name. I am making fun of the people that
want a GOOD REASON for choosing a name.

People generally don't care what silly name you choose for a dog and
certainly tolerate weird names for a racehorse. But they might question
naming a child Thingamajig Mistake Jones or Moon Unit, whatever that means.

Is python an elegant animal name for the language python once was? Sure.
Many animals are admired and on the cover of computer books. My PERSONAL
opinion is that it has become quite a complex language and might as well be
named "The Bronx Zoo" as it houses lots of different animating aspects. I
like it when a commonly used name is easy to remember and pronounce unlike,
say, 3CPO and R2D2.

I am now truly sorry I said anything since no matter what I say, someone
will find it wanting. When python grows enough, maybe we can rename it "the
Full Monty" and people will still ask why. The name is among the least
important things about python. So is the animal it also represents. But if
it pleases some people, good for them.

-Original Message-
From: Python-list  On
Behalf Of Gregory Ewing
Sent: Thursday, January 17, 2019 12:10 AM
To: [email protected]
Subject: Re: the python name

Avi Gross wrote:
> The question that seems to come up too often about the python name is 
> a distraction. In particular, it is answered fairly prominently in 
> many places as just being a nonsensical name because a founder once 
> liked a comedic entity that chose an oddball name, so they did too.

That may be how it started, but I don't think Python is a silly name for a
programming language at all.

There's a long tradition of naming things after animals that have some of
the qualities you want people to associate with them. In the case of Python,
it's not a particularly fast animal, but it is sleek and powerful, and its
minimal design has a certain elegance to it.
So, I think it's very appropriate.

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

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


Sarah Guido

2019-01-17 Thread Avi Gross
Perhaps it is not a coincidence that I plucked the mock-suggestion to name a
language Guido out of thin air.

A book I ordered quite a while ago arrived.

"Introduction to Machine Learning with Python: A Guide for Data Scientists"
by Andreas C. Müller and <<>>

Note the last name is the same Guido we have been discussing for no
meaningful reason whatsoever merely because naming after a (live) founder
may not be a good reason.

I tend to order books in bunches and I have no recollection of even noticing
the first author, let alone the second. I have received and read many of the
books on the subject that arrived first. Still, the way I read I tend to see
everything around an area even if I am not consciously reading it so I
suspect a subliminal recognition along with perhaps a subliminal amusement
that Guido is now both the first and last name of someone I can associate
with python. 

If I had been involved in the above book publication, I might have suggested
using the word "Guide" instead of "Introduction" as it melds well with the
name "Guido" so it is good nobody would even dream of asking me.

Maybe her next book will be abut a GUI to DO or something that fits.

P.S. This is not an endorsement of the book mentioned above nor of Machine
Learning in general but IS an endorsement for using python for such things.
Then again, I also endorse R as I have actually already done such things
using it and want broader choices. Heck, I have already used both together.
Their approaches can be maddeningly different and that opens up
opportunities.

-Original Message-
From: Python-list  On
Behalf Of Avi Gross
Sent: Wednesday, January 16, 2019 9:49 PM
To: [email protected]
Subject: Guido (Sarducci)

Dennis,

I wish to apologize for introducing any suggestion to name anything as
Guido, let alone any language that springs from a python. Yes, it may be a
stereotypic Italian name related to what you hint at. You probably
recognized it as an allusion to someone who is clearly Dutch and has some
finite relationship with python. The name is ultimately Germanic and used in
many countries.

I, in a Monty Python Spirit, insist I was thinking about the Saturday Night
Live comedic  character from generations ago, Father Guido Sarducci, who
does indeed appear to be Italian. That is the pythonic way to choose a name
although 3.X might well have been named after the Three Stooges.

Again, my apologies. I will try to resume being serious and maybe talk about
mission creep.

Avi

-Original Message-
From: Python-list  On
Behalf Of Dennis Lee Bieber
Sent: Wednesday, January 16, 2019 4:36 PM
To: [email protected]
Subject: Re: the python name

On Wed, 16 Jan 2019 13:46:29 -0500, "Avi Gross" 
declaimed the following:

>[HUMOR for the ALERT]
>

>But as languages develop and evolve, sometimes a name change may be a 
>decent idea. Perhaps version 4.0 should be renamed Guido so we can get 
>more silly questions.
>

So we can make jokes about a mafia hitman (which is where many might
go with the name)

>
>Imagine people developing languages like X and Y and over the years 
>enhancing them.
>
>An Enhanced or Extended X, naturally, might be renamed EX.

Getting too close to REXX (which was something like Restructured
EXtended eXecutor).

>
>With further Super new features (think super-symmetry in Physics) we 
>would have a Super Extended X, or SEX in brief.
>

Computer science already has sexpr
https://en.wikipedia.org/wiki/S-expression



-- 
Wulfraed Dennis Lee Bieber AF6VN
[email protected]://wlfraed.home.netcom.com/ 

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

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

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


RE: Pythonic Y2K

2019-01-17 Thread Avi Gross
Well said, Joseph.

Unfortunately, many companies are run these days with a view toward the
IMMEDIATE bottom line. I mean numbers like revenues or expenses are seen
short-term. If a project stops development on new things and spends time
redoing old things, there are expenses recorded with no revenues. Another
organization might go ahead and get up to date and a few years down the road
their projects are sailing along while the first employer keeps running into
obstacles and is not able to get new developments and so on. But often, the
manager making the decision will have taken their bonus or promotion and
perhaps moved on or retired.

Not to be political, I note many government entities, especially including
the state I live in, have gigantic pension obligations they have no easy way
to meet. Over the years in negotiations with unions they have often traded
rich promises for the future instead of immediate pay hikes. The costs may
largely be invisible and did not impact their current budgets so they could
waste money on other things such as giveaways that help them get re-elected
to ever higher office. But the costs are getting very visible now, and
especially when the stocks they invest in decline.

Back in the computer world, Y2K gave such managers some cover. There was a
FIRM deadline. I wonder how many used the impending arrival of the year 2000
as an excuse to perhaps clean up other parts of their act and charge it to
prevention. I mean they might suggest they rewrite some legacy COBOL or even
machine language programs into something more modern or other improvements
like getting a new database including new hardware.

I also wonder if jobs for some programmers declined sharply in the years
after when not only were they not desperately needed, but perhaps not needed
at all unless they developed new talents.

Just FYI, the name Y2K always struck me as similar nonsense. They
abbreviated Year and 2000 from at least 8 characters to 3 and did it wrong
as 2K is 2048. As far as I know, nothing special will happen in 2048 and I
also have no special vision for 2020.

-Original Message-
From: Python-list  On
Behalf Of Schachner, Joseph
Sent: Thursday, January 17, 2019 1:46 PM
To: Python 
Subject: RE: Pythonic Y2K

I'd like to add one more thing to your list of what companies will have to
consider:

6) The ability to hire and retain employees who will be happy to program in
an obsolete version of Python.  A version about which new books will
probably not be written.  A version which new packages will not support.  A
version which most other companies will no longer be using, so programming
only in Python 2 will place the employee at a disadvantage compared to
others who have gained experience with Python 3 if they ever have to change
employers.

--- Joseph S.

-Original Message-
From: Chris Angelico 
Sent: Wednesday, January 16, 2019 2:15 PM
To: Python 
Subject: Re: Pythonic Y2K

On Thu, Jan 17, 2019 at 6:04 AM Avi Gross  wrote:
>
> I see messages like the following where someone is still asking how to 
> do something in some version of python 2.X.
>
> I recall the days before the year 2000 with the Y2K scare when people 
> worried that legacy software might stop working or do horrible things 
> once the clock turned. It may even have been scary enough for some 
> companies to rewrite key applications and even switch from languages like
COBOL.
>
> What is happening in the python community, and especially in places 
> where broken software may be a serious problem?
>
> I assume versions of python 2.X will continue to be available for some 
> time but without any further support and without features being
back-ported.

Commercial support for Python 2 will probably continue for a while, in the
same way that support for versions older than 2.7 is still available to Red
Hat customers today (if I'm not mistaken). Otherwise, well, the software
will continue without updates or security patches until it breaks. Companies
will have to weigh up five costs against each other:

1) The cost of the status quo: the risk of critical failures or external
attacks against unsupported and unpatched software

2) The cost of migrating to Python 3

3) The cost of migrating to a completely different language

4) The cost of maintaining their own local fork of Python 2

5) The cost of using a supported commercial platform such as RHEL.

For most small to medium projects, it's probably going to come down to
#1 or #2, where #1 has the laziness bonus. For many larger companies,
#1 is an unpayable cost. Everyone has to make that choice, and remember that
"cost" doesn't just mean money (for instance, the cost of moving to Linux
might be quite considerable for a Windows shop, and even within a Linux
ecosystem, switching to Red Hat may have consequences to other programs you
might need).

ChrisA

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

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


RE: Pythonic Y2K

2019-01-17 Thread Avi Gross
Ian,

You just scared me. It is 2019 which has four digits. In less than 8,000
years we will need to take the fifth to make numbers from 10,000 to 10,999.
90,000 years later we will need a sixth digit and so on.

Do you know how many potential Y2K-like anomalies we may have between now
and year 292,277,026,596 when it may all be over? Will people evert learn
and just set aside lots of room that dates can grow into or allow varying
lengths?

Makes me wonder though why anyone in the distant future would want numbers
that long to represent that date. I suspect that long before then, some
surviving members of whatever the human race becomes will do a reset to a
new calendar such as the date the first settlers arrived in the Gamma
Quadrant.

So whatever unit they store time in, though, may still need a way to reach
back to historic times just as we do by talking about what may have happened
in 2000 B.C.


-Original Message-
From: Python-list  On
Behalf Of Ian Kelly
Sent: Thursday, January 17, 2019 2:14 PM
To: Python 
Subject: Re: Pythonic Y2K

On Wed, Jan 16, 2019 at 9:57 PM Avi Gross  wrote:
>
> The forthcoming UNIX 2038 problem will, paradoxically happen on 
> January
19. I wonder what they will do long before then. Will they just add a byte
or four or 256 and then make a date measurable in picoseconds? Or will they
start using a number format that can easily deal with 1 Million B.C. and 5
Billion A.D. just in case we escape earth before it co-locates with the
expanding sun.

The obvious solution is to stop using 32-bit Unix timestamps and start using
64-bit Unix timestamps. This change has already been made in some OSes, and
the problem will not repeat until the year 292,277,026,596, by which time it
is highly unlikely that either Unix timestamps or humankind itself will
still exist. Even if they will, that moment in time is so far out from the
present that I can't really be bothered by the possibility.

We have 19 years to take care of the problem before it happens. Hopefully
this time around we won't be trying to fix it right up until the last
minute.
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: Pythonic Y2K

2019-01-18 Thread Avi Gross
ould fail drastically at run time. Blue Screen of Death
type of fail. You had to save your work regularly. Languages like python
allow you to catch exceptions and deal intelligently with them to at least
close down gracefully or even recover. Heck, many programs depend on this
and instead of cluttering their code with lots of tests, wait for the error
to happen and adjust in the rare case it does.

So how reasonable would it be to still have lots of legacy software using
languages and programmers that have no easy ways to make their programs more
robust? How would such software react if it received information say in
UNICODE?

I predict that many people and companies have ignored warnings that the 2.X
train would someday be diverted to a dead-end track. It was always far
enough off in the future. But when a LAST DATE for updates is announced,
some may sit up and take notice. It may literally take something like
Insurance Companies (or the VC types) refusing to continue supporting them
if they do not change, to get them the hint. And, over time, many companies
do go under or are bought by another and often that will cause old projects
to go away or morph. 

But there is nothing fundamentally wrong with using 2.X. As I said jokingly,
if anyone wanted to keep it and support it as a DIFFERENT language than the
more modern python, fine. 

-Original Message-
From: Python-list  On
Behalf Of Michael Torrie
Sent: Friday, January 18, 2019 10:36 AM
To: [email protected]
Subject: Re: Pythonic Y2K

On 01/16/2019 12:02 PM, Avi Gross wrote:
> I recall the days before the year 2000 with the Y2K scare when people 
> worried that legacy software might stop working or do horrible things 
> once the clock turned. It may even have been scary enough for some 
> companies to rewrite key applications and even switch from languages like
COBOL.

Of course it wasn't just a scare.  The date rollover problem was very real.
It's interesting that now we call it the Y2K "scare" and since most things
came through that okay we often suppose that the people who were warning
about this impending problem were simply being alarmist and prophets of
doom.  We often deride them.  But the fact is, people did take these
prophets of doom seriously and there was a massive, even heroic effort, to
fix a lot of these critical backend systems so that disaster was avoided
(just barely).  I'm not talking about PCs rolling over to 00.  I'm talking
about banking software, mission critical control software.  It certainly was
scary enough for a lot of companies to spend a lot of money rewriting key
software.  The problem wasn't with COBOL necessarily.

In the end disaster was averted (rather narrowly) thanks to the hard work of
a lot of people, and thanks to the few people who were vocal in warning of
the impending issue.

That said, I'm not sure Python 2.7's impending EOL is comparable to the Y2K
crisis.
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: Pythonic Y2K

2019-01-18 Thread Avi Gross
Larry,

I keep hearing similar things about the Flu Vaccine. It only works 40% of
the time or whatever. But most of the people that get the flu get a
different strain they were not vaccinated against!

There are hundreds of strains out there and by protecting the herd against
just a few, others will flourish. So was it worth it?

Your argument would be that your work found lots of things related to Y2000
that could have been a problem and therefore never got a chance to show. I
wonder if anyone did a case study and found an organization that refused to
budge and changed nothing, not even other products that were changed like
the OS? If such organizations had zero problems, that would be interesting.
If they had problems and rapidly had their software changed or fixed, that
would be another and we could ask if the relative cost and consequence made
such an approach cheaper.

But in reality, I suspect that many of the vendors supplying products made
the change for all their clients. I bet Oracle might have offered some
combination of new and improved products to replace old ones or tools that
could be used to say read in a database in one format and write it out again
with wider date fields. 

The vast difference some allude to is realistic. Y2K swept the globe in
about 24 hours. No easy way to avoid it for many applications. Someone
running python 2.X on their own machines may be able to continue living in
their bubble for quite a while. If you sell or share a product with python
frozen into an app, it makes no difference. But asking some clients to
maintain multiple copies of python set up so one app keeps running as all
others use the newer one, may not remain a great solution indefinitely. 

Has anyone considered something that may be at the edges. How well do
cooperating programs work together? I mean if program one processes and
saves some data structures using something like pickle, and program two is
supposed to read the pickle back in and continue processing, then you may
get anomalies of many kinds if they use different pythons. Similarly,
processes that start up other scripts and communicate with them, may need to
start newer programs that use the 3.X or beyond version as no back-ported
version exists. The bubble may enlarge and may eventually burst.

-Original Message-
From: Python-list  On
Behalf Of Larry Martell
Sent: Friday, January 18, 2019 10:47 AM
To: Python 
Subject: Re: Pythonic Y2K

On Fri, Jan 18, 2019 at 10:43 AM Michael Torrie  wrote:
>
> On 01/16/2019 12:02 PM, Avi Gross wrote:
> > I recall the days before the year 2000 with the Y2K scare when 
> > people worried that legacy software might stop working or do 
> > horrible things once the clock turned. It may even have been scary 
> > enough for some companies to rewrite key applications and even switch
from languages like COBOL.
>
> Of course it wasn't just a scare.  The date rollover problem was very 
> real. It's interesting that now we call it the Y2K "scare" and since 
> most things came through that okay we often suppose that the people 
> who were warning about this impending problem were simply being 
> alarmist and prophets of doom.  We often deride them.  But the fact 
> is, people did take these prophets of doom seriously and there was a 
> massive, even heroic effort, to fix a lot of these critical backend 
> systems so that disaster was avoided (just barely).  I'm not talking 
> about PCs rolling over to 00.  I'm talking about banking software, 
> mission critical control software.  It certainly was scary enough for 
> a lot of companies to spend a lot of money rewriting key software.  
> The problem wasn't with COBOL necessarily.

I had one client, a hedge fund, that I fixed literally 1000's of Y2K issues
for. When Y2K came and there were no problems, the owner said to me "You
made such a big deal about the Y2K thing, and nothing happened."
--
https://mail.python.org/mailman/listinfo/python-list

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


checking protocols.

2019-01-19 Thread Avi Gross
Short question. Checking if a protocol is set up?

Many python improvements are changes to classes that implement a protocol.
There are things you can do to make your own classes work with the protocol
by setting various dunder variables like __iter__, __next__ and writing
appropriate ode including throwing the right error class when done.
Similarly the "with" statement works with objects that implement __enter__
and __exit__. There can be plenty of others like this and more can be
anticipated in the future.

So, several related questions. Tools that help a developer add appropriate
things to an object to implement the protocol or to test if it was done
right. Perhaps a function with a name like is_iterable() that tells if the
protocol can be applied. For the specific case of an iterable, I found
something that seems to work for at least some cases:

from collections import Iterable
item = [1, 2, 3, 4]

isinstance(item, Iterable)

Not sure if it would work on one I created that did the right things or what
it checks.

I am interested in a pointer to something that describes many of the known
protocols or extensions and maybe to modules designed sort of as I said
above. I am aware some protocols may be not-quite standard with parts of the
protocol embedded in different objects like wrappers or objects returned
upon a request to have a proxy and many other techniques that seem to abound
and allow multiple layers of indirection or seemingly almost magical as in
multiple inheritance drop-ins and so on. That is what may make these things
harder if someone uses something like __getattr__ or descriptors to
intercept calls and provide the functionality without any actual sign of the
dunder key normally expected.

And, yes, I am aware of a tried and true method called try ... except ... to
see if it seems to work.


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


RE: checking protocols.

2019-01-23 Thread Avi Gross
See reply BELOW in sections marked by ==:

-Original Message-
From: DL Neil  
Sent: Wednesday, January 23, 2019 7:39 PM
To: Avi Gross ; [email protected]
Subject: Re: checking protocols.

Avi

Haven't noticed an answer to this. Did I miss anything?

==REPLY ON non-TOP as requested on 1/23/2019
Dave,

I never saw the original message appear and thus expected no replies. I see a 
later post by Chris indicating he did not see it either. I assumed perhaps a 
moderator needed to approve it.

My question really boils down to being intrigued how the python language can be 
extended using documented protocols in more ways and having a place where you 
can see a list of the ones out there and a way to join in with your own classes 
reliably and so on.

I note there may be many unpublished protocols used internally within modules 
that also create similar structures but do not expect to be emulated.

I see interpolated comments below and will interpolate within that but it gets 
confusing.
==END first set of remarks on 1/23/2019
==ORIGINAL MESSAGE BELOW if anyone wants to see in-line comments and 
supply info.===

On 20/01/19 11:07 AM, Avi Gross wrote:
> Short question. Checking if a protocol is set up?

=do you mean that to check/require that a class exhibits a particular protocol 
we should use abstract classes - will not instantiate unless all the required 
components are coded?

== I am not looking for any specific options but indeed including an 
abstract class might be one way to go. It might supply a reasonable way to ask 
if the class you make yourself INTENDS on running that protocol and would 
enforce the presence of the required methods somewhere in the inheritance 
chain. Of course the functions could be stubs that don't do the right thing, or 
anything passable.


> Many python improvements are changes to classes that implement a protocol.
> There are things you can do to make your own classes work with the 
> protocol by setting various dunder variables like __iter__, __next__ 
> and writing appropriate ode including throwing the right error class when 
> done.
> Similarly the "with" statement works with objects that implement 
> __enter__ and __exit__. There can be plenty of others like this and 
> more can be anticipated in the future.
> 
> So, several related questions. Tools that help a developer add 
> appropriate things to an object to implement the protocol or to test 
> if it was done right. Perhaps a function with a name like 
> is_iterable() that tells if the protocol can be applied. For the 
> specific case of an iterable, I found something that seems to work for at 
> least some cases:
> 
> from collections import Iterable
> item = [1, 2, 3, 4]
> 
> isinstance(item, Iterable)
> 
> Not sure if it would work on one I created that did the right things 
> or what it checks.

=your code should be 'approved' if it implements the next() method, etc. 
Did you try such?

==Just to be clear, yes. That is the current state of affairs. ANY CODE 
can be run but probably fails when it does not follow the recipe. Any of many 
places that expect the iteration protocol will ask for a __iter__ and either 
catch the error or fail. If it works, they will call __next__ as often as 
needed and may or may not fail well if it is not found. And, as noted, the 
function may throw the right error object on completion or not and that may 
cause the caller to fail mysteriously or be bypassed if some other error is 
thrown instead. What I am hoping for is OPEN to multiple solutions or to be 
told there is no such need. One solution would be something that can be used to 
exercise the function and report if the protocol is being honored. In this 
case, that is fairly trivial. Just try the object in one of many places the 
iterator protocol is used. It may be less clear how you check if the 'with' 
protocol is satisfied as it may not properly close whatever it is guarding like
  closing a file or freeing a lock. If you test that you may not notice the 
file remains open and so on. But will your code also work if the user closed 
the file already on purpose?


> I am interested in a pointer to something that describes many of the 
> known protocols or extensions and maybe to modules designed sort of as 
> I said above. I am aware some protocols may be not-quite standard with 
> parts of the protocol embedded in different objects like wrappers or 
> objects returned upon a request to have a proxy and many other 
> techniques that seem to abound and allow multiple layers of 
> indirection or seemingly almost magical as in multiple inheritance 
> drop-ins and so on. That is what may make these things harder if 
> someone uses something like __getattr__ or descriptors to intercept 
> calls 

meta protocol protocol

2019-01-28 Thread Avi Gross
I brought up a topic earlier and am now taking a different slant.

 

I am thinking of the wisdom of having a protocol on announcing what
protocols you implement.

 

Python has many protocols that are now part of the language and I suspect
many more will arise. Python already has a series of variables stored in
classes or instances that store lists or dictionaries of THINGS and I won't
mention them in details as they are numerous and often mysterious. 

 

So I wondered what people thought of the general idea of adding one more
with some name like __PROTOCOLS__ that could be stored at something like the
class level.

 

Here are  examples of one person listing what they consider protocols:

 

https://ref.readthedocs.io/en/latest/understanding_python/interfaces/existin
g_protocols.html

https://stephensugden.com/crash_into_python/Protocols.html

 

When an object implements a protocol such as being callable, that generally
means they provide a method in the name __call__ which is simple enough to
check for if you know where to look. But the sequence protocol may require
quite a few such methods to be fully implemented and testing for dunders
len, getitem, setitem, delitem, reversed, contains, getslice, setslice, and
delslice may be a bit much.

 

So what if the powers that be that determine the fate of python come up with
a meta protocol. All protocols would be given a NAME for official purposes.
The two examples might become "callable" and "sequence" and the meaning of
saying you properly provide a protocol would be well documented.

 

So if someone creates an object, part of the process might be to add entries
for each protocol you declare you properly support to something like the
__PROTOCOLS__ variable. How to do so is an implementation decision but it
could be as easy as adding a method to the top class "object" than any
subclass can inherit and use to declare one or more protocols in use. You
might also add another method like has_protocol(name) that returns True if
it is registered.

 

As a programmer, you might no longer need to know the details to see if
something is in some category. Rather than checking for the presence of
various dunderheads, you simply ask if a protocol is implemented and then
use it.

 

I am not sure anything like this is wanted or practical and am asking if
people have already suggested something along these lines or whether it
would even be something worth doing or practical.

 

I can think of many complications starting with what happens if someone lies
and continuing with what happens if a class inherits from multiple other
classes but some methods are over-ridden or no longer the first one found in
the MRO search.

 

Of course, it would also be nice if there was also a tool that could be used
by developers to validate claims to implement a protocol before run-time
either in a shallow way (the right names are defined) or a deeper way by
exercising the functionality to see it does what is expected. That, too,
leads to me wondering how this could work as the above reference suggests
the copy protocol contains both a __copy__() and a __deepcopy__() and I can
imagine having just the first.

 

When I say PROTOCOL, I mean it in a very broad sense. For example, what
makes an object type IMMUTABLE? What makes the contents of an object
INVISIBLE as in you use techniques so the only way to gain access to the
hidden internals of an object is through various kinds of proxies that keep
you from actually seeing what is going on. Such aspects may not have an
exact protocol but if you want to use something as a key in a dictionary
maybe it will be happy to allow it if it thinks you are of an immutable
type. Other functionality may refuse to work with objects not deemed
invisible for privacy concerns.

 

Again. Not a serious proposal just wondering if my thought process is flawed
deeply or am I just shallow.

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


The power of three, sort of

2019-01-29 Thread Avi Gross
I have chosen to stay out of the discussion as it clearly was a TEACHING
example where giving an ANSWER is not the point.

 

So I would like to add some thought without a detailed answer for the boring
way some are trying to steer an answer for. They are probably right that the
instructor wants the students to learn that way.

 

My understanding is the lesson was in how to use the IF command on exactly
three numbers to get the maximum, or perhaps both the maximum and minimum.

 

If this was not for school but the real world, the trivial answer would be
to use max() or min() or perhaps a minmax() that returns a tuple. Or, you
could sort() and choose the first and/or last. 

 

All the above are easy and expand well to any number of N items.

 

My second thought was to do it in one of several standard methods with
nested IF/ELSE statements perhaps using an ELIF. It would produce six (or
perhaps more)  branches and each of them would set any of  a/b/c to be the
maximum. A second complete set would invert some of the > or >= symbols to
get the minimum.

 

But that seems quite long and complicated and I will not show it as we keep
waiting for the student to solve it and then show it so any other students
could copy it!

 

Since there are 3! Possible combinations (albeit if some numbers are the
same, sort of less) a brute force method seems preferable as in:

 

if (a >= b >= c): max = a

.

if (c >= b >= a): max = c

 

That seems wasteful in so many ways and can be shortened perhaps to:

 

if (a >= b >= c): max = a

elif (b >= a >= c): max = b

.

else: max = c

 

Again, six known combinations and fewer tests on average.

 

Another variation is arguably even easier to think about.

 

max, min = float('-inf'), float('inf')

if a > max: max = a

.

if c > max: max = c

# repeat for min using <

 

No nesting and I assume within the allowed rules.

 

The latter makes you wonder about using the one (perhaps two or three) line
version:

 

a, b, c = int(input("first: ")), int(input("second: ")),
int(input("last: "))

max = a if (a>=b and a>=c) else (b if (b>=a and b>=c) else c)

print("max = %d" % max)

 

Again, fairly simple but using a ternary and nested version of if.

 

Results:

 

first: 5

second: 10

last: 7

max = 10

 

first: 5

second: 10

last: 10

max = 10

 

Not saying this is a charmed version using the power of three but I wonder
what kind of answers the instructor expects. I mean you can trivially write
more versions including iterative ones where you unpack the input into a
tuple or list and iterate on it or where you use a function for recursion or
create an object you keep adding to that maintains the biggest so far and on
and on. You can even do calculations after the first two inputs and then use
that to compare after the third input. There is no one right answer even for
simplified methods.

 

If I get to teach this, I probably would not tell them there are many ways
but might give extra credit for those who innovate or make it somewhat more
efficient looking but perhaps penalize solutions that others might not
easily understand.

 

Ending comment. Every use of the ellipsis above should not be typed in and
represent missing lines that need to be added but are not being specified.
The one liner does work and there are more nested variations of that you can
use. My thoughts apply well beyond this simple example to the question of
how you define a problem so that people use only what they know so far and
are taught how to use it even if they may not ever actually need to use it
again.

 

 

 

 

 

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


RE: what considerations for changing height of replacement radiator?

2019-01-30 Thread Avi Gross
I disagree, politely, Chris. The request is too BASIC and Radiator is best
done in R. I note especially how it has support for heat maps. 

But as with Python, I recommend a recent version of 3.X, and at least
version 3.3.3 that came out in March 2017.

As for the python 2.7 radiator, it works better if it is a new style class
radiating  from base class object.


-Original Message-
From: Python-list  On
Behalf Of Chris Angelico
Sent: Wednesday, January 30, 2019 6:37 PM
To: Python 
Subject: Re: what considerations for changing height of replacement
radiator?

On Thu, Jan 31, 2019 at 10:11 AM jkn  wrote:
>
> Hi all
> I'm looking at changing a radiator in a bedroom shortly and 
> wondering about my options re. sizing.

No problems!

A Python 2.7 radiator is sometimes smaller than a Python 3.5+ radiator, but
the newer model of radiator has a number of advantageous features. For
example, you can seamlessly use temperatures in Arabic or Russian as well as
English, and you can track your energy usage using the 'statistics' module.

Or possibly this email was sent to the wrong list :)

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

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


RE: How to replace space in a string with \n

2019-01-31 Thread Avi Gross
It is amazing to watch what happens when a fairly simple question is asked
to see how people answer.

In an effort not to ramble, I will summarize my thoughts. The student wanted
to know how to solve a problem using only what they already should know and
that specifically they should not use a method. In effect, they are being
asked to write the kind of code that might be used to make such a method.

There were many answers including some that absurdly suggested even more
advanced methods they should not know. Frankly, the question belongs more in
the sister list for tutoring and even there, the goal is NOT to supply an
answer but point out flaws in code provided as an attempt or suggest an
outline of a method and let the student fill it out and learn.

This is not only a public forum but one that is searchable indefinitely into
the future. Providing a full-blown answer not only hands a solution to one
student but to their classmates and any future takers.

I note another poster asking questions turns out to be not a student but
someone quite advanced who likes to learn just in time as they search for
what is needed. They require a very different approach and can learn well
from being handed a more detailed solution they can interpolate into their
project. 

So, how do you replace? I think a loop answer is probably best for this
student. For the second type of questioner, many of the others would be
great including suggesting they just use replace as there is nothing wrong
with that!

NOTE: It is great when we have an exact set of requirements. I note that the
requirement here might not require making a new string at all. If you just
need to PRINT the words on multiple lines, one solution is to call "print"
on each character in the loop using the appropriate method to suppress
printing a newline except when you see a blank.


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


Bringing Order to programming

2019-01-31 Thread Avi Gross
The discussion moved on to debating if an algorithm is O(N) or O(N**2).

For small amounts of text, on fast machines, it really is not worth worrying
about the cost of appending to the end of a growing string resulting in
multiple copies and lots of garbage collection. Many computer textbooks love
to tell you that nothing should be modifiable as a paradigm and endless
copying is good for you since you never change existing data so fewer
mistakes ...

But, for any programmers that happily want to read in entire books and for
some reason then replace all spaces with newlines, may I suggest the
following.

Convert your "text" to/from a list of individual characters. Copy the
non-space characters to the end of an empty list and append a newline when
you see a space. This part should be O(N) as lists have a fast way to append
in constant time. At the end, use str(listname) to do what is needed to get
back a string. Also O(N).

I won't supply the code for obvious reasons but it looks like:

final_list = []
for character in initial_text:
# Add carefully to the end of final_list
final_text = str(final_list)

The second variant is to use the newer bytearray data structure very
carefully as it is to a first approximation a mutable string. Adding to the
end of a new one should be quick. WARNING: I said be careful. A bytearray is
more like a list of 8-bit ints. With care you can handle ASCII text. 





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


RE: Implement C's Switch in Python 3

2019-02-02 Thread Avi Gross
I may be missing something, but the focus seems to be only on the rightmost
digit. You can get that with


str(day)[-1]
or with
day % 10

Problem: print 1..31 using suffixes such as 1st, 2nd, 3rd, 4th ...

So your dictionary needs entries for "1" or 1 and "2" or "2" and of course 3
becoming 3rd.

And, frankly, you don't even need a dictionary as a one-liner will do.

Here is an example using a helper function:

""" Use last digit to determine suffix """

def nthSuffix(day):
nth = day % 10
suffix = "st" if nth == 1 else ("nd" if nth == 2 else ("rd" if nth == 3
else "th"))
return str(day) + suffix


Output:

>>> for day in range(1, 32):
print( nthSuffix(day))

1st
2nd
3rd
4th
5th
6th
7th
8th
9th
10th
11st
12nd
13rd
14th
15th
16th
17th
18th
19th
20th
21st
22nd
23rd
24th
25th
26th
27th
28th
29th
30th
31st

-Original Message-
From: Python-list  On
Behalf Of Sayth Renshaw
Sent: Saturday, February 2, 2019 8:53 PM
To: [email protected]
Subject: Re: Implement C's Switch in Python 3


> >I am trying to convert a switch statement from C into Python. (why? 
> >practising).
> >
> >This is the C code.
> >
> >printf("Dated this %d", day);
> >  switch (day) {
> >case 1: case 21: case 31:
> >printf("st"); break;
> >case 2: case 22:
> >printf("nd"); break;
> >case 3: case 23:
> >printf("rd"); break;
> >default: printf("th"); break;
> >
> >  }
> >  printf(" day of ");
> >
> >#Premise if the use enter an int as the date 21 for example it would
print 21st. It appends the correct suffix onto a date.
> >Reading and trying to implement a function that uses a dictionary. 
> >Not sure how to supply list into it to keep it brief and with default 
> >case of 'th'.
> >
> >This is my current code.
> >
> >def f(x):
> >return {
> >[1, 21, 31]: "st",
> >[2, 22]: "nd",
> >[3, 23]: "rd",
> >}.get(x, "th")
> >
> >
> >print(f(21))
> >
> >I have an unhashable type list. Whats the best way to go?
> 
> Skip has commented on lists being unhashable. We can elaborate on that 
> if you like.
> 
> However, even if you went to tuples (which would let you construct the 
> dict you lay out above), there is another problem.
> 
> You're looking up "x" in the dict. But the keys of the dict are not 
> integers, they are lists (or tuples) or integers, so they won't match.
> 
> You _could_ do this:
> 
>   return {
> 1: "st", 21: "st", 31: "st",
> 2: "nd", 22: "nd",
> 3: "rd", 23: "rd",
>   }.get(x, "th")
> 
> which makes distinct entries for each integer value of interest.
> 
> The conventional approach would normally be:
> 
>   if x in (1, 21, 31):
> return "st"
>   if x in (2, 22):
> return "nd"
>   if x in (3, 23):
> return "rd"
>   return "th"
> 
> While this works for a small number of choices, if you had a huge dict 
> with lots of possible values you could return to your 
> dict-keyed-on-tuples approach. You would need to try each tuple in turn:
> 
>   mapping = {
> (1, 21, 31): "st",
> (2, 22): "nd",
> (3, 23): "rd",
>   }
>   for key, suffix in mapping.items():
> if x in key:
>   return suffix
>   return "th"
> 
> However, for big dictionaries (with many keys) you loose a key 
> strength of dicts: constant time lookup. You can see the above code 
> (and the earlier "if" code) are rather linear, with run time going up 
> linearly with the number of keys. You're better with the int->string 
> single value dict version.
> 
> Cheers,
> Cameron Simpson

It seems odd with C having switch that its cleaner and more efficient than
python where we are having to implement our own functions to recreate switch
everytime.

Or perhaps use a 3rd party library like
https://github.com/mikeckennedy/python-switch

You have both given good options, it seems there are no standard approaches
in this case.

Cheers

Sayth

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

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


RE: Implement C's Switch in Python 3

2019-02-02 Thread Avi Gross
Yes, you caught the usual flaw in the often irregular English language.

The 11th, 12th and 13th do all begin with 1 so there is a simple fix in the
function version by checking if day//10 is 1.

Revised example:

""" Use last digit to determine suffix handling teens well """

def nthSuffix(day):
if (day // 10 == 1):
suffix = "th"
else:
nth = day % 10
suffix = "st" if nth == 1 else ("nd" if nth == 2 else ("rd" if nth
== 3 else "th"))

return str(day) + suffix

>>> [ nthSuffix(day) for day in range(1,32)]
['1st', '2nd', '3rd', '4th', '5th', '6th', '7th', '8th', '9th', '10th',
'11th', '12th', '13th', '14th', '15th', '16th', '17th', '18th', '19th',
'20th', '21st', '22nd', '23rd', '24th', '25th', '26th', '27th', '28th',
'29th', '30th', '31st']

Want a dictionary version? Use the above to make a full dictionary:

>>> chooseFrom = { day : nthSuffix(day) for day in range(1,32)}
>>> chooseFrom
{1: '1st', 2: '2nd', 3: '3rd', 4: '4th', 5: '5th', 6: '6th', 7: '7th', 8:
'8th', 9: '9th', 10: '10th', 11: '11th', 12: '12th', 13: '13th', 14: '14th',
15: '15th', 16: '16th', 17: '17th', 18: '18th', 19: '19th', 20: '20th', 21:
'21st', 22: '22nd', 23: '23rd', 24: '24th', 25: '25th', 26: '26th', 27:
'27th', 28: '28th', 29: '29th', 30: '30th', 31: '31st'}
>>> chooseFrom[1]
'1st'
>>> chooseFrom[11]
'11th'
>>> chooseFrom[21]
'21st'


-Original Message-
From: Python-list  On
Behalf Of MRAB
Sent: Saturday, February 2, 2019 10:06 PM
To: [email protected]
Subject: Re: Implement C's Switch in Python 3

On 2019-02-03 02:51, Avi Gross wrote:
> I may be missing something, but the focus seems to be only on the 
> rightmost digit. You can get that with
> 
I had the same thought, but came across a problem. "11st", "12nd", "13rd"?

[snip]
> 
> Output:
> 
>>>> for day in range(1, 32):
>   print( nthSuffix(day))
>   
> 1st
> 2nd
> 3rd
> 4th
> 5th
> 6th
> 7th
> 8th
> 9th
> 10th
> 11st
> 12nd
> 13rd
> 14th
> 15th
> 16th
> 17th
> 18th
> 19th
> 20th
> 21st
> 22nd
> 23rd
> 24th
> 25th
> 26th
> 27th
> 28th
> 29th
> 30th
> 31st
> 
[snip]
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: Implement C's Switch in Python 3

2019-02-03 Thread Avi Gross
The discussion strictly sets a limit of 31 for the largest number of days in
a month and asks for suffixes used to make ordinal numbers like 31st.

But in reality, you can go to 99th and beyond for other purposes albeit the
pattern for making 101 and on seems to repeat.

The last algorithm I wrote would work up to 99 in terms of the function I
wrote. To make it work higher, you would simply start by taking the original
number mod 100 before continuing and then use the original number at the
end.

But if the goal is to make a list or dictionary out of it, it gets a tad
large for the 8423rd and not manageable too far above.

If you will be using whatever technique just once, precomputing a list or
dict is extra effort. For MANY uses in the same program, it makes sense to
make a more static data structure with rapid access.

So what if you only compile lower numbers into the structure but call the
function version for higher ones?



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


Switch function

2019-02-03 Thread Avi Gross
Message asking about a fairly simple way to implement a switch in python as
per the ongoing discussion.

 

I wrote a function that might emulate a fairly simple general use of switch.

 

A function would take N+2 arguments of the form:

1: something to switch based on

2,3: something to match to the first and if matched, return the second.

4,5: another pair of match and response

.

N: an OPTIONAL singleton to serve as a default.

 

The function will be shown next but in English, it accepts the one to search
for and pairs of key/value to compare and if matched return. As soon as
anything matches, return it. If all matches fail and if there is one
argument left, return that. Else, return None.

 

Now this should work well only with relatively fixed objects that are
evaluated whether used or not. Again, just a suggestion to discuss, not
necessarily something to implement although this seems trivial enough that
something like it is likely out there.

 

def switcheroo(*args):

theOne, *rest = args

 

while len(rest) > 1:

matching, returning, *rest = rest

if theOne == matching:

return returning

if rest: # default

return rest[0]

else:

return None

 

I used python 3.7.1 so note the *rest notation may not work on very old
versions. You can use other methods like popping off a list though.

 

Now for the specific case of days 1:31, here is how you can call it:

 

>>> switcheroo(3,

   1, "st",

   2, "nd",

   3, "rd",

   21, "st",

   31, "st",

   22, "nd",

   23, "rd",

   "th" )



'rd'

 

With no default, you get an invisible None.

 

Since normal people don't like to type that way, here is how you might use
it.

 

>>> pairs =  [1,"st", 2,"nd", 3,"rd", 21,"st", 31,"st", 22,"nd",
22,"nd", 23,"rd"]



>>> switcheroo(2, *pairs, "th")



'nd'

>>> switcheroo(5, *pairs, "th")



'th'

 

You can make many variations on this theme including using dictionaries and
the **kwargs notation, or moving the default up near the front and having a
None placeholder. As far as I know, nothing stops the things being matched
or returned from being objects of any kind or functions.

 

Final note. I repeat. This method has all arguments evaluated before the
function is called even if they are not the ones being matched. There is no
delayed lazy evaluation as in R. See the following examples:

 

>>> switcheroo(1, -int((math.e**(math.pi*complex(0,1))).real), "st",

   2, "nd",

   1+2, "rd",

   21, "st",

   31, "st",

   2*11, "nd",

   23, "rd",

   "th"

   )



'st'

>>> switcheroo(23, -int((math.e**(math.pi*complex(0,1))).real), "st",

   2, "nd",

   1+2, "rd",

   21, "st",

   31, "st",

   2*11, "nd",

   23, "rd",

   "th"

   )



'rd'

 

Bottom line, does anyone bother using anything like this? It is actually a
bunch of hidden IF statements matched in order but may meet many needs.

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


RE: Implement C's Switch in Python 3

2019-02-03 Thread Avi Gross
Comment at end:

-Original Message-
From: Python-list  On 
Behalf Of Bob van der Poel
Sent: Sunday, February 3, 2019 4:01 PM
To: DL Neil 
Cc: Python 
Subject: Re: Implement C's Switch in Python 3



I'm surprised that no one has yet addressed the year 1 problem.
Hopefully we're doing numeric, not alpha sorts on the stuff before the 1st '-'. 
And, the compact versions will really screw up :).

[[The obvious solution is to list all dates in the sortable format like this 
for January 2nd, 2020:

0Q20200102

Without the 0Q we might just assume it was written in base 3, or trinary.

OK, turning sarcasm mode off.

It is very bad form to have ambiguous compressed formats. Even if you include a 
slash or minus sign or period or the delimiter of your choice, I sometimes see 
this:

01/02/2020

And I wonder if it is meant to be January 2nd or February 1st.

Clearly 30/01/2020 cannot be the 30th month so it must be an alternate format. 
And, years from now, we may get a year that might confuse us more if compressed 
like:

21121221

Is that 2112 as the year an Dec 21? 

In the interest of clarity,  how is this different than including a time zone 
alongside a time value? Maybe '0Q" is silly, but a prefix or suffix or even a 
new delimiter might be a good idea. Are any available?

2020|12|02 ???

The end]]


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


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: Switch function

2019-02-03 Thread Avi Gross
Dan,

I agree and have felt no need to do a method like this. Most of the time a
switch is easy to avoid or even forget that it exists.  I rarely needed to
use these years ago when they were available in C and C++ , JAVA,
JavaScript, PERL  or R or under  other *names* but similar functionality
like COND in versions of LISP or CASE in PASCAL.

The times I would use it would not be when were a relatively few cases. It
makes more sense for example when you are accepting a one-character command
in the very old style from the user. I repeat, OLD style. Your main loop may
largely consist of a switch statement where every possible keystroke calls
one of a set of functions. I mean things like D is for Delete and I is for
insert and A is for Append and Q is for QUIT and some are absolutely not
mnemonic like V is for Paste.

I have read books that suggest having a long function is a sign of clutter
or even insanity and I feel that is not realistic in many cases. 

The example I show above could in many cases be done as you describe but
what are you gaining?

I mean if I subtract the integer representation of a keyboard alphabetic
letter (ASCII for the example) from letter 'a' or 'A' then A maps to 0 and B
maps to 1 and ...  Z maps to 26. So, you could make a list of 26 functions
(some may be absent) and your entire switch statement looks like:

funcs=[zeroeth,first,other,...,last] # list of function handles
var=input("Enter a Command: ")
if ord('A') <= ord(var[0]) <= ord('Z'):
result = funcs[ord(var[0]) - ord('A')]()

Is that short enough?

Mind you, that is not the same as a switch statement form that allows
arbitrary code after each choice and lets you access variables at that level
and change them, as well as call functions with specific arguments that make
sense at that time. Yes, judicious use of the global or nonlocal statement
can dangerously get you some of that functionality.

A reasonable goal might be to have the code at each case be relatively
brief. Maybe a few lines adjusting local variables then calling a function
that lets more code be elsewhere by passing in additional things needed in
that context or passing in mutable arguments. The indentation should make it
reasonable to follow as if you are looking at N different functions where
each one is not too large even if it is all in one large switch.

Now this sounds quite a bit like the dictionary trick but note many of the
above languages do not have a built-in dictionary concept and some may not
support lists of functions or objects. I have seen monstrosities like this:

functionTop is:
If var == 'A':
# do something
else:
functionB(var)

Guess what functionB says?

Yep, if it is 'B" do something else call functionC.

So a mere 26 functions, each short and stacked. Ugh!

It may be a matter of taste and I have seen places such as statistical
calculations where such an approach is even needed. In very brief, some
tests require a choice of TWO so one choice is A versus non-A and then you
do something with the non-A that are B versus non-B.

Your comment about object polymorphism is interesting. I am picturing how
each choice somehow delivers an object that automatically is set up to do
the right thing.

Having said that, I realize how there is something in python quite similar
to a case statement!

Picture my example where you have a try statement that raises at least 26
error objects followed by up to 26 catch statements:

try:
something that raises a designer exception
catch errorA as var: pass
catch errorb, errorB: pass
...
catch errorZ: pass

That looks like a switch in many ways and lets you combine multiple choices
into one case. Heck, there is also a finally and else clause you can use for
fine tuning as in setting a default.

Again, see how can you write a COMPLICATED try command that captures many
things including real errors?

I know I keep repeating this but experience tells me that if not mentioned,
someone will make believe I meant something other than what I say. The above
is NOT a suggestion of what to do. It is an example of another feature that
IS in the language that in some ways is much like the switch statement. Not
always a good idea to abuse it when it can be done with IF variants or a
dict jump or many other gimmicks.

In the above the  *raise* statement within whatever you try can do the same
trick as before and create a small integer offset from letter 'A' to use in
making a slightly different object for each case in one of many ways. I will
stop here.


-Original Message-
From: Python-list  On
Behalf Of Dan Sommers
Sent: Sunday, February 3, 2019 8:29 PM
To: [email protected]
Subject: Re: Switch function

On 2/3/19 5:40 PM, Avi Gross wrote:

> Bottom line, does anyone bother u

RE: pandas read dataframe and sum all value same month and year

2019-02-04 Thread Avi Gross
Diego,

If your goal is to sum data by month, there are more general methods than
you making lists of starting and ending dates.

ONE way to consider in your case that is easy to understand is to add a
derived column/feature to your data such as the first 7 characters of the
date as perhaps a routine string. I mean 

2012-01-01 06:00

Becomes:

"2012-01"

Once you have such a column, you can aggregate your data by that column
using functionality in pandas and it will be done for all items with that
field being the same. 

The extra column can be temporary and there are other ways but it is
conceptually simple.

Of course to do the above does involve lots of details and you don't seem to
need it now, so I am leaving this as an academic hint. 

-Original Message-
From: Python-list  On
Behalf Of Diego Avesani
Sent: Monday, February 4, 2019 2:38 PM
To: [email protected]
Subject: Re: pandas read dataframe and sum all value same month and year

Deal all,
following Peter's suggestion,

I put the example code:

import pandas as pd
import numpy as np
from datetime import datetime


#input:
start_date = np.array(["2012-01-01 06:00",'2013-01-01 06:00','2014-01-01
06:00'])
end_date   = np.array(["2013-01-01 05:00",'2014-01-01 05:00','2015-01-01
05:00'])
yearfolder = np.array(['2012','2013','2014'])


for ii in range(0, 1):
   df =
pd.read_csv('dati.csv',delimiter=',',header=0,parse_dates=True,na_values=-99
9)
   df['datatime'] = df['datatime'].map(lambda x: datetime.strptime(str(x),
"%Y-%m-%d %H:%M"))
   mask = (df['datatime'] > str(start_date[ii])) & (df['datatime'] <=
str(end_date[ii]))
   df = df.loc[mask]
   df = df.reset_index(drop=True)
   #
   df.groupby(pd.TimeGrouper('m')).sum()


and the example of file:

datatime,T,RH,PSFC,DIR,VEL10,PREC,RAD,CC,FOG
2012-01-01 06:00,  0.4,100, 911,321,  2.5,  0.0,   0,  0,0
2012-01-01 07:00,  0.8,100, 911,198,  0.8,  0.0,   0, 22,0
2012-01-01 08:00,  0.6,100, 912, 44,  1.2,  0.0,  30, 22,0
2012-01-01 09:00,  3.1, 76, 912, 22,  0.8,  0.0, 134, 44,0
2012-01-01 10:00,  3.4, 77, 912, 37,  0.5,  0.0, 191, 67,0
2012-01-01 11:00,  3.5,100, 912,349,  0.4,  0.0, 277, 44,0
2012-01-01 12:00,  3.6,100, 912, 17,  0.9,  0.0, 292, 22,0
2012-01-01 13:00,  3.5,100, 912, 28,  0.3,  0.0, 219, 44,0
2012-01-01 14:00,  3.3, 68, 912, 42,  0.5,  0.0, 151, 22,0



Hope this could help in finding a way to sum value belonging to the same
month.

Thanks again, a lot

Diego





On Monday, 4 February 2019 15:50:52 UTC+1, Diego Avesani  wrote:
> Dear all,
> 
> I am reading the following data-frame:
> 
> datatime,T,RH,PSFC,DIR,VEL10,PREC,RAD,CC,FOG
> 2012-01-01 06:00, -0.1,100, 815,313,  2.6,  0.0,   0,  0,0
> 2012-01-01 07:00, -1.2, 93, 814,314,  4.8,  0.0,   0,  0,0
> 2012-01-01 08:00,  1.7, 68, 815,308,  7.5,  0.0,  41, 11,0
> 2012-01-01 09:00,  2.4, 65, 815,308,  7.4,  0.0, 150, 33,0
> 2012-01-01 10:00,  3.0, 64, 816,305,  8.4,  0.0, 170, 44,0
> 2012-01-01 11:00,  2.6, 65, 816,303,  6.3,  0.0, 321, 22,0
> 2012-01-01 12:00,  2.0, 72, 816,278,  1.3,  0.0, 227, 22,0
> 2012-01-01 13:00, -0.0, 72, 816,124,  0.1,  0.0, 169, 22,0
> 2012-01-01 14:00, -0.1, 68, 816,331,  1.4,  0.0, 139, 33,0
> 2012-01-01 15:00, -4.0, 85, 816,170,  0.6,  0.0,  49,  0,0 
> 
> 
> I read the data frame as:
> 
>  df =
pd.read_csv('dati.csv',delimiter=',',header=0,parse_dates=True,na_values=-99
9)
>df['datatime'] = df['datatime'].map(lambda x: datetime.strptime(str(x),
"%Y-%m-%d %H:%M"))
>#
>mask = (df['datatime'] > str(start_date[ii])) & (df['datatime'] <=
str(end_date[ii]))
>df = df.loc[mask]
>df = df.reset_index(drop=True)
> 
> I would to create an array with the sum of all the PREC value in the same
month.
> 
> I have tried with:
> 
> df.groupby(pd.TimeGrouper('M')).sum()
> 
> But as always, it seems that I have same problems with the indexes.
Indeed, I get:
>   'an instance of %r' % type(ax).__name__)
> TypeError: axis must be a DatetimeIndex, but got an instance of
'Int64Index'
> 
> thanks for any kind of help,
> Really Really thanks
> 
> Diego

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

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


RE: Loop with else clause

2019-02-05 Thread Avi Gross
The topic is how to deal with a python loop that may not be run if you want
something else to happen in that case. Multiple solutions are presented
along with this request:

> Is there another, more pythonic, approach to conditional (for/while) 
> loop processing?

Has anyone considered looking at this from the perspective of the CONDITION
being evaluated?

If the condition is something simple like is the "list" empty, then any
method will work as it can be evaluated before trying the loop with no side
effects.

But what if the item in question is complex and constructed dynamically as
by zipping things together or calling functions and might even produce side
effects? It might be far from trivial to do that before the loop and check
and you might inadvertently change things. Using a sentinel approach might
be safer.

And what about loops that start but exit immediately without doing anything?
If you iterate on something whose first value is wrong in some way and the
loop starts with an "if ... break" then do you want to do the ELSE condition
because the loop sort of did not run as anticipated? A similar example is if
the loop starts with a "try" and the error handler does a break. 
 


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


RE: The slash "/" as used in the documentation

2019-02-10 Thread Avi Gross
Chris,

I would appreciate another pointer to the documentation explaining what was
done and why as I deleted the earlier discussion.

You ask:

> Aside from questions about the help format, what is actually lost by the
inability 
> to pass those arguments by name?

I am not sure how python implements some of the functionality it does as
compared to other languages with similar features. But I note that there are
rules, presumably some for efficiency, such as requiring all keyword
arguments to be placed after the last positional argument. I mean I can call
func(a,b,c,d=1,e=2) but not func(a,b,d=1, c, e=2).

So if you allowed a keyword to optionally be used for any positional
argument other than the last, c, would it not require a change in this rule?
I mean func(a="invalid",b,c,d=1,e=2) would violate the rule and so would
making b a keyword version. In my example, and for this reason only, maybe c
could work.

And note the impact IF ALLOWED on the existing and new programs that allow a
variable number of arguments of the form func(*args, **kwargs) when they
evaluate. The previous model was that args would be a sequence of the
arguments you could index so args[0] would be the first, or that you can pop
off the front and use. If any of the previously un-named arguments can now
entered with a keyword, are they now placed in args or in the dictionary
kwargs? If in kwargs, the program now needs to know to look there in
addition to the command line. If it was the first argument and is no longer
in args, the second and further arguments would either be shifted over and
be used wrong or you need a placeholder.

The original motivation for keyword arguments included the concept of
specifying a default if not used. Positional arguments have no default.
Similarly, they are required if explicitly named in the function definition.
So we are intermingling multiple concepts in the previous design.

I won't go on except to say it would break lots of existing code and
potentially complicate new code.

Let me add a dumb suggestion. Anyone who desperately wants to name the
parameters has a rather strange option they can do now. Very imperfect but
consider the function prototype I have been using for illustration:

func(a,b,c,d=1,e=2)

It requires three positional arguments. What if you implement your code so
some special values mean that you are going to pass along "a" as "key_a"
instead. You can use something like None or the ellipsis(...) to signal this
as in:

def func(a, b, c, d=1, e=2, key_a=None):
if a == ... :
a = key_a
print(a)

The above does nothing but illustrates a WAY to allow a keyword
implementation by using one or more placeholders as you can do the same
gimmick for b and c.

Here is how it runs if you use the positional arg, or an ellipsis and then a
keyword or an ellipsis and accept the default for the keyword:

>>> func(1,2,3)
1
>>> func(...,2,3,key_a="keyed up")
keyed up
>>> func(...,2,3)
None

So could you re-implement processing in a NEW language to allow different
handling. I am guessing you could. Again, other languages currently do
things their own way. But for compatibility, I can see why they may be
patching and documenting what IS.

And note you could create an amazingly annoying language where each
parameter is specified as having umpteen attributes like it has to be the
second un-named argument and of a restricted number of types and if it has a
keyword it can be abbreviated as short as some string and then should it be
placed in position 2 and does it have a default and who knows what more.

Avi

-Original Message-
From: Python-list  On
Behalf Of Chris Angelico
Sent: Sunday, February 10, 2019 11:32 AM
To: Python 
Subject: Re: The slash "/" as used in the documentation

On Mon, Feb 11, 2019 at 2:49 AM Ian Kelly  wrote:
>
> On Sat, Feb 9, 2019 at 1:19 PM Terry Reedy  wrote:
> >
> > This is the result of Python being a project of mostly unpaid
volunteers.
> >
> > See my response in this thread explaining how '/' appears in help 
> > output and IDLE calltips.  '/' only appears for CPython C-coded 
> > functions that have been modified to use Argument Clinic.  A.C. was 
> > added, I believe, in 3.5.  Simple builtins like len would have been 
> > the first to be converted.  The math module was converted for 3.7.  
> > There are some new conversions for 3.8 and likely some will be left for
future versions.
>
> I'm sure there are good reasons for it like most things Python does, 
> but I can't help but wonder if working on removing the positional 
> limitation from CPython would be a better use of time.

Do you ACTUALLY want to call math.sin(x=1.234) or is it purely for the sake
of consistency? Aside from questions about the help format, what is actually
lost by the inability to pass those arguments by name?

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

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


RE: Im trying to replicate the youtube video Creating my own customized celebrities with AI.

2019-02-10 Thread Avi Gross
Bob,

>> tenserflow, pygame, scipy, and numby

> All of these are probably installable using pip. By the way did you mean
numpy? 
> At a command prompt type pip install packagename.

While you are correcting the spelling of downloads as the downloader is
quite picky about exact spelling, please mention that the tenser flow should
be tensorflow. I think numby and perhaps tense is how you feel as you read
to the end of the documentation on numpy. 

More seriously, it helps if you have some idea of why these modules get
names. NUMeric PYthon is numpy. Something like SCIentific PYthon is scipy. 

I am not as sure about TensorFlow but suspect the mathematical concept of a
Tensor along with how it improves workflow. Haven't had a need to use it
yet. Neither have I had a need for pygame which seems to be a way to make
games in python.

-Original Message-
From: Python-list  On
Behalf Of Bob Gailer
Sent: Sunday, February 10, 2019 12:07 PM
To: [email protected]
Cc: python list 
Subject: Re: Im trying to replicate the youtube video Creating my own
customized celebrities with AI.

On Feb 10, 2019 11:40 AM,  wrote:
>
> The video

I don't see any video here. If you  attached  one the attachment did not
come through.

> gives the source code and the necessary things to download with it. 
> But
I'm new to python and don't understand how to install any of the files. The
files include: Python 3

Which you can download from python.org - just follow the link to downloads.

> pip

is automatically installed when you install python

> tenserflow, pygame, scipy, and numby

All of these are probably installable using pip. By the way did you mean
numpy? At a command prompt type pip install packagename.

I suggest you switch from [email protected] to [email protected].

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

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


RE: The use of type()

2019-02-10 Thread Avi Gross
Without using regular expressions, if you just want to extract the word
"int" or "float" you can substring the results by converting what type says
to a string:

>>> a = 5
>>> str(type(a))[8:11]
'int'

>>> a=5.0
>>> str(type(a))[8:13]
'float'

Since the format and length vary, this may not meet your needs. You could
search for the first index where there is a single quote and then the next
and take what is in between.

You can run this in-line or make a function that might work for at least the
basic types:

>>> a = 5
>>> text = str(type(a))
>>> first = text.find("'")
>>> first += 1
>>> second = text.find("'", first)
>>> first, second
(8, 11)
>>> text[first : second]
'int'
>>> print(text[first : second])
Int

If I do the same with a float like 5.0:

>>> a=5.0
>>> text = str(type(a))
>>> first = text.find("'")
>>> first += 1
>>> second = text.find("'", first)
>>> print(text[first : second])
float

For a list:

>>> a = ["list", "of", "anything"]
...
>>> print(text[first : second])
list

Of course this is so simple it must be out there in some module.




-Original Message-
From: Python-list  On
Behalf Of ^Bart
Sent: Sunday, February 10, 2019 4:43 PM
To: [email protected]
Subject: The use of type()

I need to print something like "this variable is int" or "this variable is
string"

n1 = 10
n2 = 23

print ("Total of n1+n2 is: ",n1+n2," the type is", type(n1+n2))

When I run it I have:

Total of n1+n2 is:  33  the type is   >>>

I'd like to read "the type is int" and NOT "the type is , how
could I solve it?

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

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


RE: The use of type()

2019-02-10 Thread Avi Gross
Follow on to below. I was right and there is a fairly trivial and portable
way to just show 'int' for the type of probably many types:

No need to call the type() function at all.

If "a" is an integer object containing "5" then you can ask for the class of
it and then within that for the name like this:

>>> a = 5
>>> print(a.__class__.__name__)
int
>>> b = 5.0
>>> print(b.__class__.__name__)
float

-Original Message-
From: Python-list  On
Behalf Of Avi Gross
Sent: Sunday, February 10, 2019 5:43 PM
To: [email protected]
Subject: RE: The use of type()

Without using regular expressions, if you just want to extract the word
"int" or "float" you can substring the results by converting what type says
to a string:

>>> a = 5
>>> str(type(a))[8:11]
'int'

>>> a=5.0
>>> str(type(a))[8:13]
'float'

Since the format and length vary, this may not meet your needs. You could
search for the first index where there is a single quote and then the next
and take what is in between.

You can run this in-line or make a function that might work for at least the
basic types:

>>> a = 5
>>> text = str(type(a))
>>> first = text.find("'")
>>> first += 1
>>> second = text.find("'", first)
>>> first, second
(8, 11)
>>> text[first : second]
'int'
>>> print(text[first : second])
Int

If I do the same with a float like 5.0:

>>> a=5.0
>>> text = str(type(a))
>>> first = text.find("'")
>>> first += 1
>>> second = text.find("'", first)
>>> print(text[first : second])
float

For a list:

>>> a = ["list", "of", "anything"]
..
>>> print(text[first : second])
list

Of course this is so simple it must be out there in some module.




-Original Message-
From: Python-list  On
Behalf Of ^Bart
Sent: Sunday, February 10, 2019 4:43 PM
To: [email protected]
Subject: The use of type()

I need to print something like "this variable is int" or "this variable is
string"

n1 = 10
n2 = 23

print ("Total of n1+n2 is: ",n1+n2," the type is", type(n1+n2))

When I run it I have:

Total of n1+n2 is:  33  the type is   >>>

I'd like to read "the type is int" and NOT "the type is , how
could I solve it?

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

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

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


RE: The slash "/" as used in the documentation

2019-02-11 Thread Avi Gross
Ian,

I want to make sure we are talking about the same things in the same ways. I
will thus limit my comments in this message.

If efficiency is your major consideration, then using only positional
arguments of known types you can place on the stack and optimize at compile
time may be a great way to go. It is not the way python generally goes as it
supports objects at run time that can be of any type and in many cases
allows any number of arguments to a function.

Python was designed till recently in a way that valued some more innovative
methods and that included allowing a combination of positional and keyword
arguments. The positional arguments can still be called with keyword but
only if moved beyond any other positional arguments. What evolved is NOT the
only way I have seen this done. But what I see now is not what you are
describing in some ways.

If you want to talk about recent or planned changes, fine. But make that
clear. I was talking about how in the past positional arguments did not have
defaults available at the def statement level. I was talking about how use
of the symbol "=" in the context of defining function parameters had
multiple meanings. It not only established that the parameter accepted a
keyword but also provided a default. The allowed syntax required a default,
even if it was None. I mean the following fails:

>>> def func(a,b=): pass
SyntaxError: invalid syntax

If in the future (or some other language) you want to allow some way of
assigning a default to positional arguments, fine. What I see today does
not. 

So if I understand you, there is a proposal or even plan to change some of
the current functionality. I still have not seen anyone post a reference as
requested. I am very open to seeing what people are considering or maybe
even implementing and in what ways it may not be compatible with present
functionality.



-Original Message-
From: Python-list  On
Behalf Of Ian Kelly
Sent: Monday, February 11, 2019 1:46 AM
To: Python 
Subject: Re: The slash "/" as used in the documentation

On Sun, Feb 10, 2019 at 2:18 PM Avi Gross  wrote:
> I am not sure how python implements some of the functionality it does 
> as compared to other languages with similar features. But I note that 
> there are rules, presumably some for efficiency, such as requiring all 
> keyword arguments to be placed after the last positional argument. I 
> mean I can call
> func(a,b,c,d=1,e=2) but not func(a,b,d=1, c, e=2).
>
> So if you allowed a keyword to optionally be used for any positional 
> argument other than the last, c, would it not require a change in this
rule?
> I mean func(a="invalid",b,c,d=1,e=2) would violate the rule and so 
> would making b a keyword version. In my example, and for this reason 
> only, maybe c could work.

My suggestion was not to allow keyword arguments to arbitrarily replace any
positional parameter, or to otherwise change argument-passing in any way.
The suggestion was to drop positional-only arguments from functions
implemented in C instead of just documenting them better. In the example
above, if you want to pass a by keyword, you would have to pass b and c by
keyword as well.
That would still be true for functions implemented in C if a, b, and c are
no longer positional-only.

> The original motivation for keyword arguments included the concept of 
> specifying a default if not used. Positional arguments have no default.
> Similarly, they are required if explicitly named in the function
definition.
> So we are intermingling multiple concepts in the previous design.

Positional arguments are allowed to have defaults, and keyword-only
arguments are allowed to not have defaults. These are all valid
syntax:

# Allows a and b to be passed either positionally or by keyword def foo(a=1,
b=2): pass

# b is keyword-only
def foo(a=1, *, b=2): pass

# Allows a and b to be passed either positionally or by keyword def foo(a,
b): pass

# b is keyword-only and has no default
def foo(a, *, b): pass

Positional-ONLY arguments are not directly supported by the language, but
they exist in the C API and can also have defaults. For example, dict.get
takes two positional-only arguments. The second argument is optional, and
its default is None.

My point is that the axis of positional-only versus positional-or-keyword
versus keyword-only, and the axis of required versus optional are entirely
separate.

> I won't go on except to say it would break lots of existing code and 
> potentially complicate new code.

Can you give an example of something that would be broken by updating C API
functions to name positional-only arguments instead of just updating them to
document that they're positional-only?
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: The slash "/" as used in the documentation

2019-02-11 Thread Avi Gross
Ian,

I now assume we are no longer talking about the past or even the present but
some planned future. In that future we are talking about how to define a
function with added or changed functionality. So nothing I wrote earlier
really applies because I was talking of how things did work in the absence
of the changes needed to make new functionality possible.

So let me make sure I understood you. We are talking about the function
prototype as in def fun(...) and perhaps the lambda equivalent. The user of
the function would only see changes in the help files or other documentation
but no special symbols would be used when they invoke a function, albeit new
error messages may also happen if done wrong.

The earlier messages talked about using a forward slash but you seem to use
an asterisk for the same purpose. You can use the very overloaded "*"
character as a delimiter between the parameters mentioned to the left and
any remaining ones to the right. The "=" symbol is thus now allowed on
either side of the divide and now ONLY means there is a default. 

I thought the discussion was about python, not the C API that arguably is
used as much of python is in C directly or indirectly. I thought we were
talking about updating everything at the top interpreted python levels.
Please make it clear if we are not.

Will the above functionality, if understood, break (or modify how it works)
existing python code? I mean code that only uses the asterisk to denote
multiplication, exponentiation, list expansion and dictionary expansion and
so on. 

Just based on what you wrote, maybe not. It depends on the new meaning of
not having a sole asterisk somewhere in the parameter list. If that means
evaluate old style, great. If it means something else, I won't speculate but
can picture problems.

I will talk about your C API question in another message.


-Original Message-
From: Python-list  On
Behalf Of Ian Kelly
Sent: Monday, February 11, 2019 1:46 AM
To: Python 
Subject: Re: The slash "/" as used in the documentation

On Sun, Feb 10, 2019 at 2:18 PM Avi Gross  wrote:
> I am not sure how python implements some of the functionality it does 
> as compared to other languages with similar features. But I note that 
> there are rules, presumably some for efficiency, such as requiring all 
> keyword arguments to be placed after the last positional argument. I 
> mean I can call
> func(a,b,c,d=1,e=2) but not func(a,b,d=1, c, e=2).
>
> So if you allowed a keyword to optionally be used for any positional 
> argument other than the last, c, would it not require a change in this
rule?
> I mean func(a="invalid",b,c,d=1,e=2) would violate the rule and so 
> would making b a keyword version. In my example, and for this reason 
> only, maybe c could work.

My suggestion was not to allow keyword arguments to arbitrarily replace any
positional parameter, or to otherwise change argument-passing in any way.
The suggestion was to drop positional-only arguments from functions
implemented in C instead of just documenting them better. In the example
above, if you want to pass a by keyword, you would have to pass b and c by
keyword as well.
That would still be true for functions implemented in C if a, b, and c are
no longer positional-only.

> The original motivation for keyword arguments included the concept of 
> specifying a default if not used. Positional arguments have no default.
> Similarly, they are required if explicitly named in the function
definition.
> So we are intermingling multiple concepts in the previous design.

Positional arguments are allowed to have defaults, and keyword-only
arguments are allowed to not have defaults. These are all valid
syntax:

# Allows a and b to be passed either positionally or by keyword def foo(a=1,
b=2): pass

# b is keyword-only
def foo(a=1, *, b=2): pass

# Allows a and b to be passed either positionally or by keyword def foo(a,
b): pass

# b is keyword-only and has no default
def foo(a, *, b): pass

Positional-ONLY arguments are not directly supported by the language, but
they exist in the C API and can also have defaults. For example, dict.get
takes two positional-only arguments. The second argument is optional, and
its default is None.

My point is that the axis of positional-only versus positional-or-keyword
versus keyword-only, and the axis of required versus optional are entirely
separate.

> I won't go on except to say it would break lots of existing code and 
> potentially complicate new code.

Can you give an example of something that would be broken by updating C API
functions to name positional-only arguments instead of just updating them to
document that they're positional-only?
--
https://mail.python.org/mailman/listinfo/python-list

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


RE: The slash "/" as used in the documentation

2019-02-11 Thread Avi Gross
Ian,

Again, not having read whatever documentation we may be discussing, I may be
very wrong.

The topic is the C API. I started using C at Bell Laboratories in 1982
replacing other languages I had used before. I haven't felt a reason to use
it in the last few decades as I moved on to yet other languages but am quite
aware that many of those languages are largely interpreters written in
languages like C or C++ and then regularly patched by adding C-like code to
replace slower functionality. I assume the C API you are mentioning refers
to the process of how you write and compile and invoke library functions so
that the function called will properly place python data structures in some
kind of stack so that the C library can properly take it and perform
computations. Similarly, when the function returns, some additional mapping
may be done. The above is meant to be general and obviously the details
matter.

C as a stand-alone language used to have pretty much positional arguments
and often a fixed number of them. We often had multiple functions we could
call with slightly different names if we wanted special effects like not
requiring a third argument. Clearly some approaches were less efficient if
the two-argument version simply turned around and called the three-argument
version with a third argument set to a default. So, often you played other
games like requiring a third argument (or in some languages a dangling
comma) which the function might choose to replace with a default internally
if it is something like -1. Obviously C libraries that are external must be
used as-is while internal ones you have written might allow changes.

Some languages I have used do not so much support doing lots of command-line
level pre-processing of command-line arguments but provide helper functions
that can be called within the function call that take all the arguments and
do further processing and return a form that the function can more easily
use. This works even better when evaluation is lazy and you can access the
exact original text the programmer or user typed in before it is evaluated.
Python now allows a limited form of that if you ask for *args and **kwargs.

So is this mainly about efficiency and C libraries or more? You can easily
make a C function that expects positional arguments in a proper order and
then make a wrapper in python (or C or FORTRAN or whatever) with a slightly
different name that does preprocessing and/or postprocessing. Python is
loaded with such functionality that tends to allow more complex things to be
done less efficiently. So if the wrapper can evaluate your arguments and
figure out what to do with positional arguments, great. The wrapper function
might support an optional argument that specifies whether other argument
units are in feet, miles, meters or even parsecs and also accept keyword
arguments for those measures and rescale them and only then call the
efficient C function with all the right arguments in the right positions. If
you as a programmer find that slows things down, you can make sure you use
the right units for the function and call the underlying function directly
with everything in place according to those rules.

Ending with this. Is the reality that we are now talking about gradual
changes in documentation as individual C functions are updated but not at
this point about what normal python users are seeing in terms of the code?
If so, I repeat, I was not talking about that and my comments are not
applicable and I can go back to doing more useful things away from this
forum.

-Original Message-
From: Python-list  On
Behalf Of Ian Kelly
Sent: Monday, February 11, 2019 1:46 AM
To: Python 
Subject: Re: The slash "/" as used in the documentation

On Sun, Feb 10, 2019 at 2:18 PM Avi Gross  wrote:
> I am not sure how python implements some of the functionality it does 
> as compared to other languages with similar features. But I note that 
> there are rules, presumably some for efficiency, such as requiring all 
> keyword arguments to be placed after the last positional argument. I 
> mean I can call
> func(a,b,c,d=1,e=2) but not func(a,b,d=1, c, e=2).
>
> So if you allowed a keyword to optionally be used for any positional 
> argument other than the last, c, would it not require a change in this
rule?
> I mean func(a="invalid",b,c,d=1,e=2) would violate the rule and so 
> would making b a keyword version. In my example, and for this reason 
> only, maybe c could work.

My suggestion was not to allow keyword arguments to arbitrarily replace any
positional parameter, or to otherwise change argument-passing in any way.
The suggestion was to drop positional-only arguments from functions
implemented in C instead of just documenting them better. In the example
above, if you want to pass a by keyword, you would have to pass b and c by
keyword as well.
That would still be true for functions implemented in C 

RE: Why float('Nan') == float('Nan') is False

2019-02-13 Thread Avi Gross
I won't speak for the IEEE but NOT A NUMBER does not tell you what something
IS.

If "Hello, World!" is not a number as in an int or a float and we throw away
the content and simply call it a NaN or something and then we notice that an
object that is a list of fruits is also not a number so we call it a NaN
too, then should  they be equal?

A NaN is a bit like a black hole. Anything thrown in disappears and that is
about all we know about it. No two black holes are the same even if they
seem to have the same mass, spin and charge. All they share is that we don't
know what is in them.

When variable "a" is a Nan then it is sort of a pointer to a concept. The
pointer IS itself but the concepts may not be.

-Original Message-
From: Python-list  On
Behalf Of Grant Edwards
Sent: Wednesday, February 13, 2019 1:03 PM
To: [email protected]
Subject: Re: Why float('Nan') == float('Nan') is False

On 2019-02-13, ast  wrote:
> Hello
>
> >>> float('Nan') == float('Nan')
> False

If you think that's odd, how about this?

>>> n = float('nan')
>>> n
nan
>>> n is n
True
>>> n == n
False
>>>

> Why ?

IEEE says so.

-- 
Grant Edwards   grant.b.edwardsYow! Like I always say
  at   -- nothing can beat
  gmail.comthe BRATWURST here in
   DUSSELDORF!!

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

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


Re: Why float('Nan') == float('Nan') is False

2019-02-13 Thread Avi Gross

I think we should realize that Nan and NA and so on are human constructs people 
Define in programming languages. Some have subdivisions as in not an int as 
compared to not a float.

Python also has an Inf as well as a -Inf that are abstractions and not a real, 
so to speak. Number.

Mathematics is arguably a human discovery when it comes to infinities since 
Cantor but the rules are not the same. CARDINALITY is not a number. It is a 
logical range of partitions. There obviously are more integers than prime 
numbers as you count upwards to a thousand or a billion. BUT in the context of 
infinity, at the Aleph Null level, they sort of map into the same category. So 
the primes or squares or odd numbers are not equal but in the limit as you 
approach whatever infinity means, they seem effectively equal as there is 
always another.  You can sort of make a 1:1 correspondence or mapping. 

But that means that normal mathematics is warped. Double it and/or add a 
quadrillion and it remains in the same bucket.  But there are other buckets and 
everything in them is not so much the same as in some sense larger than the 
previous bucket but smaller than the next higher bucket.

The continuum hypothesis remains open as to whether there is an intermediate 
bucket you can describe between Aleph Null and Aleph one. Meaning there is no 
reasonable definition of a bucket the new infinite construct fits in while not 
fitting existing ones.

Back to python. Or is it IEEE? In type int the number can be arbitrarily large 
as long as you have enough computer memory and resources. Yet the special 
concepts of Inf and negative Inf can be compared with other ints but not 
fruitfully with Nan, right? There are helper functions you can call to ask if a 
variable is an Inf or a Nan. Doubles have size limits so anything big enough 
might as well be an Inf. I note some things like numpy use a fixed size int as 
well.

Some of the confusion may come when a language uses a concept in many ways. In 
R all an NA can mean is Not Available. Some data structures, just like a numpy 
array in python, insist on holding objects of one unified type and NA normally 
matches any such type as a placeholder. Sort of a NULL. You normally do not 
want to include an NA in calculations as it infects everything. So you often 
filter it out implicitly or explicitly. It is not necessarily an error but if 
you use it in calculating a mean, then the result is sort of an error.

You can ask if a variable is an NA as in is.na(x) which returns a Boolean. So 
to test if x and y are both NA or have the same status by both not being NA, 
use the functions. Python has similar functionality. Just don't compare the 
naked singularities to each other!


Sent from AOL Mobile Mail
On Wednesday, February 13, 2019 Chris Angelico  wrote:
On Thu, Feb 14, 2019 at 7:12 AM Test Bot  wrote:
>
> This definition of NaN is much better in mentally visualizing all the so
> called bizarreness of IEEE. This also makes intuitive that no 2 NaN will be
> equal just as no 2 infinities would be equal. I believe in a hypothesis(of
> my own creation) that any arithmetic on a data type of NaN would be similar
> to any set of operations on the set of Infinities.
>

Why would no two infinities be equal? In mathematics, there's one
best-known infinity (aleph null, aka the number of counting numbers),
and many many infinities are provably equal to it. (Others are
provably NOT equal to it, like the number of real numbers.) There's
nothing wrong with saying "there are as many prime numbers as there
are odd numbers", or equivalently that "the size/cardinality of the
set of primes is equal to the size of the set of odd numbers" [1]. And
both Python and IEEE agree:

>>> float("inf") == float("inf")
True

NaN and infinity are quite different concepts, and they behave very differently.

ChrisA

[1] I'm sure someone will point out something pedantically wrong in
what I said, but certainly the sets have the same cardinality.
-- 
https://mail.python.org/mailman/listinfo/python-list
-- 
https://mail.python.org/mailman/listinfo/python-list


  1   2   3   4   5   >