Files
python/exercises/concept/ellens-alien-game/classes_test.py
PaulT89 de26301b66 [Classes Concept & Ellens Alien Game]: Updates (#2941)
* New concept exercise: ellens-alien-game

Introduces the concept of classes.
Message-Id: <20220126095726.46310-2-keeperotphones+patch@gmail.com>

* Update config.json

Message-Id: <71aad1e9fc012ef13fa5c02ceb4e3ec349715d85.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <bc2601f32a9d9247ac2f767d1f4267f340a22ec6.1643195691.git.keeperotphones+patch@gmail.com>

* Delete introduction-draft.md

Message-Id: <d11b031b5ef068658b9e2b1efa882a75c2ba70c5.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <f61ad700909f434f38fb55076ab4dc4d9258a6ab.1643195691.git.keeperotphones+patch@gmail.com>

* Create introduction

Message-Id: <938209240cdbc86bbddc5c33403659a290ec55ac.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <ca99353a7426f0bea05df556cc19752edf48ffce.1643195691.git.keeperotphones+patch@gmail.com>

* Rename introduction to introduction.md

Message-Id: <4373a3b66fac460701b429d22c76cd33d8b7db4a.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <c675ca900a18a3ad9f8a6b48cdad1157ea312321.1643195691.git.keeperotphones+patch@gmail.com>

* Update and rename design-draft.md to design.md

Message-Id: <c863549b1a61dc045162be8d6d42ae9a505cddd1.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <71b06afa96db6e5b6dde815560a5776bc8368e8f.1643195691.git.keeperotphones+patch@gmail.com>

* Fixed typo in instructions.md

Message-Id: <21826fc58f9cfa53d61e6e3ccf5fcc30e6d9e411.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <88a24ed3e8685ba96fdf26bb4c0629131272281f.1643195691.git.keeperotphones+patch@gmail.com>

* Formatting with YAPF

Confirmed with pylint and flake8.

Co-authored-by: BethanyG <BethanyG@users.noreply.github.com>
Message-Id: <ec52cd798d671348f5b29c0a691155d072c023af.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <58b93bb2ed0919c3e5753e25228bcc175a24edfa.1643195691.git.keeperotphones+patch@gmail.com>

* Update config.json

Co-authored-by: BethanyG <BethanyG@users.noreply.github.com>
Message-Id: <467259ba695c8005f7106d1f359b1d4fe6c14562.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <29a418465a89c10dfd711475da4236932c4e8eff.1643195691.git.keeperotphones+patch@gmail.com>

* Update exercises/concept/ellens-alien-game/.meta/config.json

We'll need to rename the files though

Co-authored-by: BethanyG <BethanyG@users.noreply.github.com>
Message-Id: <933195ff036507b273b55633b40a7b76cc27f130.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <529e34d1258c17b00e20278430682cd237cae6a7.1643195691.git.keeperotphones+patch@gmail.com>

* Improve wording and formatting for code formatting

Co-authored-by: BethanyG <BethanyG@users.noreply.github.com>
Message-Id: <cf9cfa5b19e0a51a1b47f11abc6d4bfdef9c7b64.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <5fd8622d5e4147746a85f3f1e63a2d5d64a066b4.1643195691.git.keeperotphones+patch@gmail.com>

* Using comprehension for our list of aliens

Comprehensions were introduced earlier in the concept, and so we use
them here.

Co-authored-by: BethanyG <BethanyG@users.noreply.github.com>
Message-Id: <1c8e73efaddfe077fe446aed6989da14398b53c6.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <e49ae05922f3dab213853e10ccad7654a4b44e7c.1643195691.git.keeperotphones+patch@gmail.com>

* Rename alien_class_test.py to classes_test.py

Message-Id: <493ff778d4422e418d1990f96d10c0d41c4f59ed.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <ff33af10e4617a92fcb343ead33a4060b4c7d6ad.1643195691.git.keeperotphones+patch@gmail.com>

* Rename alien_class.py to classes.py

Message-Id: <394f35b706b695c4e89ed55c9ee5a440701a78b0.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <52bca7f28924b4006ec1deca1e6bfa45f4f922de.1643195691.git.keeperotphones+patch@gmail.com>

* Added pytest decorators to classes.py

Message-Id: <8b14cd3955060ba75203fd17f088876af23c403d.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <68f7980c8bc3a8a17bef575aa20b9cfb33af1a60.1643195691.git.keeperotphones+patch@gmail.com>

* Filled design.md with content

Message-Id: <c785ab3f2ef18847df4b787710f8d49789acb2ff.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <d9fed4beb51fa8cdfd6f998bae46efa1cef878b5.1643195691.git.keeperotphones+patch@gmail.com>

* Added missing pytest decorator

Message-Id: <e175774a005235c5fe4629efffc1c49b44d4898f.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <85d06e4f2024883c120931fec152cc197a74dbc4.1643195691.git.keeperotphones+patch@gmail.com>

* Update instructions.md

Message-Id: <4a6c7e47a87398e50d6b864ecafe879d13c522d7.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <adea0f3324e0d5aee0a0ddfb4dc4a001baeff404.1643195691.git.keeperotphones+patch@gmail.com>

* Update design.md

Message-Id: <e90afd667cb2428c6d86c95a0b692aa3b97c7ce4.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <c8d2ec180d0979d65eb7760495022f58d027b6f1.1643195691.git.keeperotphones+patch@gmail.com>

* Update classes.py

Message-Id: <1dc38f5ebfcfe86df926b98b465465e540670528.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <30be55cc209a83e431f2cb7d735830ad2ea3e40e.1643195691.git.keeperotphones+patch@gmail.com>

* Update hints.md

Message-Id: <6ed9657bfa2d166f445f9825b9ccf117d5d6a4b1.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <e935f4bafa27d6da7ea3c1c7827c7f7b55155881.1643195691.git.keeperotphones+patch@gmail.com>

* remove trailing whitespace

Message-Id: <9e59aa73585b1f50a27dda59d7960c9f89f54dd8.1643189851.git.keeperotphones+patch@gmail.com>
Message-Id: <b1e7081ca1bed4d9c159e20b42c9e9ada3848923.1643195691.git.keeperotphones+patch@gmail.com>

* Update exercises/concept/ellens-alien-game/.docs/instructions.md

Moved back-quotes and added smiley to line 45.  Added additional instruction to line 46.

Co-authored-by: BethanyG <BethanyG@users.noreply.github.com>

* Update exercises/concept/ellens-alien-game/.docs/instructions.md

Added back-quotes around `class` and `method`.  Specified decrement amount.

Co-authored-by: BethanyG <BethanyG@users.noreply.github.com>

* Update exercises/concept/ellens-alien-game/.docs/instructions.md

Corrected 'function' to 'method' and put back-quotes around it.  Single-letter-variables changed to word-variables.  Instances of 'position' -> 'coordinate' to maintain consistency with new word-variables.

Co-authored-by: BethanyG <BethanyG@users.noreply.github.com>

* Update exercises/concept/ellens-alien-game/.docs/instructions.md

Added back-quotes (for consistency).  Clarified task instruction.

Co-authored-by: BethanyG <BethanyG@users.noreply.github.com>

* Update exercises/concept/ellens-alien-game/.docs/instructions.md

Single-letter-variable -> word-variable (style conformity + consistency)

Co-authored-by: BethanyG <BethanyG@users.noreply.github.com>

* Update exercises/concept/ellens-alien-game/.meta/exemplar.py

Single-letter-variable -> word-variable (style conformity + consistency)

Co-authored-by: BethanyG <BethanyG@users.noreply.github.com>

* Update instructions.md

All instances of:
- coordinate_x -> x_coordinate.
- coordinate_y -> y_coordinate

* Update exemplar.py

Implemented x_coordinate and y_coordinate instance variables (and variants thereof - see teleport method) to conform with both expected style (i.e. no single-letter-variables) and the changes made to instructions.md.

* Update exercises/concept/ellens-alien-game/.docs/instructions.md

Made the instructions in the first task more explicit.

Co-authored-by: BethanyG <BethanyG@users.noreply.github.com>

* design.md: Removed `properties` from Concepts

* Code Files Cleanup

*  Added docstring to exemplar.py Alien class
*  Corrected tests in classes_test.py
*  Changed new_alien_list to new_aliens_collection

* Edited Instructions to Match Exemplar

* Merge branch 'main' of github.com:PaulT89/python

Co-Authored-By: BethanyG <BethanyG@users.noreply.github.com>

* Added contents to intro

Co-Authored-By: BethanyG <BethanyG@users.noreply.github.com>

* Added content to about

Co-Authored-By: BethanyG <BethanyG@users.noreply.github.com>

* Add content to concept intro

Co-Authored-By: BethanyG <BethanyG@users.noreply.github.com>

* Added two links + descriptions

Co-Authored-By: BethanyG <BethanyG@users.noreply.github.com>

* Update config.json

* Added blurb to config.json

* Apply suggestions from code review

Fixed a few typos and added missing code block in introduction.

* Added additional resources to links.json

* Added Python Morsels and Dan Bader
* Added links on static vs class methods
* Added link on history of New Style classes in python.

* Added links + fixed typos

Added link to:
- Official Python Classes tutorial page
- The DO tutorial article already linked in the exercise introduction (and as a resource in design.md)
- A subsequent DO tutorial article focusing specifically on class and instance variables

* Fixed typos

* General Cleaning

Reworded clumsy sentences, deleted whitespace, fixed typos, removed some back-quotes to improve consistency with other documentation.

* Fixed typos + removed whitespace

* Corrections, Nits, and Picks

* Adding IsaacG as contributor

* Added IsaacG as contributor

Co-authored-by: BethanyG <BethanyG@users.noreply.github.com>
Co-authored-by: KOTP <keeperotphones+patch@gmail.com>
2022-02-18 04:42:50 -08:00

145 lines
5.8 KiB
Python

import unittest
import pytest
from classes import new_aliens_collection
try:
from classes import Alien
except ImportError as err:
raise ImportError("We tried to import the 'Alien' class, but could not find it. "
"Did you remember to create it?") from err
class ClassesTest(unittest.TestCase):
# Test Alien class exists and correctly initialised.
@pytest.mark.task(taskno=1)
def test_alien_has_correct_initial_coordinates(self):
alien = Alien(2, -1)
error = ("Expected object to be at position (2, -1) but instead "
f"found it initialized to position {(alien.x_coordinate, alien.y_coordinate)}.")
self.assertEqual((2, -1), (alien.x_coordinate, alien.y_coordinate), msg=error)
@pytest.mark.task(taskno=1)
def test_alien_has_health(self):
alien = Alien(0, 0)
error = ("Expected object's health to be 3 but instead found "
f"it had a health of {alien.health}.")
self.assertEqual(3, alien.health, msg=error)
# Test instance variables are unique to specific instances.
@pytest.mark.task(taskno=1)
def test_alien_instance_variables(self):
alien_one = Alien(-8, -1)
alien_two = Alien(2, 5)
coord_x_error = ("Expected alien_one and alien_two to have different x "
f"positions. Instead both x's were: {alien_two.x_coordinate}.")
coord_y_error = ("Expected alien_one and alien_two to have different y "
f"positions. Instead both y's were: {alien_two.y_coordinate}.")
self.assertFalse(alien_one.x_coordinate == alien_two.x_coordinate, msg=coord_x_error)
self.assertFalse(alien_one.y_coordinate == alien_two.y_coordinate, msg=coord_y_error)
# Test class methods work as specified.
@pytest.mark.task(taskno=2)
def test_alien_hit_method(self):
data = [(1, 2), (2, 1), (3, 0), (4, -1)]
for variant, (iterations, result) in enumerate(data, 1):
alien = Alien(2, 2)
with self.subTest(f'variation #{variant}', input=iterations, output=result):
error = ("Expected hit method to decrement health by 1. "
f"Health is {alien.health} when it should be {result}.")
for _ in range(iterations):
alien.hit()
self.assertEqual(alien.health, result, msg=error)
@pytest.mark.task(taskno=3)
def test_alien_is_alive_method(self):
alien = Alien(0, 1)
alive_error = "Alien is dead while health is greater than 0."
dead_error = "Alien is alive while health is less than or equal to 0."
for _ in range(5):
alien.hit()
if alien.health > 0:
self.assertTrue(alien.is_alive(), msg=alive_error)
else:
self.assertFalse(alien.is_alive(), msg=dead_error)
@pytest.mark.task(taskno=4)
def test_alien_teleport_method(self):
alien = Alien(0, 0)
alien.teleport(-1, -4)
error = (
"Expected alien to be at position (-1, -4) but "
f"instead found it in position {(alien.x_coordinate, alien.y_coordinate)}.")
self.assertEqual((-1, -4), (alien.x_coordinate, alien.y_coordinate), msg=error)
@pytest.mark.task(taskno=5)
def test_alien_collision_detection_method(self):
alien = Alien(7, 3)
error = "Expected collision_detection method to not be implemented."
self.assertIsNone(alien.collision_detection(Alien(7, 2)), msg=error)
# Test class variables are identical across instances
@pytest.mark.task(taskno=6)
def test_alien_class_variable(self):
alien_one = Alien(0, 2)
alien_two = Alien(-6, -1)
Alien.total_aliens_created = -2
error_one = "Expected the total_aliens_created variable to be identical."
error_two = "Expected the health variable to be identical."
self.assertEqual(alien_two.total_aliens_created, alien_one.total_aliens_created, msg=error_one)
self.assertEqual(alien_two.health, alien_one.health, msg=error_two)
# Test total_aliens_created increments upon object instantiation
@pytest.mark.task(taskno=6)
def test_alien_total_aliens_created(self):
Alien.total_aliens_created = 0
aliens = [Alien(-2, 6)]
error = ("Expected total_aliens_created to equal 1. Instead "
f"it equals: {aliens[0].total_aliens_created}.")
self.assertEqual(1, aliens[0].total_aliens_created, msg=error)
aliens.append(Alien(3, 5))
aliens.append(Alien(-5, -5))
def error_text(alien, variable):
return (
"Expected all total_aliens_created variables to be "
"equal to number of alien instances (i.e. 3). Alien "
f"number {alien}'s total_aliens_created variable "
f"is equal to {variable}.")
tac_list = [alien.total_aliens_created for alien in aliens]
self.assertEqual(3, tac_list[0], msg=error_text(1, tac_list[0]))
self.assertEqual(3, tac_list[1], msg=error_text(2, tac_list[1]))
self.assertEqual(3, tac_list[2], msg=error_text(3, tac_list[2]))
# Test that the user knows how to create objects themselves
@pytest.mark.task(taskno=7)
def test_new_aliens_collection(self):
position_data = [(-2, 6), (1, 5), (-4, -3)]
obj_list = new_aliens_collection(position_data)
obj_error = "new_alien_list must return a list of Alien objects."
for obj, position in zip(obj_list, position_data):
self.assertIsInstance(obj, Alien, msg=obj_error)
pos_error = (
f"Expected object to be at position {position} but "
f"instead found it initialized to position {(obj.x_coordinate, obj.y_coordinate)}.")
self.assertEqual(position, (obj.x_coordinate, obj.y_coordinate), msg=pos_error)