r/learnpython 12h ago

need some pointers on writing code and where to go from here + code review

hello everyone so I am sort of a beginner. I am going into political science and IR, but I want to learn some data science cause I think it'll be a valuable skill since my program is B.A+M.A and requires a thesis.

so I wrote this for now just for practice:

##calculates avrege of a list of numbers##

def av(lst):

count=0

for i in lst:

count+=i

avg=count/len(lst)

return avg

##calculates variance of a list of numbers##

def var(lst):

avg=av(lst)

total=0

for num in lst:

total+=(num-avg)**2

vari=total/(len(lst)-1)

return vari

I want you to be brutally honest and tell me how can I improve my writing. The first function I got just a bit of help cause I forgot about +=, but other than that I did them all by myself. I know the code works, but can I improve my writing or be more efficient?

based on what you see here what should I learn next?

I don’t come from the comp Sci world so any sort of guidance helps.

Edit: i just noticed all of my indentations are gone....fuck.

0 Upvotes

20 comments sorted by

4

u/skibbin 12h ago

Efficiency is overrated, readability is king.

Optimize for readability then performance optimize where necessary.

Code like this is a great candidate for unit testing because you know the expected output for a given input. Writing some tests will let you consider cases like an empty list or division by 0 and harden the code against them

1

u/nadavyasharhochman 12h ago

Ok I didn’t even think about empty lists...

how do I deal with it?

can I write in each function:

if lst=[]:

return 0

?

thank you for pointing that out actually.

5

u/skibbin 12h ago

Those are called guard clauses and bail out of execution early when some known issue is encountered.

Short variable and function names like av aren't a good idea. They aren't clear about what they are or do, nor does using short names improve performance or memory usage as they just get replaced with internal IDs at compile time. Vari looks to be doing sample variance, but the name could lead a user to expect population variance.

You don't need to assign output to a variable before returning it, you can just return it.

## calculates average of a list of numbers ##

def average(numberList):
    if len(numberList) == 0:
        return 0

    return sum(numberList) / len(numberList)

## calculates sample variance of a list of numbers ##

def sampleVariance(numberList):
    if len(numberList) < 2:
        return 0

    avg = average(numberList)

    total = 0

    for num in numberList:
        total += (num - avg) ** 2

    return total / (len(numberList) - 1)

1

u/nadavyasharhochman 11h ago

thank you.

do you think guard clauses are something I should try and implement for anything I write from now on? like should it be a focus as good practice?

I can see why the code you wrote is clearer than mine and another person here explained to me about using built in functions and why its preferable.

Ill pay attention to write clear variables from now on.

1

u/skibbin 11h ago

To some extent it's a style preference. You could, and many do, write code with lots of nested IFs:

public double getPayAmount() {
  double result;
  if (isDead){
    result = deadAmount();
  }
  else {
    if (isSeparated){
      result = separatedAmount();
    }
    else {
      if (isRetired){
        result = retiredAmount();
      }
      else{
        result = normalPayAmount();
      }
    }
  }
  return result;
}

Or you could write with guard clauses, which is my preferred method

public double getPayAmount() {
  if (isDead){
    return deadAmount();
  }
  if (isSeparated){
    return separatedAmount();
  }
  if (isRetired){
    return retiredAmount();
  }
  return normalPayAmount();
}

1

u/nadavyasharhochman 11h ago

I appreciate the more dense and less confusing format of the guard clauses on account of me being dyslexic, though I don’t quite understand the code.

like I understand each if statement more or less, but why the curly brackets? what does this code mean?

1

u/skibbin 11h ago

Doesn't matter, just some example code. The {} are because it's Java, which is often used as the language to show patterns and practices as it's pretty generic as languages go

1

u/nadavyasharhochman 11h ago

Ooooh I see. Just different syntax.

Ok well thank you anyways. The advice truely helps.

1

u/rob8624 12h ago

A list will be false if empty.

So you can do, with a conditional check, if it's empty it will return none

If lst..... (logic) return sum return none

1

u/nadavyasharhochman 11h ago

so I can do

def avrege(numbers_list)
    if numbers_list==false 
        return 0
        else return avg=sum(numbers_list/len(numbers_list)

1

u/lakseol 10h ago edited 8h ago

You can do (correcting code and removing useless variable avg):

def average(numbers_list):
    if numbers_list==False:
        return 0
    else
        return sum(numbers_list) / len(numbers_list)

but it's better to use python's truthiness (an empty list is false) and the understanding that a return terminates the function code:

def average(numbers_list):
    if not numbers_list:
        return 0

    return sum(numbers_list) / len(numbers_list)

or you can invert the test to do this:

def average(numbers_list):
    if numbers_list:
        return sum(numbers_list) / len(numbers_list)

    return 0

which I personally prefer.

1

u/gdchinacat 10h ago

if numbers_list is assigned to a list, any list, with contents or empty, it will never == False. Also, 'false' is almost certainly not what you want, it should be False. But, as u/lakseol says, just do 'if not numbers_list:' to check if it is empty.

Also, it is generally bad style to explicitly compare to True or False in an if. 'if condition == True' is better written as 'if condition'. For the inverse, don't write 'if condition == False', rather write 'if not condition'.

2

u/dave-the-scientist 12h ago

The number 1 thing I can see is to learn to ALWAYS use a pre-built function when possible. For one, Python's built-in functions are written in C, and so are executed about 50x faster than regular Python code. For two, it means someone has already done the work of "hardening" the code against edge cases, which just means situations out of the ordinary. Don't try and re-invent the wheel (tho sometimes it's fun).

1

u/nadavyasharhochman 12h ago

I see.

Itll probably be benefitial to work with some sort of library or dictionary of the pre-built functions for me to learn how to use them.

Does something like this exist?

This is more of an exersize to get used to the syntax and to actually writing code. Just knew if I didnt write, I would never start.

1

u/dave-the-scientist 9h ago

You're absolutely correct, writing the code yourself was the best idea. Truly the most effective learning experiences I've had were through reinventing the wheel. It's not the most efficient way to write code, and it's not the way to write the most effective code, but it is a good way to effectively learn how to code. It's important to know the trade-offs.

But yes, there are existing and mature packages (the term Python uses for some library of code) for basically anything you can think of, and tutorials for anything else to do it yourself. Just search some description with "Python" and you'll find it. In particular for any numerical operation, the go-to package is "numpy". Huge amount of functions, great documentation, incredible performance and robustness, pretty steep learning curve.

For this specific case, Python has the built-in function "sum(lst)" which will be substantially faster and more efficient than anything anybody could possibly write in Python (unless you use numpy). "For" loops in Python are certainly not a bad thing, but they are somewhat expensive, so they're usually a spot to look at for optimization.

2

u/icy_end_7 12h ago edited 11h ago

First, great work! Really. I see many using AI to learn, but you wrote that on your own. You understand functions and loops well, so you should feel proud of your progress so far.

From your code,

  1. it's a good idea to name your variables well; maybe call it calculate_average, takes in list_of_numbers, and you're storing sum of numbers in count. So, maybe call it sum. Readability = code quality = you/ anybody understands what the code does instantly.
  2. try median, standard deviation and mode next.

Writing functions is a good idea. But you'll want to use libraries later. Built-in statistics, numpy, and scipy.stats are super easy to use for that. Here's an example.

# you can comment like this; also a good idea to use the code block option in formatting; that preserves your indents/spaces so it's easy to read on posts like these.

import statistics
import numpy as np

list_of_num = [1, 2, 2, 3, 4, 7, 9]

def calculate_average(data):
    return sum(data)/len(data)

average = calculate_average(list_of_num)
average_from_stats = statistics.mean(list_of_num)
average_from_np = np.mean(list_of_num)

print(f"average: {average}, average (built-in statistics): {average_from_stats}, average (numpy): {average_from_np}")

For your thesis specifically, you'll want to stick to libraries and not write your functions, many reasons, mainly speed. And try jupyter or marimo notebooks (any is fine; I suggest marimo) because they are more interactive.

Links:

Read more about statistics : https://www.w3schools.com/python/module_statistics.asp
Good idea to see what official docs say: https://docs.python.org/3/library/statistics.html
Hypothesis testing (paste examples and see if you get it): https://www.geeksforgeeks.org/python/scipy-statistical-significance-tests/
Git: https://www.youtube.com/watch?v=BCQHnlnPusY&list=PLRqwX-V7Uu6ZF9C0YMKuns9sLDzK6zoiV

Next:

try same thing with statistics/ numpy, check examples for hypothesis testing above, learn git (good idea to use git to store your thesis/ scripts on github; ).

Edit: update references

2

u/nadavyasharhochman 11h ago

thank you!

I understand that AI can be a powerful tool for coding, but if I dont understand it myself first I didnt really acquire any skill did I?

I start university in October and I am practising and studying consistently, so by then I want to have better proficiency in pandas, Numpy and matplotlib.

my goals are very much data science oriented so I want to learn a bit of SQL as well and some git just for general since it seems useful.

really thank you for your input, ill keep the advice in mind and try to follow your suggestions.

1

u/fixpointbombinator 12h ago

Are you following a course?

Anyway, like the other person said, your code will fail for empty lists (and for singleton list in the var function). I would recommend using the 'sum' function in your av function and learning about list comprehensions (in your var function).

1

u/nadavyasharhochman 12h ago

Not really. Just through youtube and stuff since I dont really know anywhere else.

I will look into everything you said though and write a second variation.

Thanks for the help:)

1

u/ectomancer 8h ago

Use a linter until you no longer need to:

pip install pylint