0

I'm new to Python and am running into a bit of a road block. I'm using python 3 and I have the following code:

from collections import deque

databases=input("Enter databases: ")

db_list = deque(databases.split())
node1list = []
node2list = []
node3list = []

numDatabases = len(db_list)

while len(db_list) > 0:
    if len(db_list) > 0:
        node1list.append(db_list.popleft())
    if len(db_list) > 0:
        node2list.append(db_list.popleft())
    if len(db_list) > 0:
        node3list.append(db_list.popleft())

print("Paste the following in Node 1's file")
print("--------------------------------------------")
print("[[INSTANCE]")
print("#  Keep a blank space after the colon character.")
print("#")
print("group1:", end="")
for db in node1list:
    print(" " + db, end="")

print("\n\nPaste the following in Node 2's file")
print("--------------------------------------------")
print("[[INSTANCE]")
print("#  Keep a blank space after the colon character.")
print("#")
print("group1: ", end="")
for db in node2list:
    print(" " + db, end="")

print("\n\nPaste the following in Node 3's file")
print("--------------------------------------------")
print("[[INSTANCE]")
print("#  Keep a blank space after the colon character.")
print("#")
print("group1: ", end="")
for db in node3list:
    print(" " + db, end="")

When I run the code, I get output like this:

Enter databases: one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty twentyone twentytwo twentythree twentyfour twentyfive twentysix twentyseven twentyeight twentynine thirty thirtyone thirtytwo thirtythree thirtyfour
----------------------------------------------------------------------------------------------

Paste the following in Node 1's file
--------------------------------------------
[[INSTANCE]
#  Keep a blank space after the colon character.
#
group1: one four seven ten thirteen sixteen nineteen twentytwo twentyfive twentyeight thirtyone thirtyfour

Paste the following in Node 2's file
--------------------------------------------
[[INSTANCE]
#  Keep a blank space after the colon character.
#
group1:  two five eight eleven fourteen seventeen twenty twentythree twentysix twentynine thirtytwo

Paste the following in Node 3's file
--------------------------------------------
[[INSTANCE]
#  Keep a blank space after the colon character.
#
group1:  three six nine twelve fifteen eighteen twentyone twentyfour twentyseven thirty thirtythree

But I need the group1 to only take a maximum of 5 databases, and then to automatically start plugging them into group2. Each group can only hold up to 5 databases. Also, the number of databases could be far more than just 34 (that number is an unknown variable), so I need the ability to keep increasing the number of groups to compensate for this unknown variable.

So I would like the output to look like this:

Enter databases: one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty twentyone twentytwo twentythree twentyfour twentyfive twentysix twentyseven twentyeight twentynine thirty thirtyone thirtytwo thirtythree thirtyfour

----------------------------------------------------------------------------------------------

Paste the following in Node 1's file
--------------------------------------------
[[INSTANCE]
#  Keep a blank space after the colon character.
#
group1: one four seven ten thirteen
group2: sixteen nineteen twentytwo twentyfive twentyeight
group3: thirtyone thirtyfour

Paste the following in Node 2's file
--------------------------------------------
[[INSTANCE]
#  Keep a blank space after the colon character.
#
group1: two five eight eleven fourteen
group2: seventeen twenty twentythree twentysix twentynine
group3: thirtytwo

Paste the following in Node 3's file
--------------------------------------------
[[INSTANCE]
#  Keep a blank space after the colon character.
#
group1: three six nine twelve fifteen
group2: eighteen twentyone twentyfour twentyseven thirty
group3: thirtythree

But I'm at a complete loss at how to do this. I think this can be achieved with a nested for-loop within my while-loop but I haven't been able to get the results I need. I'm not sure if I'm just over thinking things or maybe I just need to take a break lol. Any suggestions that can help me out?

etho201
  • 151
  • 9
  • The reason the databases are distributed the way you see here is because the user is inputting the list of databases based on size from largest to smallest. So this type of distribution helps keep everything level across the 3 nodes. – etho201 Jun 21 '14 at 00:58

2 Answers2

1

If I understand your problem correctly this is just a simple list of items split into chunks. Using funcy:

>>> from funcy import chunks
>>> s = "one two three four five six seven eight nine ten eleven"
>>> databases = chunks(5, s.split())
>>> databases
[['one', 'two', 'three', 'four', 'five'], ['six', 'seven', 'eight', 'nine', 'ten'], ['eleven']]
>>> databases[0]
['one', 'two', 'three', 'four', 'five']
>>> databases[1]
['six', 'seven', 'eight', 'nine', 'ten']
>>> databases[2]
['eleven']
>>> len(databases[0])
5
>>> len(databases[1])
5
>>> len(databases[2])
1

Your code could then be re-written like this:

#!/usr/bin/env python


from __future__ import print_function


from funcy import chunks


s = raw_input("Enter databases: ")

nodes = chunks(5, s.split())

for i, node in enumerate(nodes):
    print("Paste the following in Node 1's file")
    print("--------------------------------------------")
    print("[[INSTANCE]")
    print("#  Keep a blank space after the colon character.")
    print("#")
    print("group{0:d}:".format(i), end="")
    for db in node:
        print(" " + db, end="")

With the following sample output:

$ python bar.py 
Enter databases: a b c d e f g h i j k l m n o p q r s t u v w x y z
Paste the following in Node 1's file
--------------------------------------------
[[INSTANCE]
#  Keep a blank space after the colon character.
#
group0: a b c d ePaste the following in Node 1's file
--------------------------------------------

and so on...

Update:

By the way you can implement chunks like this:

def chunks(l, n):
    """ Yield successive n-sized chunks from l.
    """
    for i in xrange(0, len(l), n):
        yield l[i:i+n]

Liberally borrowed from: How do you split a list into evenly sized chunks?

Community
  • 1
  • 1
James Mills
  • 18,669
  • 3
  • 49
  • 62
  • I like the idea of using chunks... Keep in mind though that it's not the nodes that will be repeated, it's the groups within the nodes. There will only be 3 nodes and the number of groups will need to grow within the nodes. I would need something like: node1.group[], node2.group[], and node3.group[]. Perhaps my first pattern can go through populating the nodes just like before, and after that I can split them into chunks. Would something like this be possible? node1groups = chunks(5, node1list.split()), node2groups = chunks(5, node2list.split()), and node3groups = chunks(5, node3list.split()). – etho201 Jun 21 '14 at 23:30
1

Instead of using any extra modules, if you want to correct the logic of your code then just change your while-loop block as follows

i = 0
node1list = [[]]
node2list = [[]]
node3list = [[]]

while len(db_list) > 0:
    if len(node1list[i]) < 5:
        node1list[i].append(db_list.pop(0))
    elif len(node2list[i]) < 5:
        node2list[i].append(db_list.pop(0))
    elif len(node3list[i]) < 5:
        node3list[i].append(db_list.pop(0))
    else:
        node1list.append([])
        if len(db_list) > 5:
            node2list.append([])
            if len(db_list) > 10:
                node3list.append([])
        i += 1
Parth
  • 729
  • 8
  • 23
  • Whilst this might be technically correct it will not cope with a list of items > 15. In fact if the size of the list is > 15 I'm pretty sure this loop will not terminate because of the condition. – James Mills Jun 21 '14 at 01:20
  • Great :) This is now both technically correct and will handle a list of arbitrary length. However: I still feel it's best to use good code reuse here. Either ``funcy`` or ``chunk`` function as per my answer. – James Mills Jun 21 '14 at 01:32
  • The logic of this code does seem better than what I posted, but it's not the nodes that will be repeated, it's the groups within the nodes. There will only be 3 nodes and the number of groups will need to grow within the nodes. I would need something like: node1.group[], node2.group[], and node3.group[]. – etho201 Jun 21 '14 at 23:18
  • There must be an upper limit on number of groups in a node, otherwise one could fit complete `db_list` in a single node. I've updated the code considering equal distribution among all three nodes, following the precedence by index. – Parth Jun 22 '14 at 05:02