User-Defined Function in Python

  • Context: Python 
  • Thread starter Thread starter K_Physics
  • Start date Start date
  • Tags Tags
    Function Python
Click For Summary

Discussion Overview

The discussion revolves around the implementation of user-defined functions in Python, specifically focusing on a code snippet intended to calculate the Madelung constant. Participants explore issues related to the function's logic, structure, and output values, with an emphasis on debugging and understanding the code's behavior.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Homework-related

Main Points Raised

  • One participant notes that the code produces incorrect values when encapsulated in a user-defined function, despite working correctly outside of it.
  • Several participants question the necessity of looping through multiple indices (i, j, k) if the function is only returning a single value, suggesting that the logic may be flawed.
  • Concerns are raised about the indentation of the return statement, which may cause the function to exit prematurely, returning a value before completing all iterations.
  • A participant highlights that the original code used an assignment operator (=) instead of an addition assignment operator (+=), which would prevent the accumulation of values in M.
  • Another participant provides a simplified version of the function to illustrate that the same result can be achieved without unnecessary complexity.
  • One participant successfully modifies the function based on feedback, correcting the logic and indentation issues, and confirms that the function now produces the expected output.

Areas of Agreement / Disagreement

Participants generally agree on the issues present in the original code, particularly regarding the use of the return statement and the assignment operator. However, there is no consensus on the initial intent of the function or the best approach to achieve the desired outcome.

Contextual Notes

Some limitations in the discussion include unclear initial objectives for the function, potential misunderstandings about the purpose of looping, and the importance of proper indentation in Python code.

Who May Find This Useful

This discussion may be useful for beginners in programming, particularly those learning about user-defined functions in Python and debugging techniques.

K_Physics
Messages
9
Reaction score
0

Homework Statement


So currently I'm working with user-defined functions. Initially, the code inside the user-defined function worked but when I attempted to change it into a user-defined function, it produces incorrect values.

Homework Equations


No need for any equations

The Attempt at a Solution


If I were to remove the code within the user-defined function, the code gives a value of M around 1.7361319160639026, which is correct. But for some reason when I execute this code (as a user-defined function), I get values of M which are far too low. I'm slightly confused toward why this happens.
Python:
from math import sqrt

from matplotlib import pyplot as plt
from pylab import plot, show

def function(L):
   
    M = 0.0

    for i in range(-L,L+1):

        for j in range(-L,L+1):        

            for k in range(-L,L+1):

                if not (i==j==k==0):

                    M = ((-1)**(i+j+k+1))/sqrt(i*i +j*j +k*k)

                return M

list = []
L = 0

while int(L) < 50:
    list.append(L)
    L = int(L) + 1
    print(function(L))
 
Technology news on Phys.org
What are you trying to do? Why bother looping on i, j, and k when you are only calculating a single value and then returning? As I read this code, it will just return the value of:
M = \frac{-1^{-3L+1}}{\sqrt{3 L^2}}
 
phyzguy said:
What are you trying to do? Why bother looping on i, j, and k when you are only calculating a single value and then returning? As I read this code, it will just return the value of:
M = \frac{-1^{-3L+1}}{\sqrt{3 L^2}}
Initially I was calculating only one value. In this new code, I have to graph values of L from 1-50 with the corresponding M value. The issue is, none of the M values were correct after changing it into a user-defined function.
 
Like @phyzguy said, it seems weird to me that you are looping through i, j, and k, where each loops all the way to L, and calculating a brand new value of M each iteration, independent of previous iterations.

Also, there seems that there is an issue with the indentation of your "return M" statement. As it is now, the function will return immediately when i, j, k, [are all -L] and M are all [is] zero. (Python code is structured through indentation, and it looks to me that is an issue here.)

Maybe it would help if we knew what exactly it is that the code is supposed to do.
 
collinsmark said:
Like @phyzguy said, it seems weird to me that you are looping through i, j, and k, where each loops all the way to L, and calculating a brand new value of M each iteration, independent of previous iterations.

Also, there seems that there is an issue with the indentation of your "return M" statement. As it is now, the function will return immediately when i, j, k, and M are all zero. (Python code is structured through indentation, and it looks to me that is an issue here.)

Maybe it would help if we knew what exactly it is that the code is supposed to do.
The end goal of the code is to graph values of L and the corresponding value of M with the use of user-defined functions. Sorry if this was unclear. I didn't continue to plot, as the values of M produced were incorrect.
 
K_Physics said:
The end goal of the code is to graph values of L and the corresponding value of M with the use of user-defined functions. Sorry if this was unclear. I didn't continue to plot, as the values of M produced were incorrect.
I still don't understand. In the following code
Code:
def function F
     for i in range (-10, 10):
          return i

the function will return a single value of -10. Why not just set i=-10 and forget about the loop? Why bother with the loop if the function only returns a single value independent of loop iterations?
 
collinsmark said:
I still don't understand. In the following code
Code:
def function F
     for i in range (-10, 10):
          return i

the function will return a single value of -10. Why not just set i=-10 and forget about the loop? Why bother with the loop if the function only returns a single value independent of loop iterations?
The idea behind it was, the function will take the argument L multiple times

Code:
list = []
L = 0

while int(L) < 50:
    list.append(L)
    L = int(L) + 1
    print(function(L))

This way we can get the M values with the corresponding L value. I want to point out that I am a beginner. So I may not be correct in my approach.
 
I think you're still not getting that the code is probably not doing what you think it does. Note that function1 and function2 below do the same thing, but function2 is a lot simpler. Can you post the code without the user defined function that worked?

Python:
def function1(L):
     for i in range(-L,L):
          return i

def function2(L):
     return -L
 
  • Like
Likes   Reactions: K_Physics
phyzguy said:
I think you're still not getting that the code is probably not doing what you think it does. Note that function1 and function2 below do the same thing, but function2 is a lot simpler. Can you post the code without the user defined function that worked?

Python:
def function1(L):
     for i in range(-L,L):
          return i

def function2(L):
     return -L

This code was just designed to output the value of M, which happened to be around 1.7361319160639026
Python:
from math import sqrt

L = 50
     
M = 0.0

for i in range(-L,L+1):

    for j in range(-L,L+1):        

       for k in range(-L,L+1):

           if not (i==j==k==0):

              M += ((-1)**(i+j+k+1))/sqrt(i*i +j*j +k*k)

print("The Madelung constant is: ", M)
 
  • #10
OK, now we're getting somewhere. You're original code had M +=, which means the value of ((-1)**(i+j+k+1))/sqrt(i*i +j*j +k*k) was added to M each time through the loop. So the final value of M was the sum of a bunch of terms. When you converted it to a function, you made two mistakes:

(1) You just put M = instead of M+=, so M just has a single terms instead of a sum of terms. Note that
M += something is the same as M = M + something.
(2) You put the return inside the loop instead of at the completion of the loop.

If you modify your function so that it looks like the function below, I think it will work. Do you see the differences?

Python:
def function(L):  
    M = 0.0
    for i in range(-L,L+1):
        for j in range(-L,L+1):       
            for k in range(-L,L+1):
                if not (i==j==k==0):
                    M += ((-1)**(i+j+k+1))/sqrt(i*i +j*j +k*k)
    return M
 
  • Like
Likes   Reactions: K_Physics
  • #11
Python:
from math import sqrt

def function(L):
    
     M = 0.0

     for i in range(-L,L+1):

         for j in range(-L,L+1):       

             for k in range(-L,L+1):

                 if not (i==j==k==0):

                     M += ((-1)**(i+j+k+1))/sqrt(i*i +j*j +k*k)

     return M

b = function(50)
print (b)
Your original code was missing the += operator in the line that assigns a value to M. Also, the return statement needs to be aligned to the same indentation as the outermost for loop (the loop on i). In your code this wasn't the case. Python doesn't use braces as C and C++ and related languages do, so it's crucial that you get the indentation right.

With 50 as the input to the function, I get a value of 1.7361319160639026.
 
  • Like
Likes   Reactions: K_Physics
  • #12
I got it to work! Thanks for the help!
 

Similar threads

Replies
1
Views
3K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
Replies
1
Views
2K
  • · Replies 18 ·
Replies
18
Views
2K
Replies
55
Views
7K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 3 ·
Replies
3
Views
1K