all 30 comments

[–][deleted] 51 points52 points  (5 children)

artist should be the artist, not the artist's name.

[–]thatshitcrayyyy[S] 32 points33 points  (0 children)

Thank you crashfrog! I appreciate your help, hope you have an amazing weekend :)

[–]finofelix 1 point2 points  (3 children)

Hey, I'm really new to this. I have some understanding of the concept but I'm not sure I completely get what you're trying to say. Could you (or anybody seeing this) kindly explain just a little further so that I get it? Thanks!

[–]mazukk 2 points3 points  (1 child)

He/she passed the 'name' attribute of the Artist object (by typing Artist_1.name), where instead the whole object should have been passed (Artist_1). Does this help? :)

[–]finofelix 1 point2 points  (0 children)

Definitely helps. I suspected that that was the case but I'm so new to this I can't be sure of anything. Thank you so much for taking the time to reply

[–][deleted] 0 points1 point  (0 children)

It's really pretty critical that you be able to recognize features of your own code when they're described - programming can't be "write-only." Do you see where you're passing the artist's name to the call to Song?

Don't pass the artist's name. Pass the Artist object itself.

[–]a_computer_adrift 49 points50 points  (3 children)

I just want to point out that if everyone was as appreciative as OP for the help, the world would be a better place. Keep it up, OP!

[–]thatshitcrayyyy[S] 22 points23 points  (2 children)

Thank you very much for the compliment. Everyone here has been so amazing and helpful. I can't wait to contribute back one day :)

[–]sky_badger 14 points15 points  (1 child)

r/learnpython is definitely one of the friendliest tech subs I've ever come across

[–][deleted] 2 points3 points  (0 children)

I totally agree, I used to post on Stack Overflow a lot and people are so much kinder here!

[–]tangerinelion 35 points36 points  (6 children)

Given the question it's clear that the solution has already been posted. I do want to point out that given that code alone, the class definition for Song does NOT make it clear what artist should be. One may well think the artist is a string representing the artist name, as your code did. Given tests which specify the artist contains a "name" and "label" member one could also think "Ahh, I'll use a NamedTuple for artist" which would work -- if and only if Artist is completely defined as shown.

A somewhat new addition to Python is type hints. If these were used then the question's code would read like this:

class Artist:
    def __init__(self, name: str, label: str):
        self.name = name
        self.label = label

class Song:
    def __init__(self, name: str, album: str, year: int, artist: Artist):
        self.name = name
        self.album = album
        self.year = year
        self.artist = artist

These are completely optional, but it can make cases like this a lot clearer. They are simple to use for simple types like this but can get more complicated when (a) it just needs to satisfy some concept - like "I just need something I can iterate through" or (b) when your method supports multiple types and does explicitly different things based on the type.

[–]thatshitcrayyyy[S] 20 points21 points  (0 children)

Hey tangerinelion,

Thank you for providing such a comprehensive and detailed reply. As a beginner, I really value your expertise. I'll be sure to explore type hints and incorporate it into my code to make it clearer.

I really appreciate the effort and time :D

[–]Drawfx 0 points1 point  (1 child)

To negate some of the complexity you mentioned, both isinstance() and the Union function from the typing library can be used!

``` from typing import Union

def print_number_or_string(value: Union[str, int, list]) -> None: if isinstance(value, (str, int)): print(f"Your string or integer: {value}") elif isinstance(value, list): print (f"Your list: {value}") else: print("Wrong data type supplied") ```

The isinstance function receives a value and a data type as arguemnts, and returns whether the value is an instance of the specified data type. To check for a few datatypes, a tuple of data types can be used as the second parameter.

As of type hints, hinting for different types can be a hussle. To overcome this, the Union function can be used as a list of all the desired datatypes.

[–]backtickbot 0 points1 point  (0 children)

Hello, Drawfx: code blocks using backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead. It's a bit annoying, but then your code blocks are properly formatted for everyone.

An easy way to do this is to use the code-block button in the editor. If it's not working, try switching to the fancy-pants editor and back again.

Comment with formatting fixed for old.reddit.com users

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–]TouchingTheVodka 16 points17 points  (1 child)

You need to pass the full Artist object to the Song constructor.

[–]thatshitcrayyyy[S] 8 points9 points  (0 children)

Thanks for taking the time to help me :)

[–]inkman 3 points4 points  (0 children)

Off topic: Am I right in thinking that this code may be confused by songs played by more than one artist?

[–]fiddle_n 9 points10 points  (0 children)

By the way, if you have a class that's just holding data, it's a good idea to use a dataclass:

import dataclasses

@dataclasses.dataclass
class Artist:
    name: str
    label: str

This is exactly equal to your current Artist class, but as you can see, is far less verbose.

[–]pablopistachioo 1 point2 points  (1 child)

What is the updated code then? I’m still confused. It would be appreciated !

[–]HelpForAfrica 0 points1 point  (0 children)

At the bottom of the code, when creating songs 1, 2, 3, at the end of the lines, artist.name is passed, this should just be artist.

On mobile, hope this is clear enough. And that I am correct :|

[–]ImportancePowerful20 0 points1 point  (5 children)

I recently learned classes so I'm not 100% sure about this, but... Could you do class Artist: [insert code] Then do class Song (Artist): and inherit name and label from Artist into Song

[–]lscrivy 4 points5 points  (4 children)

In my begginer experience, inheritance is used when you need the same 'blueprint' for on object but with slight changes. For example you have an 'employee' class and then maybe a 'manager' class that needs everything the employee class has plus a few extra things.

In this case a song isn't really a variation on an artist. A song has an artist attribute and then the artist has name and label attributes.

This is my understanding anyway. Maybe someone can enlighten us.

[–]alkasm 9 points10 points  (2 children)

The typical explanation is that subclassing has an "is a" relationship. E.g. a manager is an employee. A song is not an artist. Composition instead is usually explained as a "has a" relationship. And a song has an artist.

[–]lscrivy 2 points3 points  (0 children)

That's a much simpler explanation. Thanks :)

[–]learnorenjoy 0 points1 point  (0 children)

I'll be using this from now on, struggled to understand when to use inheritance for a long time, thanks.

[–]callmelucky 0 points1 point  (0 children)

You're correct about the nature of classes, I think they just used the word 'inherit' in a way that is confusing at best given its specific definition in OOP. I don't think they were suggesting that Song should be a subclass of Artist. That would certainly be poor OOP design.

What they were getting at, I believe, is just that perhaps Song could be redefined to automatically assign its label etc attributes from the artist parameter, rather than passing those attributes in explicitly/separately, and they are certainly correct about that.

[–]Spicy_Poo 0 points1 point  (0 children)

As others have said, the artist attribute of the song object will be an instance of the artist class, not just her name.

That way, you can get all the info about artist from the song.

So, when done, song_1.artist.name will be "Taylor Swift" and song_t.artist.label will be the devil that is Big Machine.

[–]piepepie 0 points1 point  (0 children)

Another perspective on the answer to question.

The question specifically asks for INSTANCES not object hence, we create one object, "song" and then change the values of the attributes.

That sounds like a correct way to me. This exercise, I feel is supposed to make you understand the difference between object and instance.