Python output print problem for palindrome permutation - python

I want to see if a given string is a permutation of a palindrome or not. Here is the python solution. I am trying to test it for the following input example but I am getting error.
import re
class Solution(object):
def isPalindrome(self, s):
regex = re.compile('[^a-zA-Z0-9]')
s=regex.sub('', lower(s))
print(s)
j=len(s)-1
for i in range(0,len(s)/2):
if s[i]==s[j]:
j-=1
else:
return False
return True
# The word is civic , which is a palindrome. So it should return true.
s = "vicic"
print(isPalindrome(s))
I get this error : "NameError: name 'self' is not defined". How can I fix it and print the output?

isPalindrome() as you have defined it here is associated with the object/class Solution.
Unlike a regular Python function your method is called on your solution object.
If you want to call it given your current structure you must first instantiate an instance of solution, create the string you want to test, and then call the method on the object:
sol = Solution() # instance of Solution
s = "vicic"
sol.isPalindrome(s) # False
Also note that I took your string s out from where you had previously declared it as it was in the wrong scope.
In general it seems like your solution class may be a bit of overkill, part of the beauty of Python is its ability to write simple scripts, so you could rewrite isPalindrome() as a plain function and not a method.

Related

How to dynamically access a class and its methods from an input? [duplicate]

This question already has answers here:
How to get class object from class name string in the same module?
(3 answers)
Closed last year.
I am creating a python CLI, where user can provide an operation they want to perform, for eg:
sum 10 15
In my code, I have defined my classes as follows:
class Operation:
# common stuff
pass
class Sum(Operation):
identifier = "sum"
def perform(a, b):
return a + b
class Difference(Operation):
identifier = "diff"
def perform(a, b):
return a - b
Now, in my CLI, if I type sum 10 15 I want to return the result of Sum.perform(10, 15) and similarly if I type diff 10 15, I return the result of Difference.perform(10, 15), as sum is the identifier of class Sum and diff is the identifier of class Difference.
How do I dynamically access the class and its perform method, when I get the input directly from user input?
Classes in Python are first-class citizens, meaning they can be used as standard objects. In particular we can simply store them in a dictionary:
my_dict = {
'sum': Sum,
'diff': Difference,
}
and so on. Then when you get the operation name as string from command line you simply do
my_dict[op_name].perform(a, b)
Note that this is a very basic (and you will soon see problematic, e.g. not all operators accept two arguments) approach to what is known as parsing and abstract syntax trees. This is a huge topic, a bit hard but also very interesting. I encourage you to read about it.
// EDIT: If you want to keep identifier on the class, then you can apply a simple class decorator:
my_dict = {}
def autoregister(cls):
# It would be good idea to check whether we
# overwrite an entry here, to avoid errors.
my_dict[cls.identifier] = cls
return cls
#autoregister
class Sum(Operation):
identifier = "sum"
def perform(a, b):
return a + b
print(my_dict)
You have to remember though to import all classes before you use my_dict. In my opinion an explicit dict is easier to maintain.
Reading your comment, I think you need to interpret the input. The way I would go about this is splitting the input by spaces (based on your example), and then checking that list. For example:
# This is the place you called the input:
input_unsplit = input("Enter your command and args")
input_list = input_unsplit.split(" ")
# Check the first word to see what function we're calling
if("sum") in input_list[0].lower():
result = Sum.perform(input_list[1], input_list[2])
print(result)
# this logic can be applied to other functions as well.
This is a simple solution that could be hard to scale.
=== EDITED ===
I have more to add.
If used correctly, dir() can make a list of defined classes up to a certain point in the code. I wrote a calculator for my precal class, and in it I chose to use dir after defining all the math classes, and then if the name met certain conditions (i.e not main), it would be appended to a list of valid args to pass. You can modify your classes to include some kind of operator name property:
def class Addition:
self.op_name = "sum"
and then perform to take in an array:
def perform(numbers):
return numbers[0] + numbers [1]
To solve many of your scalability issues. Then, after declaring your classes, use dir() in a for loop to append to that valid array, like so:
valid_names = []
defined_names = dir()
for name in defined_names:
if '_' not in name:
if name not in ("sys","argparse","<any other imported module/defined var>"):
valid_names.append(name)
Note that making this step work for you is all in the placement in the script. it's a bit tedious, but works flawlessly if handled correctly (in my experience).
Then, you can use eval (safe in this context) to call the method you want:
# get input here
for name in defined_names:
if eval(name).op_name == input_list[0].lower():
eval(name).perform(input_list)
This should be a fairly easy-to-scale solution. Just watch that you keep the dir check up to date, and everything else just... works.

How to use strings as name to define a function?

What I want:
I want to use string to be name of a function, I am defining. Code to reproduce result:
def creator(string):
def string():
return 0
return string
So the creator function takes an input string, say 'test1' and the creator function should create a global function named test1. So whenever I call test1() (as a normal function call) it should return 0.
Doubts whether you really need it aside, you cannot do this in Python.
What you are looking for is a way to set a global from local context. The way Python resolves variable names (scoping) doesn't allow to do so.

Having error message on creating a module in Python

I'm starting to learn Python and I find it really interesting. I am trying to create my own module and I ran into a bump. The code goes like this:
def break_words(sentence):
words = sentence.split(' ')
return words
def sort_words (words):
sort_word=sorted(words)
return sort_word
The second function has argument words fed in by the first, and I think it should work since it has been returned, but on running filename.sort_words(words) in Python, it gives an error message of NameError:global name 'words' is not defined. And it's requiring me to define words like words=filename.break_words(sentence) before it runs the second function.
What's wrong with my code?
You should try to explain yourself better in future, it's very confusing to read and probably the reason nobody replied.
This is what I think you want to know:
import filename
words = filename.break_words('some sentence goes here')
print filename.sort_words(words)
Have you tried that?
edit:
Variables in Python are always defined in scopes, so defining one variable in a function means that it is not defined anywhere outside the function.
'return' simply returns the value of that variable to the caller.

Parentheses in Python's functions and decorators(wrappers)

Thanks for reading my question. As I'm still new to Python, I would like to ask about the () in Python.
def addOne(myFunc):
def addOneInside():
return myFunc() + 1
return addOneInside # <-----here is the question
#addOne
def oldFunc():
return 3
print oldFunc()
Please note that on line four, although the programme returns a function, it does not need parentheses(). Why does it NOT turn out with an error for syntax error? Thank you very much for your answers in advance!
The parentheses are used to run a function, but without them the name still refers to the function just like a variable.
return myFunc() + 1
This will evaluate the myFunc function, add 1 to its value and then return that value. The brackets are needed in order to get the function to run and return a numeric value.
return addOneInside
This is not actually running addOneInside, it is merely returning the function as a variable. You could assign this to another name and store it for later use. You could theoretically do this:
plusOne = addOneInside
plusOne()
And it will actually call the addOneInside function.
The particular instance in your initial question is known as a Decorator, and it's a way for you to perform code on the parameters being passed to your function. Your example is not very practical, but I can modify it to show a simple use case.
Let's say that you want to only have positive numbers passed to your function. If myFunc is passed a negative number, you want it to be changed to 0. You can manage this with a decorator like this.
def addOne(myFunc):
def addOneInside(num):
if num < 0:
num = 0
return myFunc(num)
return addOneInside # <-----here is the question
#addOne
def oldFunc(number):
return number
To explain, the #addOne is the decorator syntax, and it's attaching the addOneInside function to be called on the argument/s of oldFunc whenever you call it. So now here's some sample output:
oldFunc(-12)
>>> 0
oldFunc(12)
>>> 12
So now you could add logic to oldFunc that operates independently of the parameter parsing logic. You could also relatively easily change what parameters are permitted. Maybe there's also a maximum cap to hit, or you want it to log or note that the value shouldn't be negative. You can also apply this decorator to multiple functions and it will perform the same on all of them.
This blogpost explained a lot for me, so if this information is too brief to be clear, try reading the long detailed explanation there.
Your indentation in function addOne() was incorrect (I have fixed it), but I don't think that this was your problem.
If you are using Python3, then print is a function and must be called like this:
print(oldFunc())

Python String Comparison function()

I am checking a piece of Python code I found online (http://www.exploit-db.com/exploits/18305/), and I'm stuck over a piece of code.
To be honest I don't know Python, but I have experience in other programming languages.
The method _computeCollisionChars generates a number of characters and then adds them to a dictionary if they are different. Below is the method signature along with the relevant part for the question. Note: The actual code can be found on the linked source.
def _computeCollisionChars(self, function, count, charrange):
baseStr = ""
baseHash = function(baseStr) # What is this?
for item in source:
tempStr = ""
if tempStr == baseStr:
continue
if function(tempStr) == baseHash: # What type of comparison is this?
# logic goes here...
return
My questions are:
What does the function parameter mean in the method signature?
Most importantly what does function(string) do? Why are there two
checks, and what sort of output does function(tempStr) generate
then?
Thanks a lot guys!
Apparently you can pass any callable object as function to _computeCollisionChars. Then baseHash is initialised as the result of calling function with an empty string as parameter. Inside the loop, the condition reads: if the result of function called with an empty string as parameter equals the baseHash do this and that. Which is kind of senseless, because tempStr is always '' and baseHash never changes (or you didn't post that part).
In the current snippet the second if is never reached, because invariably tempStr == baseStr == ''.
As the commentors pointed out, in the real code tempStr and baseStr do indeed change and function is expected to be a hashing-function (but any other function which takes a string as argument should work).
In Python functions are first class objects, so they can be passed as arguments to other functions just fine. So function(baseStr) is calling the function object passed to _computeCollisionChars.
Note that Python doesn't check that it is a function object passed as an argument - it just implicitly expects this (and the program would crash it is wasn't, raising a TypeError exception).
>>> def f1():
print "Hello world"
>>> def f2(function):
function()
>>> f2(f1)
Hello World
>>> f2("not a callable function")
TypeError: 'str' object is not callable

Categories