2
\$\begingroup\$

I started programming in Python after learning the basics of C, which is why I like the user-defined functions to be described after the main() function's job is over. Also, I like to specify the sep and end parameters of every print() function in my programs.

After some research, I came to know that the majority of programmers stick to a characters-per-line limit (80, 120, etc.), while others don't bother with such a limit. I have decided to limit my lines to 80 characters (if there are no in-line comments), or to 120 characters (including in-line comments). Using this style makes codes look very neat and easy to understand, in my opinion.

def main():

    get_the_number_of_students_from_user()

    if (NUMBER_OF_STUDENTS > 0):
        get_the_list_of_names_from_user()
        get_the_list_of_marks_obtained_from_user()
        print_the_names_after_sorting()
        print_the_marks_obtained_after_sorting()
    else:
        print("The number of students should be greater than 0!\n",
              sep = "", end = "")



def get_the_number_of_students_from_user():

    global NUMBER_OF_STUDENTS

    NUMBER_OF_STUDENTS = int(input("Enter the number of students enrolled in "
                                   "this course: "))

    print("\n", sep = "", end = "")



def get_the_list_of_names_from_user():

    global LIST_OF_NAMES

    LIST_OF_NAMES = []

    for x in range(NUMBER_OF_STUDENTS):
        print("Enter the name of student no. ", x+1, ": ", sep = "", end = "")
        dummyVariable1 = input()
        LIST_OF_NAMES.append(dummyVariable1)

    print("\n", sep = "", end = "")



def get_the_list_of_marks_obtained_from_user():

    global MARKS_OBTAINED

    MARKS_OBTAINED = []

    for y in LIST_OF_NAMES:
        print("Enter the marks obtained by ", y, ": ", sep = "", end = "")
        dummyVariable2 = int(input())
        MARKS_OBTAINED.append(dummyVariable2)

    print("\n", sep = "", end = "")



def print_the_names_after_sorting():


    listOfNames = LIST_OF_NAMES                                                     # To let LIST_OF_NAMES stay
                                                                                    # constant.

    print("The name(s) of the student(s) enrolled in this course is(are) :-\n",
          sep = "", end = "")


    listOfNames.sort()

    for z in range(NUMBER_OF_STUDENTS):                                             # To print listOfNames like
        if (z+1 == NUMBER_OF_STUDENTS):                                             # a, b, c, d & e instead of like
            print(listOfNames[z], sep = "", end = " ")                              # ['a', 'b', 'c', 'd', 'e'].
        elif (z+2 == NUMBER_OF_STUDENTS):
            print(listOfNames[z], sep = "", end = " & ")
        else:
            print(listOfNames[z], sep = "", end = ", ")

    print("(in ascending alphabetical order).\n", sep = "", end = "")


    listOfNames.reverse()

    for w in range(NUMBER_OF_STUDENTS):                                             # To print listOfNames like
        if (w+1 == NUMBER_OF_STUDENTS):                                             # a, b, c, d & e instead of like
            print(listOfNames[w], sep = "", end = " ")                              # ['a', 'b', 'c', 'd', 'e'].
        elif (w+2 == NUMBER_OF_STUDENTS):
            print(listOfNames[w], sep = "", end = " & ")
        else:
            print(listOfNames[w], sep = "", end = ", ")

    print("(in descending alphabetical order).\n\n", sep = "", end = "")



def print_the_marks_obtained_after_sorting():


    marksObtained = MARKS_OBTAINED                                                  # To let MARKS_OBTAINED stay
                                                                                    # constant.

    print("The marks obtained by the student(s) enrolled in this course ",
          "is(are) :-\n", sep = "", end = "")


    marksObtained.sort()

    for u in range(NUMBER_OF_STUDENTS):                                             # To print marksObtained like
        if (u+1 == NUMBER_OF_STUDENTS):                                             # 1, 2, 3, 4 & 5 instead of like
            print(marksObtained[u], sep = "", end = " ")                            # [1, 2, 3, 4, 5].
        elif (u+2 == NUMBER_OF_STUDENTS):
            print(marksObtained[u], sep = "", end = " & ")
        else:
            print(marksObtained[u], sep = "", end = ", ")

    print("(in ascending order).\n", sep = "", end = "")


    marksObtained.reverse()

    for v in range(NUMBER_OF_STUDENTS):                                             # To print marksObtained like
        if (v+1 == NUMBER_OF_STUDENTS):                                             # 1, 2, 3, 4 & 5 instead of like
            print(marksObtained[v], sep = "", end = " ")                            # [1, 2, 3, 4, 5].
        elif (v+2 == NUMBER_OF_STUDENTS):
            print(marksObtained[v], sep = "", end = " & ")
        else:
            print(marksObtained[v], sep = "", end = ", ")

    print("(in descending order).\n", sep = "", end = "")



main()
\$\endgroup\$
0
5
\$\begingroup\$

Global variables in a module or script are a bad idea, except for constants or under rare circumstances (you don't have one of those). Instead pass the necessary data from one function to another.

It's great that you are using functions. However, you have only taken advantage of one of their purposes -- namely, to break a sequence of steps into meaningful groups. Functions can also be used to perform repetitive operations. This is their greatest value: it prevents the need to repeat yourself too often in the code.

I encourage you to abandon the style of placing comments globally aligned on the far right side. It might have an aesthetic appeal, but it's harder to maintain (and read, I would argue). The problems magnify if you ever intend to work on projects where you are writing code with other people. The commenting style in the code below is easy to edit, easy to move around in a text file, and flexible to use with a variety of types of comments.

Similarly, give up your style regarding print(). A key issue with software is how easily one can type and read it -- sometimes precisely and often via quick visual scanning. Adding unnecessary stuff hinders those goals.

Python allows you to iterate directly over collections rather than having to iterate over indexes. And if you need indexes, use enumerate().

# Do this in almost all situations.
for x in xs:
    ...

# Not this.
for i in range(len(xs)):
    x = xs[i]
    ...

Here's a short illustration of some of those ideas:

def main():
    # No global variables. Pass data back and forth among functions.
    n = get_the_number_of_students_from_user()
    if n > 0:
        names = get_the_list_of_names_from_user(n)
        ...
        print_the_names_after_sorting(names)
        ...

def print_the_names_after_sorting(names):
    # Be practical: no unnecessary arguments for print() and
    # no unnecessary text in messages to users.
    print('Students enrolled:')

    # Use loops, functions, and data to reduce code repetition.
    # Here a tuple of data drives the process.
    for rev in (False, True):

        # We use data to control sorting direction.
        #
        # Be practical: join the names on a consistent
        # basis (comma-space) so you don't need special tricks
        # to insert '&' before the last items.
        names_txt = ', '.join(sorted(names, reverse = rev))

        # Data is also used to modify the message.
        direction = 'descending' if rev else 'ascending'

        # Python has powerful ways to build strings.
        msg = f'{names_txt} (in {direction} alphabetical order).'
        print(msg)

You could take this even farther by noticing that print_the_names_after_sorting() and print_the_marks_obtained_after_sorting() are almost identical. They differ only in their initial message. You could generalize the function and use it for both names and marks:

def print_items_after_sorting(items, init_msg):
    print(init_msg)
    for rev in (False, True):
        vals_txt = ', '.join(sorted(items, reverse = rev))
        direction = 'Descending' if rev else 'Ascending'
        msg = f'{direction}: {vals_txt}'
        print(msg)
\$\endgroup\$
2
  • \$\begingroup\$ I agree that using global variables is a bad idea. But, I've used them as constants. Is that bad as well? \$\endgroup\$ – Kushagr Jaiswal Mar 10 at 11:46
  • 2
    \$\begingroup\$ @KushagrJaiswal They are not constants: they are set via user input and data conversion (eg int()) -- which can fail. Constants are just set directly: DOZEN = 12, DEFAULT_MSG = 'Hello', etc. \$\endgroup\$ – FMc Mar 10 at 18:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.