How do I get each set in a two dimensional list of unknown length to print on separate lines with tabs after each integer?

Question:

I am working on a lab for a python course. My current code gives me most but not all points available for this lab. I can’t quite seem to get the code to print correctly. I’ve tried many possible ways of printing the code. On my closest attempts, the printed output seems to be missing tabs at the end of each row. I would be most appreciative for any suggestions.

The assignment stated the following:

Hailstone sequence

Given a positive integer n, the following rules will always create a sequence that ends with 1, called the hailstone sequence:

If n is even, divide it by 2
If n is odd, multiply it by 3 and add 1 (i.e. 3n +1)
Continue until n is 1
Write a program that reads an integer as input and prints the hailstone sequence starting with the integer entered. Format the output so that ten integers, each separated by a tab character (t), are printed per line.

The output format can be achieved as follows:
print(n, end=’t’)

Ex: If the input is:

25

the output is:

25   76   38   19   58   29   88   44   22   11 
34   17   52   26   13   40   20   10   5    16 
8    4    2    1 

Here is my code:

# Taking input from user
n = int(input())

#Creating Hailstone list:
hailstone_list = []
hailstone_list.append(int(n))
while n != 1:
    if n % 2 == 0:
        n = n/2
        hailstone_list.append(int(n))
    else:
        n = 3*n + 1
        hailstone_list.append(int(n))
        
# I converted the hailstone list into a two-dimensional list called 
# "splits", where each set has up to 10 integers contained within them:
splits = [hailstone_list[i:i+10] for i in range(0,len(hailstone_list),10)]

#Different attempts made to get the output formatted correctly, 
#best attempt is the only one I have not commented out:
for sets in splits:
    print(*sets, sep='t')

# for sets in splits:
#     print('t'.join(map(str, sets)))

# for sets in splits:
#     [print(i, end='t') for i in sets]

# [print(i, end='t') for i in splits[0]]
# print()
# [print(i, end='t') for i in splits[1]]
# print()
# [print(i, end='t') for i in splits[2]]

On each example that I fail when the lab checks my code, the problem is always that the last integer on each row of 10 integers is not followed by a tab. How can I get that tab in there?

Example of the problem:
If the input is:

1024

My output is:

1024    512 256 128 64  32  16  8   4   2
1

But the expected output is:

1024    512 256 128 64  32  16  8   4   2
1

This isn’t displaying properly, so here is a screenshot to show you what I mean:
screenshot showing the lack of tabs at the end of each row

If I try using:

for sets in splits:
    print(*sets, end='tn', sep='t')

Then this happens:
Tabs are now added to the ends of the rows, but the last integer now has a tab and this causes me to fail every code test
See example screenshot here

Asked By: Gibberish Name

||

Answers:

One way you might be able to handle this is:

for sets in splits:
    print(*sets, end='tn', sep='t')

Updated for new requirement. Not pretty but probably will work for the auto-grader thing:

for sets in splits:
    print(*sets, end='tn', sep='t') if len(sets) == 10 else print(*sets, sep='t')
Answered By: Sam

Ok, I finally got all of the points by altering the code like so:

# Added a num_sets figure to use in determining which format to apply
num_sets = 0
for sets in splits:
    num_sets += 1

# An inelegant solution to printing the answer that gets all of the points.
for sets in splits:
# the if statement correctly formats a one row only answer
    if num_sets < 2:
        print(*sets, sep='t')
# the elif statement formats an answer that has multiple rows of 10 
# integers, and/or one remaining row with less than 10 integers correctly
    elif len(sets) == 10:
        print(*sets, end='tn', sep='t')
# The else statement formats answers that have less than 10 integers and 
# less than 2 rows correctly
    else:
        print(*sets, sep='t')

Here is the same code without all of my comments explaining it:

num_sets = 0
for sets in splits:
    num_sets += 1

for sets in splits:
    if num_sets < 2:
        print(*sets, sep='t')
    elif len(sets) == 10:
        print(*sets, end='tn', sep='t')
    else:
        print(*sets, sep='t')

To be honest, I suspect this is not the elegant solution the course instructors were pushing me to find, so if anyone here can think of a better one, please feel free to share.

Answered By: Gibberish Name

After A LOT of tinkering I finally found the more elegant solution I was looking for. My previous answer works but can be accomplished more simply with loops. If you know of an even more elegant solution I’m still all ears though. Here is the best answer:

# Take integer as input
n = int(input(""))

# If the integer is a 1 or a 0, this will print the integer
# without a tab
if n <= 1:
    print(n)

else:    
    # next_line variable to tell the loop when the 10th
    # integer has been reached
    next_line = 2
    # prints the first integer with a tab
    print(n, end='t')
    
    # while loop that continues the hailstone sequence
    # until the integer 1 is reached since every
    # sequence ends with a '1'
    while n != 1:
        
        # Executes as long as the 10th integer has not
        # printed
        if next_line % 11 != 0:
            
            # calculates the next integer in the hailstone
            # sequence
            if n % 2 == 0:
                n = n // 2
            else:
                n = 3 * n + 1
            
           # prints the final integer without a tab
            if n == 1:
                print(n)
            
            # prints all other integers with a tab
            # and updates next_line
            else:
                print(n, end='t')
                next_line += 1
    
        # starts a new row after the 10th integer
        # has printed
        else:
            print('')
            next_line += 1

Here is the same code without my comments:

n = int(input(""))

if n <= 1:
    print(n)
else:    
    next_line = 2
    print(n, end='t')

    while n != 1:
        if next_line % 11 != 0:
            if n % 2 == 0:
                n = n // 2
            else:
                n = 3 * n + 1
            
            if n == 1:
                print(n)
            else:
                print(n, end='t')
                next_line += 1
        else:
            print('')
            next_line += 1
Answered By: Gibberish Name
x = int(input())

pool = [x]

while x > 1:
    if x % 2 == 0:
        x = x / 2
    
    else:
        x = (x * 3) + 1
        
    pool.append(int(x))

while len(pool) > 10:
    print(*pool[0:10], end = 'tn', sep = 't')
    del pool[0:10]
if len(pool) == 10:
    print(*pool, sep = 't')
else:
    print(*pool, sep = 't', end = 'n')
Answered By: justaguy
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.