Skip to content

Commit

Permalink
initialize class attributes and methods lab
Browse files Browse the repository at this point in the history
  • Loading branch information
professor-ben committed Jul 4, 2022
0 parents commit e909ad1
Show file tree
Hide file tree
Showing 7 changed files with 276 additions and 0 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/canvas-sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Sync with Canvas

on:
push:
branches: [master, main]
paths:
- "README.md"

jobs:
sync:
name: Sync with Canvas

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6

- name: Install github-to-canvas
run: gem install github-to-canvas

# Secret stored in learn-co-curriculum Settings/Secrets
- name: Sync from .canvas file
run: github-to-canvas -a -lr --forkable
env:
CANVAS_API_KEY: ${{ secrets.CANVAS_API_KEY }}
CANVAS_API_PATH: ${{ secrets.CANVAS_API_PATH }}
38 changes: 38 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Contributing to Learn.co Curriculum

We're really exited that you're about to contribute to the [open
curriculum](https://learn.co/content-license) on [Learn.co](https://learn.co).
If this is your first time contributing, please continue reading to learn how to
make the most meaningful and useful impact possible.

## Raising an Issue to Encourage a Contribution

If you notice a problem with the curriculum that you believe needs improvement
but you're unable to make the change yourself, you should raise a Github issue
containing a clear description of the problem. Include relevant snippets of the
content and/or screenshots if applicable. Curriculum owners regularly review
issue lists and your issue will be prioritized and addressed as appropriate.

## Submitting a Pull Request to Suggest an Improvement

If you see an opportunity for improvement and can make the change yourself go
ahead and use a typical git workflow to make it happen:

- Fork this curriculum repository
- Make the change on your fork, with descriptive commits in the standard format
- Open a Pull Request against this repo

A curriculum owner will review your change and approve or comment on it in due
course.

## Why Contribute?

Curriculum on Learn is publicly and freely available under Learn's
[Educational Content License](https://learn.co/content-license). By embracing an
open-source contribution model, our goal is for the curriculum on Learn to
become, in time, the best educational content the world has ever seen.

We need help from the community of Learners to maintain and improve the
educational content. Everything from fixing typos, to correcting out-dated
information, to improving exposition, to adding better examples, to fixing
tests—all contributions to making the curriculum more effective are welcome.
23 changes: 23 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Learn.co Educational Content License

Copyright (c) 2021 Flatiron School, Inc

The Flatiron School, Inc. owns this Educational Content. However, the Flatiron
School supports the development and availability of educational materials in the
public domain. Therefore, the Flatiron School grants Users of the Flatiron
Educational Content set forth in this repository certain rights to reuse, build
upon and share such Educational Content subject to the terms of the Educational
Content License set forth [here](http://learn.co/content-license)
(http://learn.co/content-license). You must read carefully the terms and
conditions contained in the Educational Content License as such terms govern
access to and use of the Educational Content.

Flatiron School is willing to allow you access to and use of the Educational
Content only on the condition that you accept all of the terms and conditions
contained in the Educational Content License set forth
[here](http://learn.co/content-license) (http://learn.co/content-license). By
accessing and/or using the Educational Content, you are agreeing to all of the
terms and conditions contained in the Educational Content License. If you do not
agree to any or all of the terms of the Educational Content License, you are
prohibited from accessing, reviewing or using in any way the Educational
Content.
175 changes: 175 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# Class Attributes and Methods Lab

## Learning Goals

- Use class attributes and methods to write durable and powerful code.
- Store and access song data using class attributes and methods.
- Accomplish complex programming tasks using knowledge from previous modules.

***

## Key Vocab

- **Attribute**: variables that belong to an object.
- **Constant**: variable whose value cannot be changed.
- **Instance**: one specific working copy of a class. It is created when a
class's `__init__` method is called.
- **Class**: a bundle of data and functionality. Can be copied and modified to
accomplish a wide variety of programming tasks.
- **Static**: an attribute or method that cannot manipulate the class or
instance it belongs to.
- **Exception**: an error that occurs during the execution of a program.
Exceptions can be anticipated and handled without disrupting the execution of
the program.

***

## 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.

```ruby
Song.count
# => 30
```

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

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

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

```ruby
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:

```ruby
Song.genre_count
```

Should return something like this;

```ruby
{"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.

```ruby
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.

```ruby
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.

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

This manner of displaying numerical data is called a
[histogram](https://en.wikipedia.org/wiki/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`][tally docs] method.

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

## Resources

- [`#tally`][tally docs]

[tally docs]: https://ruby-doc.org/core-2.7.0/Enumerable.html#method-i-tally


***

## Resources

- [Python Documentation](https://docs.python.org/3/)
- [Classes - Python](https://docs.python.org/3/)
- [Python Class Attributes: An Overly Thorough Guide - Toptal](https://www.toptal.com/python/python-class-attributes-an-overly-thorough-guide)
- [Python's Instance, Class, and Static Methods Demystified - Real Python](https://realpython.com/instance-class-and-static-methods-demystified/)
- [The Factory Method Pattern and Its Implementation in Python - Real Python](https://realpython.com/factory-method-python/)
Empty file added lib/__init__.py
Empty file.
Empty file added testing/__init__.py
Empty file.
9 changes: 9 additions & 0 deletions testing/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env python

def pytest_itemcollected(item):
par = item.parent.obj
node = item.obj
pref = par.__doc__.strip() if par.__doc__ else par.__class__.__name__
suf = node.__doc__.strip() if node.__doc__ else node.__name__
if pref or suf:
item._nodeid = ' '.join((pref, suf))

0 comments on commit e909ad1

Please sign in to comment.