* 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>
145 lines
5.8 KiB
Python
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)
|