-1
\$\begingroup\$

I'm new to Python and programming in general.
Let's imagine I have a simple task:
Given 3 numbers from user input, I need to count negative ones and print the result.
Considering what I know about Python at this moment, I can solve it like this:

class ListTooShort(Exception):
    pass

def input_check():
    temp_list = []
    while True:
        try: 
            temp_list = [float(x) for x in input('Input 3 numbers, separated by space: ').split()]
            if (len(temp_list) < 3):
                raise ListTooShort
            if (len(temp_list) > 3):
                temp_list = temp_list[:3]
        except ValueError:
            print('One of given values is not a number, try again.')
        except ListTooShort:
            print('Not enough values, try again.')
        else: return temp_list

def count_negative_numbers(value_list):
    counter = 0
    for i in value_list:
        if (i < 0):
            counter += 1
    return counter

print('If theres more than 3 numbers,\nlist will be trimmed to 3 first values.')
numbers = input_check()
result = count_negative_numbers(numbers)
print(f'Theres {result} negative numbers in this 3 value list')

or like this:

counter = 0
numbers = [float(x) for x in input('Input 3 numbers, seperated by space: ').split()]
if (len(numbers) >= 3):
    numbers = numbers[:3]
for i in numbers:
    if (i < 0):
        counter += 1
print(f'Theres {counter} negative numbers in this value(s) list')

Both do the trick, but the main questions I have is:

  1. Would it be better to not complicate the code too much when there's a simple task at hand?
  2. Is it even worth to make functions for simple things like that or should I just go straight to solving an issue?
  3. Should I even pay attention to things like that or its better to just "freeroam" without caring that much?
\$\endgroup\$
2
  • 4
    \$\begingroup\$ The title should reflect what the program does, not what your question is. Thanks. \$\endgroup\$
    – ggorlen
    Dec 5, 2022 at 20:15
  • 2
    \$\begingroup\$ The current question title, which states your concerns about the code, applies to too many questions on this site to be useful. The site standard is for the title to simply state the task accomplished by the code. Please see How do I ask a good question?. \$\endgroup\$
    – BCdotWEB
    Dec 6, 2022 at 8:54

1 Answer 1

6
\$\begingroup\$

Getting exactly 3 values

I think that since you are requesting exactly 3 values, I'd abandon inputting an arbitrary number of values separated by a space. Instead, in your while loop, just enforce the constraint that your list has no more than 3 values:

temp_list = []

while len(temp_list) < 3:
    try:
        temp_list.append(
            float(input(f"Input number {len(temp_list) + 1}: "))
        )
    except ValueError:
        print("Error processing your number, try again!")

Defining custom exceptions

While we're at it, rarely do you need to create your own exceptions. A ValueError, if needed, would suffice:

def some_function(mylist: List[int]):
    if len(mylist) != 3:
        raise ValueError("Expected 'mylist' to have exactly 3 values")
   
    print(len(mylist))

bool and int can be used the same way

When you are checking for a condition and counting True values, this behaves just like 1:

int(True)
1

int(False)
0

So you can add the boolean expression if you felt so inclined:

def count_negative_numbers(value_list):
    counter = 0
    for i in value_list:
        counter += (i < 0)
    return counter

Your for loop here is perfectly readable and doesn't really need refactoring, but a more advanced technique would be to feed a generator expression to sum:

def count_negative_numbers(value_list):
    return sum(i < 0 for i in value_list)

Other Questions

Would it be better to not complicate the code too much when theres a simple task at hand?

To borrow a quote:

Simple is better than complex, complex is better than complicated.

Make it as simple as reasonably possible to solve the problem at hand. As a note, less code (one-liners) does not always mean simpler.

Is it even worth to make functions for simple things like that or should i just go straight to solving an issue?

It's good practice (both in terms of standards and practice in general) to keep up good code organization. Personally, I have found myself sometimes going back to small scripts I wrote where I know I solved a certain problem before. Writing good functions with helpful names and docstrings makes finding them much faster.

I'd keep writing functions where you find it helps readability and organization of your scripts. It will pay dividends when it comes time to write much larger applications.

Should i even pay attention to things like that or its better to just "freeroam" without caring that much?

Freeroaming is great for just getting ideas out there, but there's a balance to be struck. Writing nothing but "freeroam" code will enforce habits that will need to be broken when writing code for larger problems/applications. It's an iterative process:

  1. Solve
  2. Refactor
  3. Repeat
\$\endgroup\$

Your Answer

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

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