Why do parenthesis make such a difference? - python

I wrote a code that returns the count of distinct case-insensitive alphabetic characters and numeric digits that occur more than once in the input string. Here's my code:
def duplicate_count(text):
sum_low = 0
dic_low = []
sum_up = 0
dic_up = []
sum_num = 0
dic_num = []
total = 0
for i in text:
if i.isalpha():
if i.islower() and text.count(i) > 1 and i not in dic_low:
dic_low.append(i)
sum_low = sum_low + 1
elif i.isupper() and text.count(i) > 1 and i not in dic_up:
dic_up.append(i)
sum_up = sum_up + 1
elif i.isdigit() and text.count(i) > 1 and i not in dic_num:
dic_num.append(i)
sum_num = sum_num + 1
total = sum_low + sum_up + sum_num
print (total)
The problem is, I noticed that when I missed parenthesis after "if i.isalpha()" this code worked perfectly with alphabetic characters but appeared to ignore digits, so for instance if I passed "aabbcdeBBAA" it printed "4", but if the argument was "11336" it printed "0". Later I found out that the parenthesis had been missed and corrected it, and the code started to work normally, but I still don't understand what the problem was. There was no any TraceBack, so I guess the problem was in missing parenthesis. Why does it make such a big difference?
PS: sorry if the code is too weird, I'm new to programming and just started to learn coding.
Thank you!

i.isalpha is an object (the method isalpha of your string i). It is not Null, nor does it correspond to a falsy value like 0, "", [] etc., so if checked for its boolean value, it is evaluated as True.
Only by adding (), you actually call that method.
A practical tip: There is a common beginners' mistake with file handles: myfile.close doesn't close the file myfile, only myfile.close() does. But the first statement is syntactically valid and will not raise an error. You just might be wondering why the file you just wrote is empty...

If you write i.isalpha means you are referring to the function, not actually calling the function, you need to add () at the end to call the function
>>> i = 'some text'
>>> obj = i.isalpha # just reference not actually call
>>> obj
<function str.isalpha>
>>> obj() # adding '()' executes the function
False
>>> i.isalpha()
False

Related

Confused about Python code (Beginner)

I've come across a question that I was confused about so decided to look it up. However, I'm a bit confused as to what some of the functions do in the code. The question was 'write a function to get rid of duplicate letters'
def remove_duplicates(s):
result = ""
dic = {}
for i in s:
if i not in dic:
result+=i
if ord(i.lower()) >= ord('a') and ord(i.lower()) <= ord('z'):
dic[i] = 1
return result
print(remove_duplicates("bookkeeper"))
I'm a bit confused as to what the purpose of the result = "" and dic = {}? I've never seen this before so no idea how it works.
And what does result+=i mean? And finally I have absolutely no idea what's going in the if ord line. Ord is something I just learned an hour ago so I have no idea how it's interacting with i.lower and 'a' / 'z'.
result = "" creates a variable named result and initializes it to a blank string.
dic = {} creates a variable named dic and initializes it to an empty dictionary. (Dictionaries are special Python objects.)
result += i is shorthand for result = result + i.
The if ord line is ensuring that i is a letter between A and Z. (Although this seems a very roundabout way to do it.)
Perhaps you should spend some time with a basic Python tutorial?
result = "" and dic = {} initallize the variables result as an empty string ans dic as a dictionary.
result+=i mean === result = result + i
About the ord() it checks if i.lower is in "range" of a - z

Return and assignment in recursive function in python: None type given, expected an int value

I am fairly new to python but worked with recursion previously. I came across this problem while working with recursive functions.
archive = {1: 0}
def engine(base, chain=0):
if base in archive:
return archive[base]
else:
if base == 1:
return chain
elif base % 2 == 0:
get = engine(base/2)
meaning = 1 + get
archive[base] = meaning
else:
next = 3 * base + 1
get = engine(next)
meaning = 1 + get
archive[base] = meaning
print archive(13)
I worked with scheme recently. So, I expected it to work.
I want the code to evaluate till the case bool(base==1) becomes true and then work it's way up ward making a new entry to the dictionary on each level of recursion.
How can I achieve that? I am just counting the level of recursion until the fore-mentioned condition becomes True with the variable 'chain'.
[Solved]: I missed the return statement in two clauses of if-else statement. The scheme would pass the function itself and the last return statement would do the work but not with python. I understand it now.
Thanks everyone who responded. It was helpful.
Your last two elif and else clauses have no return statements and Python returns None by default.

make a program return True if there is more than one dot in the string?

so I'm new to programming (and python) and I have to make this program that returns True if the string has zero or one dot characters ("." characters) and return False if the string contains two or more dots
here is what I currently have, I cannot get it to work for me, please correct me if I am wrong, thanks!
def check_dots(text):
text = []
for char in text:
if '.' < 2 in text:
return True
else:
return False
Use the builtin Python function list.count()
if text.count('.') < 2:
return True
It can be even shorter if instead of an if-else statement, you do
return text.count('.') < 2
Also, there are some errors in your function. All you need to do is
def check_dots(text):
return text.count('.') < 2
A correct and shorter version would be:
return text.count('.') <= 1
Python has a function called count()
You can do the following.
if text.count('.') < 2: #it checks for the number of '.' occuring in your string
return True
else:
return False
A shortcut would be:
return text.count('.')<2
Let's analyze the above statement.
in this part, text.count('.')<2: It basically says "I will check for periods that occur less than twice in the string and return True or False depending on the number of occurences." So if text.count('.') was 3, then that would be 3<2 which would become False.
another example. Say you want it to return False if a string is longer than 7 characters.
x = input("Enter a string.")
return len(x)>7
The code snippet len(x)>7 means that the program checks for the length of x. Let's pretend the string length is 9. In this case, len(x) would evaluate to 9, then it would evaluate to 9>7, which is True.
I shall now analyze your code.
def check_dots(text):
text = [] ################ Don't do this. This makes it a list,
# and the thing that you are trying to
# do involves strings, not lists. Remove it.
for char in text: #not needed, delete
if '.' < 2 in text: #I see your thinking, but you can use the count()
#to do this. so -> if text.count('.')<2: <- That
# will do the same thing as you attempted.
return True
else:
return False

python recursion vowel count

def count_vowels(s):
if not s:
return 0
elif s[0] in VOWELS:
return 1 + count_vowels(s[1:])
else:
return 0 + count_vowels(s[1:])
I see that this code works perfectly fine for finding the number of vowels in a string. I also understand recursion always calls for a base case. I guess my main problem with this code is what does the first if statement actually mean? What is it checking?
if not s:
return 0
if what not s? Is there any way to write the code without that portion?
This is your exit from recursion. Your recursion has to stop at some point of time (otherwise it will run forever).
It means that if the string is empty - return 0 (there are no vowels in empty string) and stop.
if not s checks if the string is empty. Empty strings are "false-y" objects in Python. If the string is empty, it must not have any vowels.
I realize you are probably required to use recursion here, but this would be a better way to do it in practice:
>>> VOWELS = set('aeiou')
>>> def count_vowels(s):
... return sum(x in VOWELS for x in s)
...
>>> count_vowels('hello world')
3

What causes my function to return None at the end? [duplicate]

This question already has answers here:
Why is "None" printed after my function's output?
(7 answers)
Closed 7 months ago.
My very simple python function is returning None at the end of it and I'm not sure quite why. I've looked at some other posts and still can't figure it out.
Here is my code:
def printmult(n):
i = 1
while i <= 10:
print (n * i, end = ' ')
i += 1
print(printmult(30))
Because in Python, every function returns a value, and None is what is returned if you don't explicitly specify something else.
What exactly did you expect print(printmult(30)) to do? You've asked it to evaluate printmult(30), and then print whatever results from that. Something has to result from it, right? Or were you maybe expecting some kind of exception to be raised?
Please be sure you understand that printing and returning are not the same thing.
You are not returning anything in the function printmult, therefore when you print the result of printmult(30) it will be None (this is the default value returned when a function doesn't return anything explictly).
Since your method have a print statement inside and it's not supposed to return something (usually when a method names is something like printSomething(), it doesn't return anything), you should call it as:
printmult(30)
not
print(printmult(30))
The other answers have done a good job of pointing out where the error is, i.e. you need to understand that printing and returning are not the same. If you want your function to return a value that you can then print or store in a variable, you want something like this:
def returnmult(n):
i = 1
result_string = ''
while i <= 10:
result_string += str(n * i) + ' '
i += 1
return result_string
print(returnmult(30))
def printmult(n):
i = 1
while i <= 10:
print (n * i, end = ' ')
i += 1
printmult(30)
The issue was that you were printing the return value of a function that returns nothing, which would print None
I came from Ruby as well and it seems strange at first.
If you print something that has a print statement in it, the last thing it returns is None.
If you just returned the values and then invoked a print on the function it would not output None.
Hope this helps :)

Categories