Hello community, here is the log from the commit of package python-python-louvain for openSUSE:Factory checked in at 2020-07-16 12:15:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-python-louvain (Old) and /work/SRC/openSUSE:Factory/.python-python-louvain.new.3592 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-python-louvain" Thu Jul 16 12:15:05 2020 rev:5 rq:820913 version:0.14 Changes: -------- --- /work/SRC/openSUSE:Factory/python-python-louvain/python-python-louvain.changes 2020-05-20 18:48:01.141626945 +0200 +++ /work/SRC/openSUSE:Factory/.python-python-louvain.new.3592/python-python-louvain.changes 2020-07-16 12:16:25.450841657 +0200 @@ -1,0 +2,8 @@ +Tue Jul 14 13:44:51 UTC 2020 - Marketa Calabkova <mcalabk...@suse.com> + +- update to version 0.14 + * Replace RandomState.permutation with RandomState.shuffle + * include resolution parameter in __modularity calculation + * docs fixes + +------------------------------------------------------------------- Old: ---- python-louvain-0.13.tar.gz New: ---- python-louvain-0.14.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-python-louvain.spec ++++++ --- /var/tmp/diff_new_pack.I5gX2D/_old 2020-07-16 12:16:26.674842895 +0200 +++ /var/tmp/diff_new_pack.I5gX2D/_new 2020-07-16 12:16:26.678842898 +0200 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-python-louvain -Version: 0.13 +Version: 0.14 Release: 0 Summary: Louvain algorithm for community detection License: BSD-3-Clause ++++++ python-louvain-0.13.tar.gz -> python-louvain-0.14.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-louvain-0.13/PKG-INFO new/python-louvain-0.14/PKG-INFO --- old/python-louvain-0.13/PKG-INFO 2018-12-21 10:07:17.000000000 +0100 +++ new/python-louvain-0.14/PKG-INFO 2020-04-06 14:39:45.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: python-louvain -Version: 0.13 +Version: 0.14 Summary: Louvain algorithm for community detection Home-page: https://github.com/taynaud/python-louvain Author: Thomas Aynaud diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-louvain-0.13/README.rst new/python-louvain-0.14/README.rst --- old/python-louvain-0.13/README.rst 2018-11-28 15:48:23.000000000 +0100 +++ new/python-louvain-0.14/README.rst 2020-04-06 14:21:27.000000000 +0200 @@ -1,30 +1,42 @@ Louvain Community Detection =========================== +.. image:: https://travis-ci.org/taynaud/python-louvain.svg?branch=master + :target: https://travis-ci.org/taynaud/python-louvain + +.. image:: https://readthedocs.org/projects/python-louvain/badge/?version=latest + :target: http://python-louvain.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + Installing ---------- -To build and install run from source:: +To build and install run from source + +.. code-block:: shell + + python setup.py install - python setup.py install +You can also install from pip with -You can also install from pip with:: +.. code-block:: shell pip install python-louvain The package name on pip is `python-louvain` but it is imported as `community` in python. You will find documentation about this module at -http://python-louvain.readthedocs.io/ +`http://python-louvain.readthedocs.io/ <http://python-louvain.readthedocs.io/>`_ Usage ----- -To use as a python library:: +To use as a python library +.. code-block:: python - import community + import community as community_louvain import networkx as nx import matplotlib.pyplot as plt @@ -32,7 +44,7 @@ G = nx.erdos_renyi_graph(30, 0.05) #first compute the best partition - partition = community.best_partition(G) + partition = community_louvain.best_partition(G) #drawing size = float(len(set(partition.values()))) @@ -51,22 +63,26 @@ -There is also a command line:: +There is also a command line + +.. code-block:: bash $ community <filename> filename is a binary file as generated by the -convert utility distributed with the C implementation at https://sites.google.com/site/findcommunities/ This is mostly for debugging purpose -and I advise to use this module more as a library with your graph loading code +convert utility distributed with the C implementation at `https://sites.google.com/site/findcommunities/ <https://sites.google.com/site/findcommunities/>`_ +This is mostly for debugging purpose and I advise to use this module more as a library with your graph loading code than with this command. Documentation ------------- -You can find documentation at https://python-louvain.readthedocs.io/ +You can find documentation at `https://python-louvain.readthedocs.io/ <https://python-louvain.readthedocs.io/>`_ + +To generate documentation run -To generate documentation run:: +.. code-block:: shell pip install numpydoc sphinx cd docs @@ -75,16 +91,9 @@ Tests ----- -To run tests:: +To run tests + +.. code-block:: shell pip install nose python setup.py test - - -.. image:: https://travis-ci.org/taynaud/python-louvain.svg?branch=master - :target: https://travis-ci.org/taynaud/python-louvain - - -.. image:: https://readthedocs.org/projects/python-louvain/badge/?version=latest - :target: http://python-louvain.readthedocs.io/en/latest/?badge=latest - :alt: Documentation Status diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-louvain-0.13/community/__init__.py new/python-louvain-0.14/community/__init__.py --- old/python-louvain-0.13/community/__init__.py 2018-12-21 09:49:48.000000000 +0100 +++ new/python-louvain-0.14/community/__init__.py 2020-04-06 14:38:52.000000000 +0200 @@ -15,7 +15,7 @@ load_binary, ) -__version__ = "0.13" +__version__ = "0.14" __author__ = """Thomas Aynaud (thomas.ayn...@lip6.fr)""" # Copyright (C) 2009 by # Thomas Aynaud <thomas.ayn...@lip6.fr> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-louvain-0.13/community/community_louvain.py new/python-louvain-0.14/community/community_louvain.py --- old/python-louvain-0.13/community/community_louvain.py 2018-11-28 15:34:16.000000000 +0100 +++ new/python-louvain-0.14/community/community_louvain.py 2020-04-06 14:38:51.000000000 +0200 @@ -345,7 +345,7 @@ status.init(current_graph, weight, part_init) status_list = list() __one_level(current_graph, status, weight, resolution, random_state) - new_mod = __modularity(status) + new_mod = __modularity(status, resolution) partition = __renumber(status.node2com) status_list.append(partition) mod = new_mod @@ -354,7 +354,7 @@ while True: __one_level(current_graph, status, weight, resolution, random_state) - new_mod = __modularity(status) + new_mod = __modularity(status, resolution) if new_mod - mod < __MIN: break partition = __renumber(status.node2com) @@ -397,7 +397,7 @@ >>> ind = induced_graph(part, g) >>> goal = nx.Graph() >>> goal.add_weighted_edges_from([(0,1,n*n),(0,0,n*(n-1)/2), (1, 1, n*(n-1)/2)]) # NOQA - >>> nx.is_isomorphic(int, goal) + >>> nx.is_isomorphic(ind, goal) True """ ret = nx.Graph() @@ -465,7 +465,7 @@ """ modified = True nb_pass_done = 0 - cur_mod = __modularity(status) + cur_mod = __modularity(status, resolution) new_mod = cur_mod while modified and nb_pass_done != __PASS_MAX: @@ -473,7 +473,7 @@ modified = False nb_pass_done += 1 - for node in random_state.permutation(list(graph.nodes())): + for node in __randomize(graph.nodes(), random_state): com_node = status.node2com[node] degc_totw = status.gdegrees.get(node, 0.) / (status.total_weight * 2.) # NOQA neigh_communities = __neighcom(node, graph, status, weight_key) @@ -483,7 +483,7 @@ neigh_communities.get(com_node, 0.), status) best_com = com_node best_increase = 0 - for com, dnc in random_state.permutation(list(neigh_communities.items())): + for com, dnc in __randomize(neigh_communities.items(), random_state): incr = remove_cost + resolution * dnc - \ status.degrees.get(com, 0.) * degc_totw if incr > best_increase: @@ -493,7 +493,7 @@ neigh_communities.get(best_com, 0.), status) if best_com != com_node: modified = True - new_mod = __modularity(status) + new_mod = __modularity(status, resolution) if new_mod - cur_mod < __MIN: break @@ -531,7 +531,7 @@ weight + status.loops.get(node, 0.)) -def __modularity(status): +def __modularity(status, resolution): """ Fast compute the modularity of the partition of the graph using status precomputed @@ -542,5 +542,12 @@ in_degree = status.internals.get(community, 0.) degree = status.degrees.get(community, 0.) if links > 0: - result += in_degree / links - ((degree / (2. * links)) ** 2) + result += in_degree * resolution / links - ((degree / (2. * links)) ** 2) return result + + +def __randomize(items, random_state): + """Returns a List containing a random permutation of items""" + randomized_items = list(items) + random_state.shuffle(randomized_items) + return randomized_items diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-louvain-0.13/docs/index.rst new/python-louvain-0.14/docs/index.rst --- old/python-louvain-0.13/docs/index.rst 2018-12-21 10:02:37.000000000 +0100 +++ new/python-louvain-0.14/docs/index.rst 2020-04-06 14:38:52.000000000 +0200 @@ -91,6 +91,7 @@ Changelog : =========== +* 2020-04-06 : 0.14, bugfixes (on resolution parameter), optimization on random state * 2018-12-21 : 0.13, better random state, some files missing included, communities always in 0..N-1 * 2018-05-22 : 0.11, stop forcing networkx<2.0 and expose module __version__ * 2018-01-02 : 0.10, bug fix: taking into account the node removal cost diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-louvain-0.13/python_louvain.egg-info/PKG-INFO new/python-louvain-0.14/python_louvain.egg-info/PKG-INFO --- old/python-louvain-0.13/python_louvain.egg-info/PKG-INFO 2018-12-21 10:07:17.000000000 +0100 +++ new/python-louvain-0.14/python_louvain.egg-info/PKG-INFO 2020-04-06 14:39:45.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: python-louvain -Version: 0.13 +Version: 0.14 Summary: Louvain algorithm for community detection Home-page: https://github.com/taynaud/python-louvain Author: Thomas Aynaud diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-louvain-0.13/python_louvain.egg-info/requires.txt new/python-louvain-0.14/python_louvain.egg-info/requires.txt --- old/python-louvain-0.13/python_louvain.egg-info/requires.txt 2018-12-21 10:07:17.000000000 +0100 +++ new/python-louvain-0.14/python_louvain.egg-info/requires.txt 2020-04-06 14:39:45.000000000 +0200 @@ -1 +1,2 @@ networkx +numpy diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-louvain-0.13/setup.py new/python-louvain-0.14/setup.py --- old/python-louvain-0.13/setup.py 2018-12-21 09:49:19.000000000 +0100 +++ new/python-louvain-0.14/setup.py 2020-04-06 14:38:52.000000000 +0200 @@ -2,7 +2,7 @@ setup( name="python-louvain", - version="0.13", + version="0.14", author="Thomas Aynaud", author_email="tayn...@gmail.com", description="Louvain algorithm for community detection", @@ -19,6 +19,7 @@ packages=['community'], install_requires=[ "networkx", + "numpy" ], scripts=['bin/community'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/python-louvain-0.13/test_community.py new/python-louvain-0.14/test_community.py --- old/python-louvain-0.13/test_community.py 2018-11-28 15:31:08.000000000 +0100 +++ new/python-louvain-0.14/test_community.py 2020-04-06 14:38:47.000000000 +0200 @@ -6,8 +6,10 @@ import random import networkx as nx +import numpy import community as co +from community.community_louvain import __randomize as randomize def girvan_graphs(zout): @@ -311,5 +313,63 @@ self.assertEqual(len(set(comhigher)), 1) +class NodeTypeTest(unittest.TestCase): + def test_multiple_node_types(self): + """ + Test that a graph with nodes of different Python types still gets + correct results + """ + node01 = 6 + node02 = 'hello' + node11 = False + node12 = lambda: 0 + node13 = 22.2 + edges = [(node01, node02), (node11, node12), (node12, node13)] + graph = nx.Graph(edges) + partition = co.best_partition(graph) + for (a, b) in edges: + self.assertEqual(partition[a], partition[b]) + self.assertNotEqual(partition[node01], partition[node11]) + + +class RandomizeTest(unittest.TestCase): + """Test the __randomize utility function""" + + def test_randomize_handles_list_items(self): + """Test that Lists are randomized correctly""" + l = list(range(100)) + random_state = numpy.random.RandomState() + randomized_items = randomize(l, random_state) + self.assertNotEqual(l, randomized_items, "List was not randomized") + self.assertEqual(set(l), set(randomized_items), + "Input items and randomized items are not equal sets") + self.assertEqual(sorted(l), l, "Input list was changed") + + def test_randomize_handles_dict_items(self): + """Test that Dict#items() are randomized correctly""" + d = {"1": 1, 2: 2, "3": "3"} + random_state = numpy.random.RandomState() + randomized_items = randomize(d.items(), random_state) + self.assertEqual(set(d.items()), set(randomized_items), + "Input items and randomized items are not equal sets") + + def test_randomize_handles_mixed_items(self): + """Test that Lists of mixed types are randomized correctly""" + random_state = numpy.random.RandomState() + items = [True, 1, 1.0, lambda x: 1, (2,), "test"] + randomized_items = randomize(items, random_state) + self.assertEqual(set(items), set(randomized_items), + "Input items and randomized items are not equal sets") + + def test_randomize_handles_iterators(self): + """Test that Iterators are randomized correctly""" + it = iter(range(10)) + random_state = numpy.random.RandomState() + randomized_items = randomize(it, random_state) + self.assertEqual(set(range(10)), set(randomized_items), + "Input items and randomized items are not equal sets") + + + if __name__ == '__main__': unittest.main()