User-Defined Function in Python

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

The forum discussion centers on the implementation of user-defined functions in Python, specifically regarding the calculation of the Madelung constant. The original code produced incorrect values due to improper use of the assignment operator and incorrect indentation of the return statement. The corrected function accumulates the value of M using the += operator and returns the final result after all iterations. With these adjustments, the function successfully computes the Madelung constant as approximately 1.7361319160639026.

PREREQUISITES
  • Understanding of Python programming, particularly functions and loops
  • Familiarity with mathematical concepts such as the Madelung constant
  • Knowledge of Python's indentation rules and their impact on code execution
  • Experience with the math module in Python, specifically the sqrt function
NEXT STEPS
  • Review Python function definitions and best practices for returning values
  • Explore the use of loops in Python and how to accumulate results effectively
  • Learn about debugging techniques in Python to identify logical errors
  • Investigate the mathematical background of the Madelung constant and its applications
USEFUL FOR

This discussion is beneficial for beginner to intermediate Python developers, particularly those interested in mathematical programming and function optimization. It is also useful for educators teaching programming concepts related to functions and loops.

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 5 ·
Replies
5
Views
3K
Replies
1
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