6

So I want to know, is there any simple code for making an Hour Glass pattern with odd or even input using Java or Python? Because my code is not simple (I'm using Python).

Here's the output example:

Expected Output

And then, here is my code:

def evenGlassHour(target):
 jsp=1
 jtop=target
 jbot=2
 jbotspace=int(target/2)
 eventarget=int(target/2)
 temp=""
 for i in range(eventarget):
     for j in range(i):
         temp+=" "
     for jsp in range(jtop):
         temp+="@"
     jtop-=2
     temp+="\n"
 for i in range(eventarget-1):
     for j in range(jbotspace-2):
         temp+=" "
     for j in range(jbot+2):
         temp+="@"
     jbot+=2
     jbotspace-=1
     temp+="\n"

 print(temp)

def oddGlassHour(target):
 jsp=1
 jtop=target
 jbot=1
 jbotspace=int(target/2)
 oddtarget=int(target/2)
 temp=""
 for i in range(oddtarget):
     for j in range(i):
         temp+=" "
     for jsp in range(jtop):
         temp+="@"
     jtop-=2
     temp+="\n"
 for i in range(oddtarget+1):
     for j in range(jbotspace):
         temp+=" "
     for j in range(jbot):
         temp+="@"
     jbot+=2
     jbotspace-=1
     temp+="\n"

 print(temp)

target=int(input("Input : "))

if(target%2==0):
 evenGlassHour(target)
else:
 oddGlassHour(target)

And this is the result from my code:

 Input : 6
 @@@@@@
  @@@@
   @@
  @@@@
 @@@@@@

 Input : 7
 @@@@@@@
  @@@@@
   @@@
    @
   @@@
  @@@@@
 @@@@@@@
4
  • Please post the code and results directly instead of screenshots. Commented Jan 22, 2019 at 11:26
  • okay, wait I'll edit it Commented Jan 22, 2019 at 11:27
  • Keep in mind that your question needs the code included in the question itself if you move it to Code Review. Also, it's not obvious what your program is supposed to do, so better add an example. Commented Jan 22, 2019 at 11:31
  • thank you so much for the information Commented Jan 22, 2019 at 11:32

4 Answers 4

1

You can use string formatting with str.zfill and recursion:

def _glass(_input, _original, flag=True):
  if _input in {1, 2}:
    return ('00' if _input == 2 else '0').center(_original) if flag else ''
  if flag:
    return ('0'*(_input)).center(_original)+'\n'+_glass(_input-2, _original, flag=flag)
  return _glass(_input-2, _original, flag=flag)+'\n'+('0'*(_input)).center(_original)

def print_glasses(_input):
  print(_glass(_input, _input)+_glass(_input, _input, False))

for i in range(3, 8):
  print_glasses(i)
  print('-'*20)

Output:

000
 0 
000
--------------------
0000
 00 
0000
--------------------
00000
 000 
  0  
 000 
00000
--------------------
000000
 0000 
  00  
 0000 
000000
--------------------
0000000
 00000 
  000  
   0   
  000  
 00000 
0000000
--------------------
Sign up to request clarification or add additional context in comments.

Comments

1

In java you can write something like below:

public static void printPattern(int size) {
    int n = size; 
    boolean upper = true;
    for(int i = 0; size%2 == 0? i< size-1 : i<size; i++){            
        String str = String.join("", Collections.nCopies(n, "@"));
        String pad = String.join("", Collections.nCopies((size-n)/2 , " "));
        System.out.println(pad+str+pad);
        if(n-2>0 && upper){
            n-=2;
        }
        else {
            n+=2;
            upper = false;
        }           
    }
}

Comments

1

Use center-justication string formatting

inspiration: https://stackoverflow.com/a/44781576

def render(size):
    char = "*"
    #build a center-justified format mask
    mask = '{:^%ds}' % (size)

    print("size:%s:\n" % (size))

    #count down your shrinking
    for i in range(size, 0, -2):
        print(mask.format(char * i))

    #trickier:  you've already printed the narrowest
    #and your next line is different depending on odd/even input 
    if size % 2:
        start = 3
    else:
        start = 4

    for i in range(start, size+1, 2):
        print(mask.format(char * i))
    print()


render(3)
render(5)
render(12)

outputs:

size:3:

***
 *
***

size:5:

*****
 ***
  *
 ***
*****

size:12:

************
 **********
  ********
   ******
    ****
     **
    ****
   ******
  ********
 **********
************

Comments

0

In Python, you can take advantage of the fact that you can multiply a string by x and get the string concatenated with itself x times, like:

"test" * 3 # becomes testtesttest

Further you can use the same function for top and bottom of the hourglass, by using different values for range:

def evenGlassHour(target, direction = 1):
    for i in range(target, 1, -2) if direction == 1 else range(4, target+1, 2):
        pad = int((target - i) / 2)
        print((" " * pad) + "@" * i + " " * pad)
    if direction == 1:
        evenGlassHour(target, -1)

def oddGlassHour(target, direction = 1):
    for i in range(target, 1, -2) if direction == 1 else range(1, target+1, 2):
        pad = int((target - i) / 2)
        print((" " * pad) + "@" * i + " " * pad)
    if direction == 1:
        oddGlassHour(target, -1)

target=int(input("Input : "))

if target % 2 == 0:
    evenGlassHour(target)
else:
    oddGlassHour(target)

EDIT: You can even remove the recursive-call, and just chain the two ranges together, making the function even smaller:

from itertools import chain

def evenGlassHour(target):
    for i in chain(range(target, 1, -2), range(4, target+1, 2)):
        pad = int((target - i) / 2)
        print((" " * pad) + "@" * i + " " * pad)

Finally, you can make the functions accept the desired symbol to be printed (of any length), like this:

def evenGlassHour(target, symbol = "@"):
    for i in chain(range(target, 1, -2), range(4, target+1, 2)):
        pad = int((target - i) / 2) * len(symbol)
        print((" " * pad) + symbol * i + " " * pad)

You can also combine the two functions, to make it even more ridiculous:

from itertools import chain
def glassHour(t, s = "@"):
    for i in chain(range(t, 1, -2), range((4 if t % 2 == 0 else 1), t+1, 2)): 
        print((" " * (int((t - i) / 2)*len(s)) + s * i + " " * (int((t - i) / 2)*len(s))))

target=int(input("Input : "))
glassHour(target, "$$")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.