I'm new to python, just installed vs code on my Ubuntu 18.04 and ran some simple python code such as
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 20, 100) # Create a list of evenly-spaced numbers over the range
plt.plot(x, np.sin(x)) # Plot the sine of each x point
plt.show() # Display the plot
but how could I call a python snippet defining a class?
Here I got a solution for the "longest palindromic substring" problem, implemented as a class, but without any entry point similar to C++ 's main() function. How shall I call this "longest palindromic substring" code?
class LPS:
"""
#param s: input string
#return: the longest palindromic substring
"""
def longestPalindrome(self, s):
if not s:
return ""
n = len(s)
is_palindrome = [[False] * n for _ in range(n)]
for i in range(n):
is_palindrome[i][i] = True
for i in range(1, n):
is_palindrome[i][i - 1] = True
longest, start, end = 1, 0, 0
for length in range(1, n):
for i in range(n - length):
j = i + length
is_palindrome[i][j] = s[i] == s[j] and is_palindrome[i + 1][j - 1]
if is_palindrome[i][j] and length + 1 > longest:
longest = length + 1
start, end = i, j
return s[start:end + 1]
Outside of class (and after it!) call
LPS().longestPalindrome("someString")
Note the parenthesis after LPS and before .longestPalindrome. This way you create an object of class LPS allowing you to call its "nonstatic" methods (see that longestPalindrome has self as a parameter).
Another way would be to call it as
lps = LPS()
lps.longestPalindrome("someString")
Alternatively, omit the self parameter which is completely redundant in your case and call as
LPS.longestPalindrome("someString")
Note: self is like this in Java.
Edit: I see some answers omitting () after LPS, like LPS.longestPalindrome(“someString”). This is highly unhigienic Python, just like using ”” for character literals and ’ ’ for strings, although both are correct.
Generally in Java or C we create the object of the class and access any method of that class via the object.
But in Python you can simply use the class name followed by the dot operator and finally the method you want to access, like
LPS.longestPalindrome(s)
in your case
You can simply import your class by name and use class method in another python script or same script like this
import LPS
LPS.longestPalindrome(0, "Your String")
you can do it by adding these lines of code:
if __name__ == "__main__":
# Creates object of your class
lp = LPS()
# Calls the longesetPalindrome() with "prateek" as argument
response=lp.longestPalindrome("prateek")
# Prints the response which the function returns.
print(response)
Since, you are new to python and if you are looking for something similar like 'main()' of c++ in python then you can use
if __name__ == "__main__":
it works almost similar to main() but it is not a function.
Basically, Every Python module has its name defined and if this is ‘main’, it implies that the module is being run standalone by the user and we can do corresponding appropriate actions.
The if __name__ == “main”: is used to execute some code only if the file was run directly, and not imported.
Related
I'm looking for a way to change the variables defined inside a function after defining the function.
For example
def GetNthPower(x) :
n = None
return x**n
my_numbers_list = [11,23,45,56,78,98]
# now if I feel like I need the 4th power of some numbers in the list
GetNthPower.n = 4
for x in my_numbers_list :
print GetNthPower(x)
# If I want 7th power then
GetNthPower.n = 7
This obviously will not work, is there any way to do this?
N.B: I know we can achieve this by setting 'n' as an argument of the function, but I want to do it this way for a particular reason.
I want my function to have only one argument (for using the function in multiprocessing.Pool.map()).
You can define static variables inside functions, almost like you did:
def GetNthPower(x) :
return x ** GetNthPower.n
GetNthPower.n = 3
print(GetNthPower(2)) #8
Make sure to initialize correctly your GetNthPower.n before first use though.
If you're worried about initialization, you could go for this version which uses a default value 1:
def GetNthPower(x) :
return x ** (GetNthPower.n if hasattr(GetNthPower, "n") else 1)
I think it would still be better for you to write a function that takes two arguments, or use the predefined ** operator.
Don't use one function; create a function that makes your function, using a closure.
def nth_power_maker(n):
def _(x):
return x ** n
return _
my_numbers_list = [11,23,45,56,78,98]
# now if I feel like I need the 4th power of some numbers in the list
get_4th_power = nth_power_maker(4)
for x in my_numbers_list:
print(get_4th_power(x))
get_7th_power = nth_power_maker(7)
Alternatively, you could use functools.partial to bind a keyword argument to a function
from functools import partial
def get_nth_power(x, n):
return x ** n
get_third = partial(get_nth_power, n=3)
get_third(4)
64
x = 4
# in a loop
for pow in [2, 4, 6, 8]:
f = partial(get_nth_power, n=pow)
f(x)
I need to use a function as range but an error appears saying that n was not set:
NameError: name 'n' is not defined
I'm actually learning how to use python and I do not know if the syntax is correct, I just find examples of lists as ranges.
Could someone clear my ideas, give me some suggestions?
[EDIT1] My function z depends on j and f(n).
[EDIT2] I´m usind fibonacci ranges for integrate over a sphere.
The program is something like this:
def f(n):
a, b = 0, 1
for i in range(n):
a, b = b, a+b
return a
def y(n):
return f(n) + some_const
def z(j):
for j in range(0,f(n-1)):
return j*y(n) + j*f(n-1) + j*f(n)
You have
def z(j):
for j in range(0,f(n-1)):
return j*y(n) + j*f(n-1) + j*f(n)
Notice you say this takes something called j while your other functions take n.
Did you mean
def z(n):
for j in range(0,f(n-1)):
return j*y(n) + j*f(n-1) + j*f(n)
When you get an error check the line number it refers to.
Also, consider giving your variables longers names - just single letters get easy to muddle up!
As pointed out by the comment, once this stops giving the error message it might not do what you want.
You first function loops and then returns:
def f(n):
a = something
for i in range(n):
a = a + i
return a
(I presume something is set to, er, something)
Your z function returns as soon as it gets into the loop: perhaps you just want to collect the results and return them?
def z(n):
stuff = []
for j in range(0,f(n-1)):
stuff.append( j*y(n) + j*f(n-1) + j*f(n) )
return stuff
Notice the return is further left - no longer indented inside the for loop.
In fact you could use a list comprehension then:
def z(n):
return [j*y(n) + j*f(n-1) + j*f(n) for j in range(0,f(n-1))]
There are several problems with the snippet that you posted.
It would help if you include the code that calls the functions. It also seems that you should look into local-scope of vars in Python- it does not matter what you call the parameter passed into the function, so you could call the var in the brackets "n" for every function, but it is preferable to give them a meaningful name that indicates what that parameter represents- just useful for others looking at the code, and good practice!
Lastly, using a docstring inside the function makes it very clear what the functions do, and may include a desc. of the params passed (type/class).
def range_sum(n): # instead of f- range_sum seems appropriate
"""
Sums the range of numbers from 0 to n
>>> range_sum(4) # example data
10
"""
# no idea what a is meant to be, unless an accumulator to
# store the total, in which case it must be initialised
accum = 0
for i in range(1, n+1): #iterates from 1 to n
accum = aaccum + i
return a # returns the total
def y(m, const): # use a descriptive func name
"""
Sums the range of numbers from 0 to m and adds const
>>> y(4, 7) # example data
17
"""
return range_sum(m) + const
def z(j, n, m): # pass all the vars you need for the function so they have a value
"""
Something descriptive
>>> z(4, 2, 5) # example data
?
"""
total
for j in range(0,f(n-1)):
total += j*y(m) + j*f(n-1) + j*f(n)
return total
print("First Func, ", range_sum(4))
print("Second Func, ", y(4, 7))
print("Third Func, ", z(4, 2, 5))
Note that the number of arguments passed to each function matches the number expected by the function. It is possible to set defaults, but get the hang of getting this right first.
Not sure what the last function is meant to do, but as mentioned in the comment above, showing some code to illustrate how you call the code can be useful, as in the sample.
As a way of practicing python I'm trying to write a little program that creates sudoku puzzles. I've found multiple questions similar to my issue but none seem to exactly relate.
#!usr/bin/python3
from random import randint
class Puzzle :
def __init__(self, **puzzle):
puzzle = [[0 for x in range(9)]for y in range(9)]
def createEasy(self):
count = 0
while(count < 32):
i = randint(0,8)
j = randint(8,9)
k = randint(1,9)
if (self.puzzle[i][j] != 0):
self.puzzle[i][j] = k
count += 1
def createMedium(self):
count = 0
while(count < 30):
i = randint(0,8)
j = randint(8,9)
k = randint(1,9)
if (self.puzzle[i][j] != 0):
self.puzzle[i][j] = k
count += 1
def createHard(self):
count = 0
while(count < 26):
i = randint(0,8)
j = randint(8,9)
k = randint(1,9)
if (self.puzzle[i][j] != 0):
self.puzzle[i][j] = k
count += 1
def main():
print("Welcome to sudoku!!!")
answer = input( "what level of difficultly do you want today?")
if (answer == "easy"):
self.createEasy()
for x in Puzzle.puzzle:
for y in x:
print(y)
print('\n')
Puzzle.main()
Most answers I found either had to do with functions not being defined in the right order or not putting "self" in the parameter list of all the functions. One answer even said to get rid of "self" parameter in the init function but that didn't help either. I also found this answer though I don't think it relates either. NameError: name 'self' is not defined The only thing I can think of is that I need to declare the list called puzzle elsewhere since it's suppose to be a class variable but from python code I've I don't think that's true not to I'm not sure since it's 2d and writing puzzle = [][] is wrong.
Sorry here's the whole output with error.
Welcome to sudoku!!!
what level of difficultly do you want today?easy
Traceback (most recent call last):
File "sudoku_maker.py", line 49, in <module>
Puzzle.main()
File "sudoku_maker.py", line 43, in main
self.createEasy(self)
NameError: name 'self' is not defined
It seems like you want main() to be a class method or a static method rather than an instance method. Class methods are methods that are not bound to an object but to a class. In that case, you need to define it clearly.
https://docs.python.org/3.5/library/functions.html#classmethod
https://docs.python.org/3.5/library/functions.html#staticmethod
This answer clearly explains the difference between class methods and static methods.
What is the difference between #staticmethod and #classmethod in Python?
One more way of solving your problem is :
Make main() as an instance method by passing self as an argument.
main(self)
Create an object of Puzzle.
puzzle = Puzzle()
Call the object's main method.
puzzle.main()
The error disappears if you make the following changes:
Add self as a parameter of the main() function.
Create an instance of the class: p = Puzzle() and call p.main() then.
Write self.puzzle in the __init__ function instead of just puzzle.
(Then there are different errors though not related to this one)
First of all, in __init__ method when you declare puzzle attribute, you forgot the self, so it is not declared:
def __init__(self, **puzzle):
self.puzzle = [[0 for x in range(9)] for y in range(9)]
You also forgot de self when declaring the main function. And, inside of this one you got an error too, when you call Puzzle.puzzle, it should be with the self instance:
def main(self):
print("Welcome to sudoku!!!")
answer = input( "what level of difficultly do you want today? ")
if (answer == "easy"):
self.createEasy()
for x in self.puzzle:
for y in x:
print(y)
print('\n')
And finally, when you call the function. You need to create the instance of Puzzle first, but you are using Puzzle.main, so your not initializing the object, so the self instance will not exist.
You have to do it like this:
Puzzle().main()
However, there's another error when using randint(a, b), because this function generate a random int between a and b, but including the limits, so when you call it in createEasy, the 9 should not be in the limits.
please keep in mind that while I showcase my code, that I am fairly new to programming. So please forgive any problems. I am writing a piece of python code that uses the output of one function and then averages it in another function. I am having troubling proceeding on how to do that, this is what I have so far:
def avg(A):
if not A:
return 0
return sum(A) / len(A)
Using the function above, I have to use it to calculate the average of the function produced below:
def SampleFunction(): # Example Function
A = list(range(300))
for i in range(300):
if i%2:
A[i] = 3.1*(i+1)**1.2 - 7.9*i
else:
A[i] = 4.2*(i+2)**.8 - 6.8*i
return A
Below this is a function I have trying to tie the two together.
def average(SampleFunction):
if len(SampleFunction) == 0: return 0
return sum(SampleFunction) / len(SampleFunction)
def avg(A):
if not A:
return 0
return sum(A) / len(A)
def SampleFunction(): # Example Function
A = list(range(300))
for i in range(300):
if i%2:
A[i] = 3.1*(i+1)**1.2 - 7.9*i
else:
A[i] = 4.2*(i+2)**.8 - 6.8*i
return avg(A) #Return the avg of A instead of just A
You are right at the moment of passing SampleFunction as parameter, but it's a function, you have to call invoke it inside average():
def average(some_function):
result = some_function() # invoke
return avg(result) # use the already defined function 'avg'
When you call it, pass the function you want to average():
print average(SampleFunction)
Note:
I would recommend you to follow Python naming conventions. Names like SomeName are used for classes, whereas names like some_name are used for functions.
I have a function that returns a number. I want to assign a variable to have this value, but python gives a runtime error when I say temp = foo(i, j) : NameError: name 'foo' is not defined. Note that I've changed the function bodies of bar and foo around, obviously having a function that just returns 1 is useless, but it doesn't change my error.
sum = 0
for i in range(2, 100):
for j in range(2, i):
temp = foo(i, j)
if (temp > 100):
sum = sum + 1
print sum
def bar (n, a):
r = 1
return r
def foo (n, a):
s = bar(n, a)/factorial(5);
return s
def factorial (n):
r = 1
for i in range (2, n + 1):
r *= i;
return r
Names in Python do not exist until they are bound. Move the def foo(...): block above the code that uses foo().
Your definition of foo is AFTER you use it in the file. Put your function definition above the for loop.
As per other answers, your issue is the order in which you run your code: foo hasn't been defined yet when you first call it. Just wanted to add a comment about best practices here.
I always try to put everything in a function and then call any scripts at the bottom. You've probably encountered this pattern before, and it's a good habit to get into:
CONSTANT = 5
def run():
for i in xrange(CONSTANT):
print foo(i) # whatever code you want
def foo(n):
# some method here...
pass
if __name__ == "__main__":
run()
if you run this with python script.py or by hitting f5 in idle, run() will be executed after everything is defined.
By following this pattern you don't have to worry about the order you define your functions in, and you get the added benefit of being able to import foo with other functions without having your script execute during the import, which is probably not a desired behavior.