Why is count in quotes and how does hasattr work in an if statement?

Can someone explain why "count" in the if hasattr(element, "count") line of this problem does not return false?

The way I am understanding, hasttr() is that it takes in 2 arguments and it checks if the 2nd argument exists and returns True if it does.

Shouldn’t "count" return False and skip the print statement?

I probably just need some sleep but would really appreciate someone helping me understand why if hasattr(element, "s") doesn’t work.

Thank you. :slight_smile:

image

https://www.codecademy.com/paths/computer-science/tracks/cspath-python-objects/modules/cspath-python-classes/lessons/data-types/exercises/attribute-functions

6 Likes

Even thought the count is in " " it’s not checking for the string count. It’s using the count method. In this case it just checking to see if the item is a string.

This attribute thing hasn’t made any sense to me. Incoming really long rant/confusion:

First of all, both "count"s in the solution function in ways that the course has not taught, so I couldn’t get the answer right because they were never explained.

(Side Note):
This is by biggest complaint about this course is being occasionally roadblocked by being asked to do something that hasn’t been taught how to do, and I have to reverse learn it from looking at the solution (like what “.index” does in module 4. (Fortunately a lot of it is self-explanatory after-the-fact so I can still learn it)

Anyways, looking at the “.count” in the print() statement, I can infer that it probably counts the number of "s"s in element. But it was really confusing at first after just coming from learning about methods in classes and and calling them. So I wasn’t sure if “.count” was a built-in function of Python or calling a method that was hidden or something.

Secondly, from what dataace74980 was saying, it sound like the first “count” checks whether each item is in the list is a string or not and also somehow it’s using the “count method” at the same time? Now I’m really confused, and on top of that, the solution prints “5” and “2” (which I assume are counted by the “.count” function"). So it looks like it counted the number of "s"s in the string as well as in the list. That tells me that the first “count” isn’t checking whether something is a string or not because the 2 "s"s are from the list which isn’t classed as a string (and there isn’t a second loop looking at the list). This also makes me wonder why it did not include the “s” from the dictionary. So what the heck does the first “count” do?

Any explanation of this would be greatly appreciated.

25 Likes

@triangularapple @netrunner25041
Consider this list -
how_many_s = [{‘s’: False}, “sassafrass”, 18, [“a”, “c”, “s”, “d”, “s”]]
we are looping through individual element of these list.
First Iteration -
element = {‘s’: False}
Q) Does this dictionary element is having inbuilt function count(argument) !?
Ans = We can check it using hasattr(element, “count”) function . It will return false as Dictionary does not have in-built method / function count() .
You can check and confirm in-built methods of dictionary here (https://www.programiz.com/python-programming/methods/dictionary)

Second Iteration -
element = “sassafrass”
lets check whether String in-built methods/function have in-built count() method.
You can confirm from here . (https://www.programiz.com/python-programming/methods/string)
Yes, String has in-built count method, so the hasattr(element, “count”) will return true, and next line will be executed.
Next line is print(element.count(“s”)) - As In second iteration element’s datatype is string, it will call string in-built method count(argument) and it will count occurrences of character/letter of that string.

In these way, whole list will be looped and executed.
Hope these helps.

32 Likes

The line in question returns “False” in response to the if statement, so it doesn’t print anything (including “False”). Since the if statement only says to print element.count(“s”) if the attribute is present, there’s no need to print False.

My solution followed by your solution – both work correctly, and neither says to print False:

for s in how_many_s:

  try:
    print(s.count("s"))
  except AttributeError:
    None
    
for element in how_many_s:
  if hasattr(element, "count"):
    print(element.count("s"))

# prints True or False    
for element in how_many_s:
  print(hasattr(element, "count"))

Hello!

Are methods considered attributes? When we use the hasattr() function, it seems to find the “count()” method, but I can’t wrap my head around why it would do this, since I’ve been under the impression that attributes and methods are separate concepts…

Thanks in advance!

Totally didn’t understand this lesson: In your example

I don’t get the line

if hasattr(element, "count"):

Googling I found this python code:

class Person:
    age = 23
    name = 'Adam'

person = Person()

print('Person has age?:', hasattr(person, 'age'))
print('Person has salary?:', hasattr(person, 'salary'))

first is True and second is False…

It makes much much more sense for me like this and it’s in the context of classes.
(We are checking in the Person class for a age attribute)

8 Likes

+1 exactly same rant for me

Yes they are. Attributes are associated objects, and methods are associated objects so that makes them attributes.

We’re given a list, and lists are made up of zero or more elements, which we are iterating over. element refers to a value from the list.

count is a method of some objects, but not of others. For instance, dict and int objects do not have a count() method, and therefore no count attribute. Strings and lists do have that attribute.

hasattr is a built in function for testing whether objects have a particular attribute, or not.

When we test either the string element or the list element in the given list, we find that they do have a count attribute so we can call that method of them to count the s's in their value.

if hasattr(element, 'count'):
    print (element.count('s'))

Note that we are calling the method on the element. Without this check in place, we would raise an exception on the dict object, right off the top.

10 Likes

Tnx this was a helpful explanation!

2 Likes

Great questions/rant. Exactly. Thank you.

Excellent explanation. I tested multiple built-in string methods in place of “count” and they all work, return the same result. Thank you!

1 Like

So we could put any kind of string as the second argument and it will be true anyway ? for example:

for element in how_many_s:
if hasattr(element, “anything”) :
print(element.count(“s”))

This will work to?

No. In the list that’s being evaluated,
[{'s': False}, 'sassafrass', 18, ['a', 'c', 's', 'd', 's']]
… there are objects of four types: dictionary, string, int and list. The attribute mentioned must be an attribute of the particular type of object.

Let’s comment out the print line, put in a different one, then explore several different attributes:

how_many_s = [{'s': False}, "sassafrass", 18, ["a", "c", "s", "d", "s"]]
print(" Original list = {}\n".format(how_many_s))

for attr in ["keys", "count", "bit_length", "append"]:    
    for item in how_many_s:
        if hasattr(item, attr):      
    #    print(item.count('s'))
            print("attribute = {},  item = {}, item type = {}".format(attr, item, type(item)))
    print("***")

Output

 Original list = [{'s': False}, 'sassafrass', 18, ['a', 'c', 's', 'd', 's']]

attribute = keys,  item = {'s': False}, item type = <class 'dict'>
***
attribute = count,  item = sassafrass, item type = <class 'str'>
attribute = count,  item = ['a', 'c', 's', 'd', 's'], item type = <class 'list'>
***
attribute = bit_length,  item = 18, item type = <class 'int'>
***
attribute = append,  item = ['a', 'c', 's', 'd', 's'], item type = <class 'list'>
***

You can see here that the attribute count is shared by both string and list, which is why the original function printed out, first 5, then 2, from the string and the list, respectively.

I couldn’t get my head around that, now i do , thank you ! This was really helpful

1 Like

So this is checking whether the method is available for the type of object each element is? So these are not attributes that have been assigned based on any class. Just attributes of types in python.

@petercook0108566555 Yes, hasattr() function checks whether the method/attribute is defined or not in an object.
If you have to check all the attributes of an object, then open your python shell and view it using:

dir(str)
dir(dict)
dir(int)
dir(list)

or
for above example u can check it using below code:

how_many_s = [{'s':False},"sassafrass",18,['a','c','s','d','s']]
for i in how_many_s:
	print('{a} has attributes {b}'.format(a=type(i),b= dir(type(i))))
2 Likes

Can someone help me understand why count needs to be in parenthesis for this exercise? My understand is that the line of code is cycling through the list and seeing if the variable is able to ‘count’ and if so count the number of ‘s’ in the variable. If that’s the case why put ‘count’ in a string vs. referring the actual function count?

Do you mean this line?

if hasattr(element, 'count'):

We do this to verify that the element has a count method, as some do not. If we try to run a method that is not an attribute, then it will raise an exception, halting the code.

Hi Roy - thanks for the response. I understand that we’re checking to see if the element has a count method but i’m still not 100% sure why we just don’t search for count vs. ‘count’ . For some reason i thought if you are searching for count as a string (i.e. with quotations). For example you would use a piece of code like this: print(“The count is:”, count) not print(“The count is:”, ‘count’)