Hi guys,
I'm a little worried about the expected disappearance of lambda in
python3000. I've had my brain badly broken by functional programming
in the past, and I would hate to see things suddenly become harder
than they need to be.
An example of what I mean is a quick script I wrote for doing certain
actions based on a regexp, which I will simlify in this instance to
make the pertanant points more relevent.
{
'one': lambda x:x.blat(),
'two': lambda x:x.blah(),
}.get(someValue, lambda x:0)(someOtherValue)
The alternatives to this, reletively simple pattern, which is a rough
parallel to the 'switch' statement in C, involve creating named
functions, and remove the code from the context it is to be called
from (my major gripe).
So, the questions I am asking are:
Is this okay with everyone?
Does anyone else feel that lambda is useful in this kind of context?
Are there alternatives I have not considered?
merrily-yr's
Stephen. 63 3310
On 2004-12-23, Stephen Thorne <st************@gmail.com> wrote: Hi guys,
I'm a little worried about the expected disappearance of lambda in python3000. I've had my brain badly broken by functional programming in the past, and I would hate to see things suddenly become harder than they need to be.
I use Python lambda quite a bit, and I don't understand the recent noise
about problems with it, and its removal. I don't have a problem with
lambdas.
My personal gripe is this. I think the core language, as of 2.3 or 2.4
is very good, has more features than most people will ever use, and they
(Guido, et al.) can stop tinkering with it now and concentrate more on
the standard libraries.
--
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
Keith Dart <kd***@kdart.com>
public key: ID: F3D288E4
================================================== ===================
Stephen Thorne wrote: { 'one': lambda x:x.blat(), 'two': lambda x:x.blah(), }.get(someValue, lambda x:0)(someOtherValue)
The alternatives to this, reletively simple pattern, which is a rough parallel to the 'switch' statement in C, involve creating named functions, and remove the code from the context it is to be called from (my major gripe).
Here's what my code for a very similar situation usually looks like:
py> class Foo(object):
.... def blat(self):
.... print "blat"
.... def blah(self):
.... print "blah"
....
py> key, foo = 'two', Foo()
py> try:
.... result = dict(one=Foo.blat, two=Foo.blah)[key](foo)
.... except KeyError:
.... result = 0
....
blah
As you can see, I just use the unbound methods of the parent class
directly. Of course this means that your code won't work if 'foo' isn't
actually a Foo instance. So you lose a little generality, but you gain
a bit in conciceness of expression (IMHO). Note also that I don't use
dict.get, relying on the KeyError instead. Usually, my case for when no
function applies is complex enough to not be expressable in a lambda
anyway, so this is generally more appropriate for my code.
While I don't generally find that I need lambda, I'm not particularly
arguing against it here. I just thought it might be helpful to
demonstrate how this code might be written concicely without lambdas.
Steve
This is NOT true. Functional programming, AFAIKC, is a cool thing, and
in-fashion, increases productivity & readability, and an indispensable
thing for a flexible scripting lang. The inline/lambda function is
feature is shared by many lang. which I frequently use,
MATLAB/R/Python/etc. Well, you can say apply() is 'deprecated' now,
(which is another functional thing I like), but I am still using it. I
am not a desperate person who uses higher-order function factory a lot,
but if lambda keyword is removed, I swear I will not use the python
anymore.
On Thu, 2004-12-23 at 12:47, Keith Dart wrote: On 2004-12-23, Stephen Thorne <st************@gmail.com> wrote: Hi guys,
I'm a little worried about the expected disappearance of lambda in python3000. I've had my brain badly broken by functional programming in the past, and I would hate to see things suddenly become harder than they need to be.
I use Python lambda quite a bit, and I don't understand the recent noise about problems with it, and its removal. I don't have a problem with lambdas.
My personal gripe is this. I think the core language, as of 2.3 or 2.4 is very good, has more features than most people will ever use, and they (Guido, et al.) can stop tinkering with it now and concentrate more on the standard libraries.
As someone working with the Python/C API, I'd have to argue that the
Python language may (I express no opinion on this) be "Done", but
CPython doesn't look like it is.
In my view a bunch of minor, but irritating, issues exist:
It's hard to consistently support Unicode in extension modules without
doing a lot of jumping through hoops. Unicode in docstrings is
particularly painful. This may not be a big deal for normal extension
modules, but when embedding Python it's a source of considerable
frustration. It's also not easy to make docstrings translatable.
Supporting an optional encoding argument for docstrings in the
PyMethodDef struct would help a lot, especially for docstrings returned
by translation mechanisms.
Py_NewInterpreter/Py_EndInterpreter used in the main thread doesn't
work with a threaded Python debug build, calling abort(). If a
non-threaded Python is used, or a non-debug build, they appear to work
fine. There are some indications on the mailing list that this is due to
Python's reliance on thread-local-storage for per-interpreter data, but
there are no suggestions on how to work around this or even solid
explanations of it. This sucks severely when embedding Python in Qt
applications, as GUI calls may only be made from the main thread but
subinterepreters may not be created in the main thread. It'd be
fantastic if the subinterpreter mechanism could be fleshed out a bit. I
looked at it, but my C voodo just isn't up there. The ability to run
scripts in private interpreters or subinterpreters (that are disposed of
when the script terminates) would be immensely useful when using Python
as a powerful glue/scripting language in GUI apps.
IMO the reference behaviour of functions in the C API could be
clearer. One often has to simply know, or refer to the docs, to tell
whether a particular call steals a reference or is reference neutral.
Take, for example, PyDict_SetItemString vs PyMapping_SetItemString . Is
it obvious that one of those steals a reference, and one is reference
neutral? Is there any obvious rationale behind this? I'm not overflowing
with useful suggestions about this, but I do think it'd be nice if there
was a way to more easily tell how functions behave in regard to
reference counts.
Const. I know there's a whole giant can of worms here, but even so -
some parts of the Python/C API take arguments that will almost always be
string literals, such as format values for Py_BuildValue and
PyArg_ParseTuple or the string arguments to Py*_(Get|Set)String calls.
Many of these are not declared const, though they're not passed on to
anywhere else. This means that especially in c++, one ends up doing a
lot of swearing and including a lot of ugly and unnecessary string
copies or const_cast<char*>()s to silence the compiler's whining. It
would be nice if functions in the Python/C API would declare arguments
(not return values) const if they do not pass them on and do not change
them.
Of course, all these are just my opinion in the end, but I'd still have
to argue that using Python from C could be a lot nicer than it is. The
API is still pretty good, but the solution of these issues would make it
a fair bit nicer again, especially for people embedding Python in apps
(a place were it can seriously excel as a scripting/extension/glue
language).
--
Craig Ringer ta********@gmail.com wrote: Well, you can say apply() is 'deprecated' now, (which is another functional thing I like), but I am still using it.
Interesting. Could you explain why? Personally, I find the
*expr/**expr syntax much simpler, so I'd be interested in knowing what
motivates you to continue to use apply...
Steve
On Thu, 2004-12-23 at 15:21, ta********@gmail.com wrote: This is NOT true. Functional programming, AFAIKC, is a cool thing, and in-fashion, increases productivity & readability, and an indispensable thing for a flexible scripting lang.
Couldn't agree more. One of the things I find most valuable about Python
is the ability to use functional style where it's the most appropriate
tool to solve a problem - WITHOUT being locked into a pure-functional
purist language where I have to fight the language to get other things
done.
The inline/lambda function is feature is shared by many lang. which I frequently use, MATLAB/R/Python/etc. Well, you can say apply() is 'deprecated' now, (which is another functional thing I like), but I am still using it. I am not a desperate person who uses higher-order function factory a lot, but if lambda keyword is removed, I swear I will not use the python anymore.
I also make signficant use of Lambda functions, but less than I used to.
I've recently realised that they don't fit too well with Python's
indentation-is-significant syntax, and that in many cases my code is
much more readable through the use of a local def rather than a lambda.
In other words, I increasingly find that I prefer:
def myfunction(x):
return x**4
def mysecondfuntion(x):
return (x * 4 + x**2) / x
make_some_call(myfunction, mysecondfunction)
to:
make_some_call( lambda x: x**4, lambda x: (x * 4 + x**2) / x)
finding the former more readable. The function names are after all just
temporary local bindings of the function object to the name - no big
deal. Both the temporary function and the lambda can be used as
closures, have no impact outside the local function's scope, etc. I'd be
interested to know if there's anything more to it than this (with the
side note that just don't care if my temporary functions are anonymous
or not).
One of the things I love about Python is the ability to mix functional,
OO, and procedural style as appropriate. I can write a whole bunch of
functions that just return the result of list comprehensions, then use
them to operate on instances of an object from a procedural style main
function. In fact, that's often the cleanest way to solve the problem.
The fact that I have that option is something I really like.
As for apply(), while it is gone, the f(*args) extension syntax is now
available so I don't really see the issue. After all, these two are the
same:
def callfunc(function,args):
return apply(function,args)
and
def callfunc(function,args):
return function(*args)
its just an (IMO trivial) difference in syntax. I'd be interested in
knowing if there is in fact more to it than this.
--
Craig Ringer
Craig Ringer wrote: It's hard to consistently support Unicode in extension modules without doing a lot of jumping through hoops. Unicode in docstrings is particularly painful. This may not be a big deal for normal extension modules, but when embedding Python it's a source of considerable frustration. It's also not easy to make docstrings translatable. Supporting an optional encoding argument for docstrings in the PyMethodDef struct would help a lot, especially for docstrings returned by translation mechanisms.
docstrings should be moved out of the C modules, and into resource
files. (possibly via macros and an extractor). when I ship programs
to users, I should be able to decide whether or not to include docstrings
without having to recompile the darn thing.
and yes, docstrings should support any encoding supported by python's
unicode system.
Const. I know there's a whole giant can of worms here, but even so - some parts of the Python/C API take arguments that will almost always be string literals, such as format values for Py_BuildValue and PyArg_ParseTuple or the string arguments to Py*_(Get|Set)String calls. Many of these are not declared const, though they're not passed on to anywhere else. This means that especially in c++, one ends up doing a lot of swearing and including a lot of ugly and unnecessary string copies or const_cast<char*>()s to silence the compiler's whining. It would be nice if functions in the Python/C API would declare arguments (not return values) const if they do not pass them on and do not change them.
I think the only reason that this hasn't already been done is to reduce the
amount of swearing during the conversion process (both for the core developer
and C extension developers...).
</F>
Keith Dart <kd***@kdart.com> wrote: My personal gripe is this. I think the core language, as of 2.3 or 2.4 is very good, has more features than most people will ever use, and they
Indeed, it has _too many_ features. Look at the PEP about 3.0, and
you'll see that removing redundant features and regularizing a few
oddities is what it's meant to be all about.
(Guido, et al.) can stop tinkering with it now and concentrate more on the standard libraries.
No doubt the standard library needs more work, particularly if you count
the built-ins as being part of the library (which, technically, they
are). Indeed, much of the redundancy previously mentioned is there
rather than in the core language strictly speaking -- e.g., all of the
things returning lists (from keys, values, items methods in dicts, to
the range built-in) mostly-duplicated with things returning iterators
(iterkeys, etc) or nearly so (xrange). These are things that can't
change in 2.5 to avoid breaking backwards compatibility. Other things,
where bw compat is not threatened, are no doubt going to be targeted in
2.5.
Alex
On Thu, 23 Dec 2004 14:13:28 +1000, Stephen Thorne
<st************@gmail.com> wrote: I'm a little worried about the expected disappearance of lambda in python3000. I've had my brain badly broken by functional programming in the past, and I would hate to see things suddenly become harder than they need to be.
Me too.
But its not only about becoming harder, I actually like the fact
that lamda exists as a tie in to the actual concept of an
anonymous function. When you read a math book on lambda calculus
its nice to transform those concepts directly to the language.
The current Pythonic lambda has its limitations, but being able
to explicitly create lambdas is a nice feature IMHO. Its much
better than having to create lots of one-off single use functions
with meaningless names.
It can't be that hard to maintain the lambda code, why not just
leave it there for the minority of us who like the concept?
Alan G.
Author of the Learn to Program website http://www.freenetpages.co.uk/hp/alan.gauld
On 22 Dec 2004 23:21:37 -0800, ta********@gmail.com wrote: but if lambda keyword is removed, I swear I will not use the python anymore.
While I would be dissappointed to lose lambda, I think losing
Python would hurt me a lot more! After all we aren't losing
functionality here, just adding sonme extra work and losing some
readability. Pythonic lambdas are just syntactic sugar in
practice, they just make the code look more like true
functional code.
Alan G.
Author of the Learn to Program website http://www.freenetpages.co.uk/hp/alan.gauld
Alan Gauld <al********@btinternet.com> writes: readability. Pythonic lambdas are just syntactic sugar in practice,
Actually it's the other way around: it's named functions that are the
syntactic sugar.
Craig Ringer <cr***@postnewspapers.com.au> wrote:
... Couldn't agree more. One of the things I find most valuable about Python is the ability to use functional style where it's the most appropriate tool to solve a problem - WITHOUT being locked into a pure-functional purist language where I have to fight the language to get other things done.
By the way, if that's very important to you, you might enjoy Mozart
(http://www.mozart-oz.org/) -- I'm looking at it and it does appear to
go even further in this specific regard (rich support for multi -
paradigm programming). It's also blessed with a great book,
<http://www.info.ucl.ac.be/people/PVR/book.html> -- I've just started
browsing it, but it appears to be worthy of being called "SICP for the
21st century"...!-). Just like SICP made it worthwhile to learn a
little Scheme even if you'd never use it in production, so does CTMCP
(acronym for this new book by Van Roy and Haridi) work for Oz, it
appears to me.
def callfunc(function,args): return apply(function,args)
and
def callfunc(function,args): return function(*args)
its just an (IMO trivial) difference in syntax. I'd be interested in knowing if there is in fact more to it than this.
No, the semantics are indeed the same.
Alex
On 23 Dec 2004 00:52:53 -0800, Paul Rubin
<"http://phr.cx"@nospam.invalid> wrote: Alan Gauld <al********@btinternet.com> writes: readability. Pythonic lambdas are just syntactic sugar in practice,
Actually it's the other way around: it's named functions that are the syntactic sugar.
Not true, you can't re-write
def f():
raise ValueError, "Don't call f"
as a lambda. Lambdas contain only a single expression. Even the py3k
wiki page ignores this critical difference. A single expression means
no statements of any kind can be included. Assignment, if/elif/else,
while, for, try/except, etc are not catered for in lambdas.
There has been a case in the past for a lambda that contains
statements, but they have been stomped on due to problems with syntax.
I don't like lambdas that have more than a single expression myself
(if it's more complex than "lambda x:baz(x.foo(y))", I would prefer to
write a named function).
ultimate-ly yr's.
Stephen Thorne.
Stephen Thorne wrote: Not true, you can't re-write
def f(): raise ValueError, "Don't call f"
f = lambda: eval(compile("raise ValueError(\"Don't call f\")", "", "exec"))
note that lambdas have names too, btw:
print f.func_name
<lambda>
</F>
Alan Gauld <al********@btinternet.com> wrote:
... It can't be that hard to maintain the lambda code, why not just leave it there for the minority of us who like the concept?
I guess the key motivator is the usual set of design principles:
3. Keep the language small and simple.
4. Provide only one way to do an operation.
Well, this phrasing is actually from the "Spirit of C" section of the
introduction to the ISO C standard, but the Zen of Python phrasing,
"""There should be one-- and preferably only one --obvious way to do
it.""" isn't all that different.
Having lambda in the language in addition to def provides two ways to do
an operation (make a function), and for that it makes the language a
little bit less simple and less small than if only def was there. I
guess that's why Guido now regrets ever having accepted lambda into the
language, and hopes to take it away when backwards compatibility can be
broken (i.e., in 3.0).
Having just reviewed, edited and merged over 1000 recipes to select
about 1/3 of those for the 2nd edition of the Cookbook, I think I'm in a
good position to state that, at least as far as CB contributors are
representative of the Python community, uses of lambda that are dubious
to very dubious to absurd outnumber those which are decent to good by
around 4:1. If I see another case of:
somename = lambda x: ...
instead of the obvious
def somename(x): ...
I think I'll scream, though not quite as loud as for my next seeing:
map(lambda x: f(x), ...
instead of
map(f, ...
I don't know what it IS about lambda that prompts so much dubious to
absurd use, but that's what I observed. I don't know if that plays any
role in Guido's current thinking, though -- I have no idea how much
"dubious Python" he's had to struggle with. One could argue that the
typical abuses of redundant lambda as shown above are closely related,
e.g., to typical abuses of booleans, such as:
if (x>y) == True:
Funny enough, though, I've seen the equivalent of this latter abuse very
often in C and C++, but not in Python (again judging e.g. from the
submissions to the cookbook site). Maybe it's bool's relatively recent
introduction in the language; after all, one DOES often see:
if len(somecontainer) > 0:
instead of the obvious
if somecontainer:
so it's not as if pythonistas in general are blessed with some magical
"redundancy avoidance spell"...
Alex
Alan Gauld wrote: It can't be that hard to maintain the lambda code, why not just leave it there for the minority of us who like the concept?
Because one of the points of Py3K is to clean up the language concepts and
syntax, and the current lambda just doesn't fit cleanly. If it was proposed in a
PEP, the syntax would be rejected as not being sufficiently Pythonic and for
being a castrated near-synonym for the def statement.
Now, Python 3K will retain the statement/expression distinction, so anonymous
functions will indeed be impossible without lambda - the link from a statement
to an expression will need to be made through the local namespace.
So, rather than pushing to retain lambda for Py3K, it might be more productive
to find a better statement -> expression translation for function definitions.
Guido seems to prefer named functions, so it would still be tough to gain his
acceptance. However, a more Pythonic syntax is the only way I can see anonymous
functions making into 3.0
The current best example of a statement->expression translation is generator
expressions:
def squares(seq)
for x in seq:
yield x * x
total = sum(squares(seq))
versus:
total = sum(x * x for x in seq)
If we consider a function definition (omitting decorators and docstrings) we get:
def foo(a, b, c):
return f(a) + o(b) - o(c)
accepts_func(foo)
What would a Pythonic 'function as expression' look like?
Perhaps something like:
accepts_func( (def (a, b, c) to f(a) + o(b) - o(c)) )
Here we simply omit the function name and use 'to' instead of ':' (the colon is
omitted to avoid making our expression look like it might be a statement). We
also don't need a return statement, since our target is an expression. The
surrounding parentheses would be required.
The "def (arg-tuple) to (result)" form is intended to show that we're talking
about a function in the mathematical sense of a single expression, rather than
the general Python sense of a suite of statements. That is, it has the same
behaviour as the current lambda - if you want a real Python function, write a
real Python function :)
Personally, I don't see the restriction of anonymous functions to single
expressions any more of a wart than the restriction of the value portion of a
generator expression to a single expression. If an algorithm is too complex for
a single expression, it's probably worth giving a name.
Some more examples:
(def (x) to x * x) # Map values to their squares
(def () to x) # No arguments, always map to x
(def (*a, **k) to x.bar(*a, **k)) # Look up the method now, call it later
And in combination with a generator expression:
( (def () to x(*a, **k)) for x, a, k in funcs_and_args_list)
Replacing the 'to' with -> might actually read better:
(def (a, b, c) -> f(a) + o(b) - o(c))
(def (x) -> x * x)
(def () -> x)
(def (*a, **k) -> x.bar(*a, **k))
( (def () -> x(*a, **k)) for x, a, k in func_list)
Anyway, thats just some ideas if you're concerned about the plan to have lambda
disappear in 3K.
Cheers,
Nick.
--
Nick Coghlan | nc******@email.com | Brisbane, Australia
--------------------------------------------------------------- http://boredomandlaziness.skystorm.net
Alex Martelli wrote: I think I'll scream, though not quite as loud as for my next seeing:
map(lambda x: f(x), ...
instead of
map(f, ...
note that if you replace "map" with "some function that takes a callable", the difference
between these two constructs may be crucially important.
</F>
Alex Martelli wrote: if len(somecontainer) > 0:
instead of the obvious
if somecontainer:
so it's not as if pythonistas in general are blessed with some magical "redundancy avoidance spell"...
That is not always equivalent: z = Numeric.zeros(5) z
array([0, 0, 0, 0, 0]) bool(z)
False len(z) > 0
True
Peter
Fredrik Lundh <fr*****@pythonware.com> wrote: Alex Martelli wrote:
I think I'll scream, though not quite as loud as for my next seeing:
map(lambda x: f(x), ...
instead of
map(f, ...
note that if you replace "map" with "some function that takes a callable", the difference between these two constructs may be crucially important.
Sure -- if global name f gets rebound during the execution of the ``some
function'' (or if that function stashes the callable away, and that name
gets rebound later, etc), the semantics of passing f are different -- to
get the same semantics with a lambda, you'd have to use the old trick:
somefunc(lambda x, f=f: f(x), ...
I don't recall ever having seen the late-binding semantics (of the
lambda I originally showed) ``used properly'' -- I _have_ sometimes seen
that semantics cause subtle bugs, though. Do you have any real-life
examples where expecting and allowing for rebinding of global name `f'
is proper and desirable behavior? Being able to show a "good" use of
this late-binding could be helpful, if I knew of any.
Alex
Stephen Thorne wrote: Hi guys,
I'm a little worried about the expected disappearance of lambda in python3000. I've had my brain badly broken by functional programming in the past, and I would hate to see things suddenly become harder than they need to be.
Don't worry, it's not gonna go away because too much software is
depending on it. If you don't follow the advice that lambda is
deprecated and you keep using it, more software will depend on it and it
will never disappear :)
Personally I'm not a fan of functional programming but lambda *is*
useful when I want to say for example:
f (callback=lambda x, y: foo (y,x))
I don't believe it will ever disappear.
G.
Peter Otten <__*******@web.de> wrote: Alex Martelli wrote:
if len(somecontainer) > 0:
instead of the obvious
if somecontainer:
so it's not as if pythonistas in general are blessed with some magical "redundancy avoidance spell"...
That is not always equivalent:
z = Numeric.zeros(5) z array([0, 0, 0, 0, 0]) bool(z) False len(z) > 0
True
Good point! Numeric sure has semantics here that can be confusing;-).
numarray's arrays just can't be used as the argument to bool(...) -- you
get a runtime error "An array doesn't make sense as a truth value. Use
sometrue(a) or alltrue(a)" ("in the face of ambiguity, refuse the
temptation to guess"). Still, this ALSO means that len(z)>0 is very
different from bool(z), for numarray as for Numeric.
Most containers don't choose to implement __nonzero__, so bool(z) just
calls __len__ instead; that's the scenario I had in mind, of course.
But sure, if somecontainer might define peculiar semantics in
__nonzero__, then in order to test if it's empty you can't use the
normal pythonic idiom of checking its truth value, but rather must check
its length. (I still prefer "if len(z):", avoiding the redundant ">0",
but that's just a small difference, of course).
Alex
jfj wrote: Stephen Thorne wrote:
Hi guys,
I'm a little worried about the expected disappearance of lambda in python3000. I've had my brain badly broken by functional programming in the past, and I would hate to see things suddenly become harder than they need to be.
Don't worry, it's not gonna go away because too much software is depending on it. If you don't follow the advice that lambda is deprecated and you keep using it, more software will depend on it and it will never disappear :)
No, that doesn't apply for Python 3.0
Indeed, lambda as it currently stands will disappear for the Python 2.x series.
Python 3.0 will be a case of "OK, let's take the things we learned were good and
keep them, and throw away the things we realised were bad"
Undoubtedly, the two languages will co-exist for quite some time.
Cheers,
Nick.
--
Nick Coghlan | nc******@email.com | Brisbane, Australia
--------------------------------------------------------------- http://boredomandlaziness.skystorm.net
Nick Coghlan <nc******@iinet.net.au> wrote:
... Perhaps something like:
accepts_func( (def (a, b, c) to f(a) + o(b) - o(c)) )
Nice, except I think 'as' would be better than 'to'. 'as' should be a
full keyword in 3.0 anyway (rather than a surprisingly-NOT-keyword like
today), and "define something as somethingelse" seems marginally more
readable to me than "define something to somethingelse" anyway.
Alex
Fredrik Lundh wrote: Craig Ringer wrote: It's hard to consistently support Unicode in extension modules without doing a lot of jumping through hoops. Unicode in docstrings is particularly painful. This may not be a big deal for normal extension modules, but when embedding Python it's a source of considerable frustration. It's also not easy to make docstrings translatable. Supporting an optional encoding argument for docstrings in the PyMethodDef struct would help a lot, especially for docstrings returned by translation mechanisms.
docstrings should be moved out of the C modules, and into resource files. (possibly via macros and an extractor). when I ship programs to users, I should be able to decide whether or not to include docstrings without having to recompile the darn thing.
Good point. Unfortunately, many translation mechanisms - like Qt's, for
example - don't make it easy to translate strings in resource files
using the same tools as the core app. Translators have a hard enough job
already with one set of tools in my experience, lumping more on them
probably isn't nice. On the other hand, this isn't really Python's
problem - but neither is where they come from. Even if I load docstrings
from resource files, I still have a fair bit of work ahead to make
Python accept them if they're not plain ASCII. In my current project, I
actually gave up and changed sysdefaultencoding to utf-8 . (It's an
embedded interpreter, so it's not too bad - and all modules should
handle that correctly by now anyway). Const. I know there's a whole giant can of worms here, but even so - some parts of the Python/C API take arguments that will almost always be string literals, such as format values for Py_BuildValue and PyArg_ParseTuple or the string arguments to Py*_(Get|Set)String calls. Many of these are not declared const, though they're not passed on to anywhere else. This means that especially in c++, one ends up doing a lot of swearing and including a lot of ugly and unnecessary string copies or const_cast<char*>()s to silence the compiler's whining. It would be nice if functions in the Python/C API would declare arguments (not return values) const if they do not pass them on and do not change them.
I think the only reason that this hasn't already been done is to reduce the amount of swearing during the conversion process (both for the core developer and C extension developers...).
Agreed. However, it's my understanding that one can convert:
PyObject* *Py_BuildValue*( char *format, ...)
to
PyObject* *Py_BuildValue*( const char *format, ...)
(for example) without affecting module developers or users of that
function elsewhere in the core code. const _arguments_ are often very
safe, its const return values that tend to suck.
--
Craig Ringer
Alex Martelli wrote:
...... By the way, if that's very important to you, you might enjoy Mozart (http://www.mozart-oz.org/) -- I'm looking at it and it does appear to go even further in this specific regard (rich support for multi - paradigm programming). It's also blessed with a great book, <http://www.info.ucl.ac.be/people/PVR/book.html> -- I've just started browsing it, but it appears to be worthy of being called "SICP for the 21st century"...!-). Just like SICP made it worthwhile to learn a little Scheme even if you'd never use it in production, so does CTMCP (acronym for this new book by Van Roy and Haridi) work for Oz, it appears to me.
......very interesting, but it wants to make me install emacs. :(
Alex
--
Robin Becker
Alex Martelli wrote: Nick Coghlan <nc******@iinet.net.au> wrote: ...
Perhaps something like:
accepts_func( (def (a, b, c) to f(a) + o(b) - o(c)) )
Nice, except I think 'as' would be better than 'to'. 'as' should be a full keyword in 3.0 anyway (rather than a surprisingly-NOT-keyword like today), and "define something as somethingelse" seems marginally more readable to me than "define something to somethingelse" anyway.
I actually flipped back and forth between preferring 'as' and 'to' while writing
the message.
It was the mathematical phrasing of "f is a function from R to R" (replacing the
capital R's with the symbol for the real numbers) that first made me think of
'to', since I was trying to emphasise the parallels with mathematical functions.
(To my mind, theoretical mathematics is one of the areas with significant
legitimate uses for lambda functions).
The '->' suggestion had a similar source.
The way I'd read the 'to' version out loud when explaining to someone what the
code did:
"DEFine an anonymous function from arguments a, b and c TO the value f of a plus
o of b minus o of c"
or the short version:
"DEFine a function from a, b and c TO f a plus o b minus o c"
As an even simpler example, (def (x) to x * x) would be "define a function from
x to x squared". (def () to <whatever>) would be "define a function from no
arguments to <whatever>"
'as' already implies renaming semantics due to from-style imports. In Py3k, it's
likely to pick up the naming duties in except clauses as well (i.e. "except
ValueError, TypeError as ex:").
'as' is also a candidate for optional static typing and adaptation (and
hopefully someone will talk Guido out of his punctuation happy version of that!).
I eventually decided that using 'as' for anonymous functions as well would just
be plain confusing.
Cheers,
Nick.
--
Nick Coghlan | nc******@email.com | Brisbane, Australia
--------------------------------------------------------------- http://boredomandlaziness.skystorm.net
Nick Coghlan wrote: Indeed, lambda as it currently stands will disappear for the Python 2.x series.
Will NOT disappear. I repeat, will NOT disappear.
Cheers,
Nick.
Damn those missing negators. . .
--
Nick Coghlan | nc******@email.com | Brisbane, Australia
--------------------------------------------------------------- http://boredomandlaziness.skystorm.net
On Thu, 23 Dec 2004 13:47:49 +0100, Alex Martelli <al*****@yahoo.com> wrote: Nick Coghlan <nc******@iinet.net.au> wrote: ... Perhaps something like:
accepts_func( (def (a, b, c) to f(a) + o(b) - o(c)) )
Nice, except I think 'as' would be better than 'to'. 'as' should be a full keyword in 3.0 anyway (rather than a surprisingly-NOT-keyword like today), and "define something as somethingelse" seems marginally more readable to me than "define something to somethingelse" anyway.
I'm sorry, but I dislike this quite a bit, 'def arglist as expression'
just doesn't fit right for me.
After reading the discussion, and trying to glean answers to my
original questions, I realise that there's a pragmatic way of doing
the things that I mentally 'require' lambda for, without using lambda
at all. I might try and catalog lambda patterns and their alternatives
at some point.
Alex, thankyou for the feedback concerning the misuse of lambda. I
consider prevention of misuse to be much more important than the
denial of use. I recognise fully the frustration you must experience
when you see map(lambda x:f(x).
I think it is important to voice concern, and I recieved not a few
'me-too's in reply to this thread. But at the end of the day, I'm not
against removing lambda in py3k.
slightly-less-concerned-ly yr's
Stephen Thorne.
Stephen Thorne <st************@gmail.com> wrote in
news:ma**************************************@pyth on.org: Hi guys,
I'm a little worried about the expected disappearance of lambda in python3000. I've had my brain badly broken by functional programming in the past, and I would hate to see things suddenly become harder than they need to be.
An example of what I mean is a quick script I wrote for doing certain actions based on a regexp, which I will simlify in this instance to make the pertanant points more relevent.
{ 'one': lambda x:x.blat(), 'two': lambda x:x.blah(), }.get(someValue, lambda x:0)(someOtherValue)
The alternatives to this, reletively simple pattern, which is a rough parallel to the 'switch' statement in C, involve creating named functions, and remove the code from the context it is to be called from (my major gripe).
So, the questions I am asking are: Is this okay with everyone? Does anyone else feel that lambda is useful in this kind of context? Are there alternatives I have not considered?
Not addressing lambdas per se, but something similar to your pseudo-
switch statement can be done without using them at all. One way might
be to use a function dictionary wrapped in an accessor function, such
as this:
def dofns(key):
fd2 = {
0:'print "Key 0"',
1:'print "one"',
4:"\n".join(['for ix in range(15):',
' print "%s%d" % (" "*ix,ix)']),
}
try:
exec(fd2[key])
except KeyError:
print 'Key',key,'not found'
The keys can as easily be strings, of course. One virtue of this
method is that it allows multi-line statements and looping (as in fd2
[4]).
Now the actual 'switch' statement becomes as simple as:
dofns(key)
If there are parameters involved, this solution becomes a little
tackier. One way might be something like:
def dofns(key,**kws):
fd2 = {
0:'print "Key 0"',
1:'print "one"',
2:"\n".join(['n=kws["name"]','x=kws["x"]',
'y=kws["y"]','print "%s:"%n,x,y']),
3:"\n".join(['val=kws["x"]*7 + kws["y"]',
'print kws["x"],kws["y"],val']),
4:"\n".join(['for ix in range(kws["x"]):',
' print "%s%d" % (" "*ix,ix)']),
5:'exec(fd2[3])',
6:"\n".join(['print kws["z"],',
'dofns(3,x=13,y=22)']),
}
try:
exec(fd2[key])
except KeyError:
print 'Key',key,'not found'
# switch (key kwdparms)
for key in [0, 1,2,3,4,5,6,7]:
dofns(key,name='Gladys',y=50,x=8,z=34)
You could remove the function dictionary from the wrapper and use it
similarly to your example, but I find that less readable.
exec({
multi-line dictionary definition
}[key] parms) # what were we doing again? Oh! exec!
Anyway, for those who use lambdas, this approach is likely to be
unappealing. For those who find lambdas puzzling, it may be an
alternative, at least for a way to handle the switch equivalent.
--
rzed
Keith> My personal gripe is this. I think the core language, as of 2.3
Keith> or 2.4 is very good, has more features than most people will ever
Keith> use, and they (Guido, et al.) can stop tinkering with it now and
Keith> concentrate more on the standard libraries.
What keeps you from being part of the "et al"? This is open source, after
all. Note that there's more to be done than simply writing code.
Documentation always needs attention. Bug reports and patches always need
to be verified and vetted. Even mundane stuff like managing mailing lists
detracts from the time the most experienced people could spend writing code
you might not be able to do. There's lots to do. Start here: http://www.python.org/dev/
Go anywhere. <wink>
Skip
Craig> IMO the reference behaviour of functions in the C API could be
Craig> clearer. One often has to simply know, or refer to the docs, to
Craig> tell whether a particular call steals a reference or is reference
Craig> neutral. Take, for example, PyDict_SetItemString vs
Craig> PyMapping_SetItemString . Is it obvious that one of those steals
Craig> a reference, and one is reference neutral? Is there any obvious
Craig> rationale behind this?
Sure. PyDict_SetItemString was first written very early on in Python's
development (actually, it was originally called something
namespace-ly-dangerous like dict_setstring). PyMapping_SetItemString (part
of the abstract objects api) was written later with an emphasis on the
consistency of behavior you desire. You're generally going to be better off
sticking with the abstract objects api. For obvious reasons of backward
compatibility, the concrete apis (PyDict_*, PyList_*, etc) must be retained.
Skip
I have this book called TEXT PROCESSING IN PYTHON by David Mertz on
hand, it is a good book and in the first chapter it is really a show
room for higher-order functions which I may now cite to remind you of
the FLEXIBILITY of this keyword.
''' combinatorial.py
from operator import mul, add, truth
apply_each = lambda funs, args = []: map(apply, fns, [args]*len(fns))
bools = lambda lst: mpa(truth, lst)
bool_each = lambda fns, args = []: bools(apply_each(fns, args))
conjoin = lambda fns, args = []: reduce(mul, bool_each(fns, args))
all = lambda fns: lambda arg, fns = fns: conjoin(fns, (arg,))
both = lambda f,g: all(f(f,g))
all3 = lambda f,g,h: all((f,g,h))
and_ = lambda f,g: lambda x, f=f, g=g: f(x) and g(x)
disjoin = lambda fns, args = []: reduce(add, bool_each(fns, args))
some = lambda fns: lambda arg, fns = fns: disjoin(fns, (arg,))
either = lambda f,g: some((f,g))
anyof3 = lambda f,g,h: some((f,g,h))
compose = lambda f,g: lambda x, f=f, g=g: f(g(x))
compose3 = lambda f,g,h: lambda x, f=f, g=g, h=j: f(g(h(x)))
ident = lambda x:x
'''
And some other lambda function usage is when they are treated like
objects, they can also fit in generators... THIS IS ART. Well, some may
argue that it is hard for people to maintain these codes, put the
problem to Haskell people and see how they respond(at least you don't
need to scroll up and down...) Oh! So when did python adopt simplicity
rather than verbosity?
Q: It simply doesn't FIT.
A: OK, OK, get all these map, filter stuff away, and go python, go and
get mixed with them. ta********@gmail.com wrote: I have this book called TEXT PROCESSING IN PYTHON by David Mertz on hand, it is a good book and in the first chapter it is really a show room for higher-order functions which I may now cite to remind you of the FLEXIBILITY of this keyword.
I'm not exactly sure what you mean by "flexibility"; all of these
examples can be written without lambdas:
apply_each = lambda funs, args = []: map(apply, fns, [args]*len(fns))
def apply_each(fns, args=[]):
return [fn(*args) for fn in fns]
bools = lambda lst: mpa(truth, lst)
def bools(lst):
return [bool(x) for x in lst]
bool_each = lambda fns, args = []: bools(apply_each(fns, args))
def bool_each(fns, args=[]):
return bools(apply_each(fns, args))
conjoin = lambda fns, args = []: reduce(mul, bool_each(fns, args))
def conjoin(fns, args=[]):
reduce(mul, bool_each(fns, args))
all = lambda fns: lambda arg, fns = fns: conjoin(fns, (arg,))
def all(fns):
def _(arg):
return conjoin(fns, (arg,))
return _
both = lambda f,g: all(f(f,g))
def both(f, g):
return all(f(f,g))
all3 = lambda f,g,h: all((f,g,h))
def all3(f, g, h):
return all((f,g,h))
and_ = lambda f,g: lambda x, f=f, g=g: f(x) and g(x)
def and_(f, g):
def _(x):
return f(x) and g(x)
return _
disjoin = lambda fns, args = []: reduce(add, bool_each(fns, args))
def disjoin(fns, args=[]):
return reduce(add, bool_each(fns, args))
some = lambda fns: lambda arg, fns = fns: disjoin(fns, (arg,))
def some(fns):
def _(arg):
return disjoin(fns, (arg,))
return _
either = lambda f,g: some((f,g))
def either(f, g):
return some((f,g))
anyof3 = lambda f,g,h: some((f,g,h))
def anyof3(f, g, h):
return some((f,g,h))
compose = lambda f,g: lambda x, f=f, g=g: f(g(x))
def compose(f, g):
def _(x):
return f(g(x))
return _
compose3 = lambda f,g,h: lambda x, f=f, g=g, h=j: f(g(h(x)))
def compose3(f, g, h):
def _(x):
return f(g(h(x)))
return _
ident = lambda x:x
def ident(x):
return x
Steve
Thanks. :-) Two remarks.
o One-liner fits the eyes & brains of a portion of people.
o Why don't you just say all python can be written in equivalent java,
can I assert that Guido doesn't want to get mixed with those
mainstream>? ta********@gmail.com wrote: o Why don't you just say all python can be written in equivalent java,
your argumentation skills are awesome.
</F>
"jfj" wrote: Personally I'm not a fan of functional programming but lambda *is* useful when I want to say for example:
f (callback=lambda x, y: foo (y,x))
I don't believe it will ever disappear.
agreed. there's no reason to spend this christmas rewriting your programs, folks.
I'm sure you all have better things to do ;-)
cheers /F
<ta********@gmail.com> wrote: Thanks. :-) Two remarks. o One-liner fits the eyes & brains of a portion of people.
True! So, personally, I'd rather code, e.g.,
def bools(lst): return map(bool, lst)
rather than breal this one-liner into two lines at the colon, as per
standard Python style. However, uniformity has its advantages, too; I'm
ready for the one-liner style to be outlawed in Python 3.0, purely in
the advantage of uniformity.
Note that lambda is utterly useless here, be it for one-liners or not.
Alex
Fernando Perez said unto the world upon 2004-12-23 14:42: Alex Martelli wrote:
I don't know what it IS about lambda that prompts so much dubious to absurd use, but that's what I observed. I don't know if that plays any role in Guido's current thinking, though -- I have no idea how much "dubious Python" he's had to struggle with.
Just a side comment, unrelated to the lambda issue: it just occurred to me that it might be very useful to have a collection of 'dubious python' available somewhere. Just as it is great for everyone to see good code in action, it is equally enlightening to see examples of bad practices (preferably with an explanation of why they are bad and the good alternatives).
I suspect after your CB2 experience, you are in a uniquely well-qualified position to have such a collection handy. Whether you feel inclined to spend the necessary time assembling it for public consumption is a different story :) But I think it would be a very valuable resource, and a great way to point newbies to 'mandatory reading' before they travel down the same blind alleys for the n-th time.
Cheers, and happy holidays,
f
Hi all,
+1
I would find this really useful!
I'm much more likely to be among the benefited than the benefactors.
This could be a lot of work for one person. Thus, it seems like a good
thing for a wiki, so as to spread the weight around. With that in mind,
I created <http://www.python.org/moin/DubiousPython>. I hope this seems
like a good idea to others, particularly those more able to extend it
than I. (I'd also be grateful if others could remove any feet than I
might have inadvertently put into my mouth on the wiki page.)
Best to all,
Brian vdB readability. Pythonic lambdas are just syntactic sugar in practice,
Paul> Actually it's the other way around: it's named functions that are
Paul> the syntactic sugar.
While I'm sure it can be done, I'd hate to see a non-trivial Python program
written with lambda instead of def. (Take a crack at pystone if you're
interested.)
Skip
Skip Montanaro wrote: Keith> My personal gripe is this. I think the core language, as of 2.3 Keith> or 2.4 is very good, has more features than most people will ever Keith> use, and they (Guido, et al.) can stop tinkering with it now and Keith> concentrate more on the standard libraries.
What keeps you from being part of the "et al"?
as I've proven from time to time, joining the "et al" and *not* tinkering with
the language doesn't mean that the language stays where it is.
(I've said it before, and I'll say it again: native unicode and generators are
the only essential additions I've seen since 1.5.2, with properties and sub-
classable C types sharing a distant third place. the rest of the stuff has had
zero impact on my ability to write solid code in no time at all, and negative
impact on my ability to download stuff that others have written and expect
it to work in any Python version but the latest...)
</F>
Alex Martelli wrote: I don't know what it IS about lambda that prompts so much dubious to absurd use, but that's what I observed. I don't know if that plays any role in Guido's current thinking, though -- I have no idea how much "dubious Python" he's had to struggle with.
Just a side comment, unrelated to the lambda issue: it just occurred to me that
it might be very useful to have a collection of 'dubious python' available
somewhere. Just as it is great for everyone to see good code in action, it is
equally enlightening to see examples of bad practices (preferably with an
explanation of why they are bad and the good alternatives).
I suspect after your CB2 experience, you are in a uniquely well-qualified
position to have such a collection handy. Whether you feel inclined to spend
the necessary time assembling it for public consumption is a different
story :) But I think it would be a very valuable resource, and a great way to
point newbies to 'mandatory reading' before they travel down the same blind
alleys for the n-th time.
Cheers, and happy holidays,
f
<ta********@gmail.com> wrote in message
news:11*********************@z14g2000cwz.googlegro ups.com... Well, you can say apply() is 'deprecated' now,
What is deprecated is the spelling, not the concept or functionality.
As far as I know, apply(func, args) is exactly equivalent to func(*args).
If the latter had been invented in the beginning and you had learned it as
Python's spelling of the apply concept, you might never miss the 'apply'
spelling.
Terry J. Reedy
Terry Reedy wrote: As far as I know, apply(func, args) is exactly equivalent to func(*args).
After playing around a bit I did find one difference in
the errors they can create. def count():
.... yield 1
.... apply(f, count())
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: apply() arg 2 expected sequence, found generator f(*count())
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: len() of unsized object
That led me to the following
class Blah:
.... def __len__(self):
.... return 10
.... def __getitem__(self, i):
.... if i == 0: return "Hello!"
.... raise IndexError, i
.... blah = Blah() len(*blah)
6 apply(len, *blah)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: len() takes exactly one argument (6 given)
Is that difference a bug?
Andrew da***@dalkescientific.com
Nick Coghlan <nc******@iinet.net.au> writes: jfj wrote: Python 3.0 will be a case of "OK, let's take the things we learned were good and keep them, and throw away the things we realised were bad"
Undoubtedly, the two languages will co-exist for quite some time.
Perl 6.0 is going to include even more drastic changes. It will also
include a Perl 5.x interpreter, and will have to be switched to 6.0
mode by a magic cookie of some kind in the source. Possibly Python 3.0
could do something similar. Use the same byte code engine, and a
compiler switch that enables the gotchas. Or maybe
"from __past__ import gotchas"
<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Andrew Dalke wrote: Terry Reedy wrote:
As far as I know, apply(func, args) is exactly equivalent to func(*args).
After playing around a bit I did find one difference in the errors they can create.
def count(): ... yield 1 ... apply(f, count()) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: apply() arg 2 expected sequence, found generator f(*count()) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: len() of unsized object
No question that they report different errors in the face of being given
unsupported input.
That led me to the following
<snip> blah = Blah() len(*blah) 6 apply(len, *blah) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: len() takes exactly one argument (6 given)
Is that difference a bug?
They do two different things. I think you have a spurious * in the call
to apply. The apply above is equivalent to len('H', 'e', 'l', 'l', 'o', '!')
Which gives the same error:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: len() takes exactly one argument (6 given)
If the * is removed, it works correctly:
apply(len, blah)
6
--
Benji York be***@benjiyork.com
"Andrew Dalke" <da***@dalkescientific.com> wrote in message
news:pa****************************@dalkescientifi c.com... Terry Reedy wrote: As far as I know, apply(func, args) is exactly equivalent to func(*args). After playing around a bit I did find one difference in the errors they can create.
Ok, add 'assuming that func and args are a valid callable and sequence
respectively.' Error messages are not part of the specs, and may change
for the same code from version to version. def count(): ... yield 1 ... apply(f, count()) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: apply() arg 2 expected sequence, found generator f(*count()) Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: len() of unsized object That led me to the following class Blah: ... def __len__(self): ... return 10 ... def __getitem__(self, i): ... if i == 0: return "Hello!" ... raise IndexError, i ... blah = Blah() len(*blah) 6 apply(len, *blah)
To be equivalent to len(*blah), this should be apply(len, blah), no *.
apply(len, blah)
6 #Py2.2
Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: len() takes exactly one argument (6 given)
Is that difference a bug?
In your input, yes ;-)
Terry J. Reedy
Mike> Perl 6.0 is going to include even more drastic changes. It will
Mike> also include a Perl 5.x interpreter, and will have to be switched
Mike> to 6.0 mode by a magic cookie of some kind in the source. Possibly
Mike> Python 3.0 could do something similar.
-1
Things are complex enough as it is. Maintaining two interpreters that have
to somehow comingle would be worse. Maintain Python 2.x as a separate
release for a period of time after Python 3.0 is released (a couple years,
anyway, maybe longer), but don't mix the two.
Skip
Benji York wrote: They do two different things. I think you have a spurious * in the call to apply. The apply above is equivalent to
D'oh! This cold has definitely made me error prone the last
couple of days. Yesterday I managed to leave my cell phone
in my pants pocket along with a couple pens. My new phone has
a color screen and a camera.
Andrew da***@dalkescientific.com This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Oliver Fromme |
last post by:
Hi,
I'm trying to write a Python function that parses
an expression and builds a function tree from it
(recursively).
During parsing, lambda functions for the the terms
and sub-expressions...
|
by: Skip Montanaro |
last post by:
Stephen> {
Stephen> 'one': lambda x:x.blat(),
Stephen> 'two': lambda x:x.blah(),
Stephen> }.get(someValue, lambda x:0)(someOtherValue)
One thing to remember is that function calls in Python...
|
by: Steven Bethard |
last post by:
I thought it might be useful to put the recent lambda threads into
perspective a bit. I was wondering what lambda gets used for in "real"
code, so I grepped my Python Lib directory. Here are some...
|
by: Tom Anderson |
last post by:
Comrades,
During our current discussion of the fate of functional constructs in
python, someone brought up Guido's bull on the matter:
http://www.artima.com/weblogs/viewpost.jsp?thread=98196
...
|
by: taylorcarr |
last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
| |