1
\$\begingroup\$

Context:

Write a program to print the output for the given input(Example is given in comments of my code). String is of odd length.

I would be grateful if anyone could give feedback on my following code. The code runs correctly but I want to know if there can be any potential improvements in terms of code style and optimization.

 s=input("enter string") #take s="12345" for example #output should be: # 1 5 # 2 4 # 3 # 2 4 # 1 5 for i in range(0,len(s)): # loop runs 5 times from index 0 to index 4 if i==((len(s)-1)//2): #first condition prints the center of pattern print(" "*i,s[i]) #leading 2 spaces print 3 elif i>(len(s)-1)//2: # second condition prints the characters above the center 3 print(" "*(len(s)-1-i),s[len(s)-i-1]," "*(i-(len(s)-i)-1)+s[i]) # 1 5 # 2 4 # 3 else: print(" "*i,s[i]," "*(len(s)-(2*(i+1))-1)+s[len(s)-i-1]) # else statement prints characters below the center # in reversed order # 3 # 2 4 # 1 5 
\$\endgroup\$
5
  • \$\begingroup\$Just a thought, this might make for simpler code: Iterate from both sides of the array at the same time. "left" indexes from 0 to 4 and "right" indexes 4 to 0. No fancy arithmetic. Just iterate, and print both values with appropriate spaces\$\endgroup\$
    – radarbob
    CommentedAug 28, 2024 at 18:41
  • \$\begingroup\$Should the code work with the input of say 11 or 101? If not, you can build the X by mutating a list.\$\endgroup\$
    – Peilonrayz
    CommentedAug 28, 2024 at 18:45
  • \$\begingroup\$There may be a special case when both "left" & "right" are at the same index. The value should be printed only once.\$\endgroup\$
    – radarbob
    CommentedAug 28, 2024 at 18:48
  • \$\begingroup\$I did not get the last part . Could you please tell what you mean by special case?\$\endgroup\$
    – Silah
    CommentedAug 29, 2024 at 2:40
  • \$\begingroup\$Are you talking about the center of X shape because the first condition deals with that special case. And any odd length string works as expected\$\endgroup\$
    – Silah
    CommentedAug 29, 2024 at 2:42

2 Answers 2

2
\$\begingroup\$

Writing index-conditional statements on the inside of a loop is a code smell. Instead you should prefer "looping like a native" making appropriate use of enumerate and zip.

You can also replace the string-multiply approach with formatting widths:

def print_x(s: str) -> None: n = len(s) # Converging (top half) forward = s[:n//2] reverse = s[-1: (-1 - n)//2: -1] for i, (char1, char2) in enumerate(zip(forward, reverse)): print(f'{char1:>{i + 1}}{char2:>{n - 2*i - 1}}') # Middle, single-character case if n % 2 == 1: print(f'{s[n//2]:>{1 + n//2}}') # Diverging (bottom half) reverse = s[-n//2 - 1: -1 - n: -1] forward = s[(n + 1)//2:] for i, (char1, char2) in enumerate(zip(reverse, forward)): print(f'{char1:>{n//2 - i}}{char2:>{(n - 1)//2 + 2*i}}') 
\$\endgroup\$
2
  • \$\begingroup\$I understand about the string formatting but did not get how index conditionals inside of loop can be a problem . Could you please explain a little or suggest resources where I can get a clearer understanding about code smell in general . Just a beginner right now .\$\endgroup\$
    – Silah
    CommentedAug 29, 2024 at 15:27
  • \$\begingroup\$Thank you . I just gave it a read , got to know how using the approach I took can make my code more hard coded and less of something modular. It really doesn’t look quite right after you pointed out ,and discovered that python already has methods for characters’ alignment. Have a lot to improve on\$\endgroup\$
    – Silah
    CommentedAug 29, 2024 at 15:53
4
\$\begingroup\$

A big change would be to improve the readability of the program.

Some changes I would make are:

  • Add spacing between operators and make bracket style consistent (e.g. ((len(s)-1)//2) vs (len(s)-1)//2).
  • Convert calculations that are done multiple times (e.g. mid and size) into variables.
  • Break down the large print statements into smaller and more readable sections; just making the code more verbose.
input_string = input("Enter string: ") size = len(input_string) mid = size // 2 for i in range(size): if i == mid: print(' ' * i + input_string[i]) elif i > mid: left_space = ' ' * (size - 1 - i) middle_space = ' ' * (2 * i - size + 1) print(f"{left_space}{input_string[size-i-1]}{middle_space}{input_string[i]}") else: left_space = ' ' * i middle_space = ' ' * (size - 2 * i - 2) print(f"{left_space}{input_string[i]}{middle_space}{input_string[size-i-1]}") 
\$\endgroup\$
1
  • 2
    \$\begingroup\$Thank you . I am working on my code style and readability and your feedback helped .\$\endgroup\$
    – Silah
    CommentedAug 28, 2024 at 15:47

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.