<jupyter_start><jupyter_text>Creating Our Own Objects<jupyter_code>class PlayerCharacter:   #Another rule is to have the name singular
    def __init__(self, name):
        self.name = name
        
    def run(self):
        print('run')
        
player1 = PlayerCharacter()
print(player1)<jupyter_output><empty_output><jupyter_text>When we build a class we usually see __init__ method/constructor method and this is automatically called when we instantiate(calling the class to create an object). When we instantiate, player1 = PlayerCharacter() it automatically runs everything in that code block. It tries to do self.name = name but we didn't give any argument so it gives an error. So if we do:<jupyter_code>player1 = PlayerCharacter('Cindy')<jupyter_output><empty_output><jupyter_text>'self' in above code refers to PlayerCharacter that we are going to create i.e. player1. So when we print the following we get:<jupyter_code>print(player1.name)<jupyter_output>Cindy<jupyter_text>We get Cindy because we gave it as the parameter to PlayerCharacter and when we instantiate it we pass the 'name' parameter. The default parameter is self and then we gave name to 'self.name'. In order to player have name we need to do 'self.' because self refers to player1.If we create another player and run it we use same piece of code but we get different values as we use different attributes:<jupyter_code>player2 = PlayerCharacter('Tom')
print(player2.name)<jupyter_output>Tom<jupyter_text>We can have multiple things in the class like age. Will add self.age in the above class definition.<jupyter_code>class PlayerCharacter:   #Another rule is to have the name singular
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
    def run(self):
        print('run')
player1 = PlayerCharacter('Cindy', 22)
player2 = PlayerCharacter('Tom', 31)
print(player1.age)
print(player2.age)
print(player1.run())<jupyter_output>run
None<jupyter_text>We get **None** because the function isn't returning anything in the function run(). If we add:def run(self):        print('run')        return('done')        Then it will return:rundone<jupyter_code>print(player1)
print(player2)<jupyter_output><__main__.PlayerCharacter object at 0x7fa98fbca340>
<__main__.PlayerCharacter object at 0x7fa98fbca3a0>
{'fraction_non_alphanumeric': 0.07984462667242123, 'fraction_numerical': 0.014242555028053518, 'mean_word_length': 4.780548628428928, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '507700', 'license': 'MIT', 'n_tokens_mistral': 699, 'n_tokens_neox': 672, 'n_words': 256, 'path': 'Python Notes/Creating Our Own Objects.ipynb', 'repo_name': 'ankitluthra/Python-Jupyter-Notebook', 'size': '2317'}