Giter Site home page Giter Site logo

phase-3-ruby-oo-class-variables-and-class-methods-lab's Introduction

Class Variables And Class Methods Lab

Learning Goals

  • Use class variables to keep track of data pertaining to a class
  • Define class methods to expose data pertaining to a class

Introduction

In this lab, we'll be dealing with a Song class. The Song class can produce individual songs. Each song has a name, an artist and a genre. We need our Song class to be able to keep track of the number of songs that it creates.

Song.count
# => 30

We need our Song class to be able to show us all of the artists of existing songs:

Song.artists
# => ["Jay-Z", "Drake", "Beyonce"]

We need our Song class to be able to show us all of the genres of existing songs:

Song.genres
# => ["Rap", "Pop"]

We also need our Song class to be able to keep track of the number of songs of each genre it creates.

In other words, calling:

Song.genre_count

Should return something like this;

{"rap" => 5, "rock" => 1, "country" => 3}

Lastly, we want our Song class to reveal to us the number of songs each artist is responsible for.

Song.artist_count
# => {"Beyonce" => 17, "Jay-Z" => 40}

We'll accomplish this with the use of class variables and class methods.

Instructions

Define your Song class such that an individual song is initialized with a name, artist and genre.

There should be an attr_accessor for those three attributes.

ninety_nine_problems = Song.new("99 Problems", "Jay-Z", "rap")

ninety_nine_problems.name
# => "99 Problems"

ninety_nine_problems.artist
# => "Jay-Z"

ninety_nine_problems.genre
# => "rap"

Create a class variable, @@count. We will use this variable to keep track of the number of new songs that are created from the Song class. Set this variable equal to 0.

At what point should we increment our @@count of songs? Whenever a new song is created. Your #initialize method should use the @@count variable and increment the value of that variable by 1.

Next, define the following class methods:

Song.count: returns the total number of songs created.

Song.genres: returns an array of all of the genres of existing songs. This array should contain only unique genres — no duplicates! Think about what you'll need to do to get this method working:

  • You'll need a class variable, let's call it @@genres, that is equal to an empty array.
  • When should you add genres to the array? Whenever a new song is created. Your #initialize method should add the genre of the song being created to the @@genres array. All genres should be added to the array. Control for duplicates when you code your .genres class method, not when you add genres to the original @@genres array. We will want to know how many songs of each genre have been created. We'll revisit that job a little later on.

Song.artists: returns an array of all of the artists of the existing songs. This array should only contain unique artists––no repeats! Once again think about what you need to do to implement this behavior.

  • You'll need a class variable, let's call it @@artists, that is equal to an empty array.
  • When should you add artists to this array? Whenever a new song is initialized. Your #initialize method should add artists to the @@artists array. All artists should be added to the array. Control for duplicates when you code your .artists class method, not when you add artists to the original @@artists array. We will want to know how many songs each have been assigned to each artist. We'll revisit that job a little later on when we write our .artist_count method.

Song.genre_count: returns a hash in which the keys are the names of each genre. Each genre name key should point to a value that is the number of songs that have that genre.

Song.genre_count
  # => {"rap" => 5, "rock" => 1, "country" => 3}

This manner of displaying numerical data is called a histogram. How will you create your histogram? There are a few ways!

  • You can need to iterate over the @@genres array and populate a hash with the key/value pairs. You will need to check to see if the hash already contains a key of a particular genre. If so, increment the value of that key by one, otherwise, create a new key/value pair.
  • You can also look into the #tally method.

Song.artist_count: returns a histogram similar to the one above, but for artists rather than genres.

Resources

phase-3-ruby-oo-class-variables-and-class-methods-lab's People

Contributors

alexgriff avatar annjohn avatar aviflombaum avatar beingy avatar dakotalmartinez avatar deniznida avatar franknowinski avatar ghostofvermeer avatar ihollander avatar jeffkatzy avatar jmburges avatar johnsont426 avatar lizbur10 avatar maxwellbenton avatar msuzoagu avatar sophiedebenedetto avatar tothutra avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

phase-3-ruby-oo-class-variables-and-class-methods-lab's Issues

RSpec tests for array uniqueness should not fail on account of out of order (and give example for @@genres/@@artists)

Canvas Link

https://learning.flatironschool.com/courses/5187/assignments/180214?module_item_id=397942

Concern

A) tests like this for artists and genres:
"is a class method that returns a unique array of genres of existing songs"

do not specify that elements should appear in a certain order
yet the tests emit failure if expect ['a', 'b'] doesn't match ['b', 'a']

B) Please elaborate on language like this:
All genres should be added to the array.

It feels wrong to create arrays like this: ['rap', 'rap', 'pop', 'rap']
when statements like
@@genre_ct[genre.to_sym] += 1
make it simple to take in new Songs and update the histogram at the same time, i.e.
to fulfill "All genres should be added to the array."

Specifically warn that rspec will fail if 'genres/artists' do not contain duplicates.
And/or, as happens for:

Song.genre_count
# => {"rap" => 5, "rock" => 1, "country" => 3}

spell it out with an example:

Song.genres
# => ['rap', 'rap', 'pop', 'rap']

PS: I did it my way (the way the text advises against), accumulating the stats with each new entry.
And then I did it so I could pass the opinionated tests. ("Opinionated" in the good sense.)
Wow: initializing with "@@genres << genre" and then "def self.genre_count @@genres.tally; end" and "def self.genres @@genres.uniq; end" was noticeably less code/complexity than what I wrote (premature optimization?):
@@genre_ct = Hash.new(0)
def initialize(...)
@@genre_ct[genre.to_sym] += 1
@@genres = chg_hash_keys_to_sym(@@genre_ct)
end
private
def chg_hash_keys_to_sym (a_hash)
a_hash.keys.map{|k| k.to_s}
end

So, please coax me into doing the "['rap', 'rap', 'pop', 'rap']" way by giving the explicit 'Song.genres' example, or some kind of sweetening statement. The current wording of:
All genres should be added to the array. Control for duplicates when you code your .genres class method, not when you add genres to the original @@genres array.

was not clear/persuasive/intuitive for me.
It wasn't a bad exercise for me to do both ways - it was good learning to step through a Ruby way of keeping counts via hash. But the value is in the "wow, less complexity" part, and I wish the text could have given me faith that such a surprise was in store.

Additional Context

No response

Suggested Changes

tests like this (both of them):
expect(Song.genres).to match(["rap", "pop"])

should be normalized with 'sort' method:
expect(Song.genres.sort).to match(["rap", "pop"].sort)

-and-

be explicit about requirement for duplication with an example:

Song.genres
# => ['rap', 'rap', 'pop', 'rap']

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.