Re: [Tutor] Defining variable arguments in a function in python

2018-12-29 Thread Avi Gross
I have my usual off the wall answer.

OK, seriously. Not exactly an answer but perhaps an experiment.

The question was how to have a non-named first argument to a function with
some form of default. 

As was pointed out, this does not fit well with being able to have python
gather all positional arguments after it as well as all keyword arguments.

But bear with me. Say I want to have a way to signal that I want a default
for the first argument?

An empty comma fails but try this:

def hello(a, *n, **m) :
if a == None: a=5
print(a)
print(*n)
print(**m)

The above says "a" is required. It can be followed by any number of
positional args gathered into "n" and any number of keyword args gathered
into "m"

But what if you define a sentinel to watch for such as None, in the above?

If the first and only arg is None, it switches to the default of 5.

>>> hello(None)
5

Add a few more args and it properly takes it.

>>> hello(1,2,3)
1
2 3

Switch the first to None:

>>> hello(None,2,3)
5
2 3

The keywords don't work for print but no biggie.

But is this only for None? What I say any negative arg is replaced by 5?

def hello(a, *n, **m) :
if a < 0: a=5
print(a)
print(*n)

Seems to work fine:

>>> hello(-666, 2, 3, 4)
5
2 3 4

And I wonder if we can use the darn ellipsis for something useful?

def hello(a, *n, **m) :
if a == ... : a=5
print(a)
print(*n)

>>> hello(1,2,3)
1
2 3
>>> hello(...,2,3)
5
2 3
>>> hello(...,2,...)
5
2 Ellipsis

OK, all kidding aside, is this helpful? I mean if you want a function where
you MUST give at least one arg and specify the first arg can be some odd
choice (as above) and then be replaced by  a default perhaps it would be
tolerable to use None or an Ellipsis.

Or on a more practical level, say a function wants an input from 1 to 10.
The if statement above can be something like:

>>> def hello(a, *n, **m) :
if not (1 <= a <= 10) : a=5
print(a)
print(*n)


>>> hello(1,2,3)
1
2 3
>>> hello(21,2,3)
5
2 3
>>> hello(-5,2,3)
5
2 3
>>> hello("infinity and beyond",2,3)
Traceback (most recent call last):
  File "", line 1, in 
hello("infinity and beyond",2,3)
  File "", line 2, in hello
if not (1 <= a <= 10) : a=5
TypeError: '<=' not supported between instances of 'int' and 'str'

As expected, it may take a bit more code such as checking if you got an int
but the idea may be solid enough. It is NOT the same as having a default
from the command line but it may satisfy some need.

Other than that, I fully agree that the current python spec cannot support
anything like this in the function definition.

Side note: To spare others, I sent Steven alone a deeper reply about ways to
select random rows from a pandas DataFrame. I am still learning how pandas
works and doubt many others here have any immediate needs.









-Original Message-
From: Tutor  On Behalf Of
Steven D'Aprano
Sent: Saturday, December 29, 2018 6:02 AM
To: tutor@python.org
Subject: Re: [Tutor] Defining variable arguments in a function in python

On Sat, Dec 29, 2018 at 11:42:16AM +0530, Karthik Bhat wrote:
> Hello,
> 
> I have the following piece of code. In this, I wanted to make 
> use of the optional parameter given to 'a', i.e- '5', and not '1'
> 
> def fun_varargs(a=5, *numbers, **dict):
[...]
> 
> fun_varargs(1,2,3,4,5,6,7,8,9,10,Jack=111,John=222,Jimmy=333)
> 
> How do I make the tuple 'number' contain the first element to be 1 and not
2?


You can't. Python allocates positional arguments like "a" first, and only
then collects whatever is left over in *numbers. How else would you expect
it to work? Suppose you called:

fun_varargs(1, 2, 3)

wanting a to get the value 1, and numbers to get the values (2, 3). And then
immediately after that you call 

fun_varargs(1, 2, 3)

wanting a to get the default value 5 and numbers to get the values (1, 2,
3). How is the interpreter supposed to guess which one you wanted?

If you can think of a way to resolve the question of when to give "a" 
the default value, then we can help you program it yourself:


def func(*args, **kwargs):
if condition:
# When?
a = args[0]
numbers = args[1:]
else:
a = 5  # Default.
numbers = args
...

But writing that test "condition" is the hard part.




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

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


Re: [Tutor] decomposing a problem

2018-12-29 Thread Avi Gross

Steven,

A more practical answer about splitting a data frame is to import modules such 
as for machine learning. 

Import sklearn.model_selection

Then use train_test_split() to return 4 parts. Not sure what answers you need 
and why here. Plenty of ways and tools exist to specify choosing percentages to 
partition by or other ways.


Sent from AOL Mobile Mail
On Saturday, December 29, 2018 Avi Gross  wrote:
Steven,

As I head out the door, I will sketch it.

Given a data.frame populated with N rows and columns you want to break it
into training and test data sets.

In a data.frame, you can refer to a row by using an index like 5 or 2019.
You can ask for the number of rows currently in existence. You can also
create an array/vector of length N consisting of instructions that can tell
which random rows of the N you want and which you don't. For the purposes of
this task, you choose random numbers in the range of N and either keep the
numbers as indices or as a way to mark True/False in the vector. You then
ask for a new data.frame made by indexing the existing one using the vector.
You can then negate the vector and ask for a second new data.frame indexing
it.

Something close to that.

Or, you can simply add the vector as a new column in the data.frame in some
form. It would then mark which rows are to be used for which purpose. Later,
when using the data, you include a CONDITION that row X is true, or
whatever.



-Original Message-
From: Tutor  On Behalf Of
Steven D'Aprano
Sent: Friday, December 28, 2018 11:12 PM
To: tutor@python.org
Subject: Re: [Tutor] decomposing a problem

On Fri, Dec 28, 2018 at 10:39:53PM -0500, Avi Gross wrote:
> I will answer this question then head off on vacation.

You wrote about 140 or more lines, but didn't come close to answering the
question: how to randomly split data from a dictionary into training data
and reserved data.



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

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


Re: [Tutor] Defining variable arguments in a function in python

2018-12-29 Thread Peter Otten
Karthik Bhat wrote:

> Hello,
> 
> I have the following piece of code. In this, I wanted to make use
> of the optional parameter given to 'a', i.e- '5', and not '1'
> 
> def fun_varargs(a=5, *numbers, **dict):
> print("Value of a is",a)
> 
> for i in numbers:
> print("Value of i is",i)
> 
> for i, j in dict.items():
> print("The value of i and j are:",i,j)
> 
> fun_varargs(1,2,3,4,5,6,7,8,9,10,Jack=111,John=222,Jimmy=333)
> 
> How do I make the tuple 'number'  contain the first element to be 1 and
> not 2?

One option is to change the function signature to

def fun_varargs(*numbers, a=5, **dict):
...

which turns `a` into a keyword-only argument.

>>> fun_varargs(1, 2, 3, foo="bar"):
Value of a is 5
Value of i is 1
Value of i is 2
Value of i is 3
The value of i and j are: foo bar

To override the default you have to specify a value like this:

>>> fun_varargs(1, 2, 3, foo="bar", a=42)
Value of a is 42
Value of i is 1
Value of i is 2
Value of i is 3
The value of i and j are: foo bar


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


Re: [Tutor] decomposing a problem

2018-12-29 Thread Avi Gross
Steven,

As I head out the door, I will sketch it.

Given a data.frame populated with N rows and columns you want to break it
into training and test data sets.

In a data.frame, you can refer to a row by using an index like 5 or 2019.
You can ask for the number of rows currently in existence. You can also
create an array/vector of length N consisting of instructions that can tell
which random rows of the N you want and which you don't. For the purposes of
this task, you choose random numbers in the range of N and either keep the
numbers as indices or as a way to mark True/False in the vector. You then
ask for a new data.frame made by indexing the existing one using the vector.
You can then negate the vector and ask for a second new data.frame indexing
it.

Something close to that.

Or, you can simply add the vector as a new column in the data.frame in some
form. It would then mark which rows are to be used for which purpose. Later,
when using the data, you include a CONDITION that row X is true, or
whatever.



-Original Message-
From: Tutor  On Behalf Of
Steven D'Aprano
Sent: Friday, December 28, 2018 11:12 PM
To: tutor@python.org
Subject: Re: [Tutor] decomposing a problem

On Fri, Dec 28, 2018 at 10:39:53PM -0500, Avi Gross wrote:
> I will answer this question then head off on vacation.

You wrote about 140 or more lines, but didn't come close to answering the
question: how to randomly split data from a dictionary into training data
and reserved data.



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

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


Re: [Tutor] Defining variable arguments in a function in python

2018-12-29 Thread Steven D'Aprano
On Sat, Dec 29, 2018 at 11:42:16AM +0530, Karthik Bhat wrote:
> Hello,
> 
> I have the following piece of code. In this, I wanted to make use
> of the optional parameter given to 'a', i.e- '5', and not '1'
> 
> def fun_varargs(a=5, *numbers, **dict):
[...]
> 
> fun_varargs(1,2,3,4,5,6,7,8,9,10,Jack=111,John=222,Jimmy=333)
> 
> How do I make the tuple 'number' contain the first element to be 1 and not 2?


You can't. Python allocates positional arguments like "a" first, and 
only then collects whatever is left over in *numbers. How else would you 
expect it to work? Suppose you called:

fun_varargs(1, 2, 3)

wanting a to get the value 1, and numbers to get the values (2, 3). And 
then immediately after that you call 

fun_varargs(1, 2, 3)

wanting a to get the default value 5 and numbers to get the values 
(1, 2, 3). How is the interpreter supposed to guess which one you 
wanted?

If you can think of a way to resolve the question of when to give "a" 
the default value, then we can help you program it yourself:


def func(*args, **kwargs):
if condition:
# When?
a = args[0]
numbers = args[1:]
else:
a = 5  # Default.
numbers = args
...

But writing that test "condition" is the hard part.




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


Re: [Tutor] Defining variable arguments in a function in python

2018-12-29 Thread Alan Gauld via Tutor
On 29/12/2018 06:12, Karthik Bhat wrote:

> def fun_varargs(a=5, *numbers, **dict):
> print("Value of a is",a)
> 
> for i in numbers:
> print("Value of i is",i)
> 
> for i, j in dict.items():
> print("The value of i and j are:",i,j)
> 
> fun_varargs(1,2,3,4,5,6,7,8,9,10,Jack=111,John=222,Jimmy=333)
> 
> How do I make the tuple 'number'  contain the first element to be 1 and not
> 2?

You need to provide a value for a.

The default 5 will only be used if the function is called
without *any* arguments. Otherwise it will always take
the first argument value. So, if you want a to be 5 and
then provide a tuple etc you must explicitly pass a 5 in:

fun_varargs(5, 1,2,3,4,5,6,7,8,9,10, Jack=111,John=222,Jimmy=333)


HTH
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


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


[Tutor] Defining variable arguments in a function in python

2018-12-29 Thread Karthik Bhat
Hello,

I have the following piece of code. In this, I wanted to make use
of the optional parameter given to 'a', i.e- '5', and not '1'

def fun_varargs(a=5, *numbers, **dict):
print("Value of a is",a)

for i in numbers:
print("Value of i is",i)

for i, j in dict.items():
print("The value of i and j are:",i,j)

fun_varargs(1,2,3,4,5,6,7,8,9,10,Jack=111,John=222,Jimmy=333)

How do I make the tuple 'number'  contain the first element to be 1 and not
2?


-- 
Regards,
Karthik A Bhat
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor