Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding function Subsets to the mathics #685

Merged
merged 5 commits into from
Sep 29, 2020
Merged

Conversation

larionvn
Copy link
Contributor

Adding Subsets[]

Copy link
Member

@sn6uv sn6uv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Just a couple of edge cases and cleanups.

if not n.get_head_name() == 'System`Integer' or n.to_python() < 0 :
return evaluation.message('Subsets', 'nninfseq', expr)

tlen = int(n.to_python())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have a utility method for this, n.get_int_value() which returns an int or None.


tlen = int(n.to_python())

nested_list = [Expression('List', *c) for i in range(0, tlen + 1) for c in combinations(tlist, i)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

range(0, tlen +1) is range(tlen+1)


if n_len == 1:
elem1 = n_python[0]
if not n.leaves[0].get_head_name() == "System`Integer" or elem1 < 0 :
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not all values can be converted to_python so elem1 may be None here. Better to use get_int_value() here too.

if n_len == 2:
elem1 = n_python[0]
elem2 = n_python[1]
if not n.leaves[0].get_head_name() == "System`Integer" or not n.leaves[1].get_head_name() == "System`Integer" or elem1 < 0 or elem2 < 0 :
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_int_value()

step_n = 1

if n_len == 3:
if not n.leaves[0].get_head_name() == "System`Integer" or not n.leaves[1].get_head_name() == "System`Integer" or not n.leaves[2].get_head_name() == "System`Integer" :
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_int_value()

tlist = [x for x in list.leaves]
expr = Expression('Subsets', list, n)

if not n.get_head_name() == 'System`Integer' or n.to_python() < 0 :
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_int_value(), see below.

@larionvn
Copy link
Contributor Author

larionvn commented Apr 4, 2017

Thanks for your feedback @sn6uv . I've just pushed the latest commit for adding Subsets[] with some changes as your recommendations. Please take a look and give me some feedback if any. Thanks in advance!

mathics/builtin/combinatorial.py Outdated Show resolved Hide resolved
return evaluation.message('Subsets', 'nninfseq', expr)

tlen = int(n.to_python())
nested_list = [Expression('List', *c) for i in range(n_value + 1) for c in combinations([x for x in list.leaves], i)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... for c in combinations(list.leaves, ....?

return self.apply(list, evaluation)

n_python = n.to_python()
n_len = len(n_python)
n_len = n.leaves.__len__()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

len(n.leaves)?

elem1 = n_python[0]
if not n.leaves[0].get_head_name() == "System`Integer" or elem1 < 0 :
elem1 = n.leaves[0].get_int_value()
if not elem1 or elem1 < 0 :
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not elem1 will also be true if elem1 is 0, use elem1 is not None

else:
return evaluation.message('Subsets', 'nninfseq', expr)

nested_list = [Expression('List', *c) for i in range(min_n, max_n, step_n) for c in combinations(tlist, i)]
nested_list = [Expression('List', *c) for i in range(min_n, max_n, step_n) for c in combinations([x for x in list.leaves], i)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

combinations(list.leaves... here too

elem1 = n.leaves[0].get_int_value()
elem2 = n.leaves[1].get_int_value()
elem3 = n.leaves[2].get_int_value()
if elem1 is None or elem2 is None or elem3 is None :
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also be checking that elem1 and elem2 aren't negative?

max_n = elem2 + 1
step_n = 1

elif n_len == 3:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs for this case missing?

@larionvn
Copy link
Contributor Author

Thanks for your feedback @sn6uv . I've just pushed the latest source code with the following changes:

  • Update code so that Subsets can find any subsets from any head
  • Adding some test cases and docs as your recommendations.

@rocky
Copy link
Member

rocky commented Sep 16, 2020

I am not seeing anything left unresolved. What am I missing?

@rocky rocky merged commit 2cfa1f1 into mathics:master Sep 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants