I mentioned in one of the recent threads that I started that it is probably time for me to attempt a substantial project using the OO paradigm. I have had no coursework or training in OOP other than my recent self-studies. Everything (Other than toy practice examples.) I have coded to date has been strictly procedural, similar to what I learned in FORTRAN ages ago. Also, I am continuing to try to do TDD and keep things DRY. So I am hoping for a thorough critique of what I will shortly present. Everything is fair game! Hopefully my self-esteem is up to this critique!
The intent of this project is more than just calculate chess ratings. I also envision being able to store a record of all game results and player information for my school chess players that I give lessons to. Some functionality I will strive to include: 1) Be able to re-rate all games from a given date to the present. 2) Record demographic information about my players, such as names, current school year, current grade, etc. 3) Have a very friendly GUI so that when I have a finished project, a student could easily take over responsibility of maintaining the school's player ratings, if I so choose to allow this. 4) Having an editor where games and player data (But NOT ratings; these would have to be re-rated starting from a corrected game(s).) can be edited, inserted, or deleted with games (If game data is edited.) automatically be re-rated. 5) Et cetera ... My current project structure is: /Projects /rating_calculator /rating_calculator __init__.py main.py /tests __init__.py test_main.py I have started my coding with a RatingCalculator class. The intent of this class is to gather all methods together needed to validate and calculate chess ratings. My intent is to only ever have a single instance of this class existing during a given running of the program. (BTW, is there a technique to _guarantee_ that this is always true?) I am only at the very beginning of coding this class. I have not added any methods yet. Currently I am adding class constants that will be used in this class' methods. These constants are for internal class use only and should not be altered from outside the class. Here is the current state of the main.py program (Which will probably be broken into multiple modules as the project develops.): ================================================================================= #!/usr/bin/env python3 """Module to process chess ratings.""" class RatingCalculator: """This class contains methods to validate and calculate chess ratings.""" # Overestimated extremes for possible chess rating values. Values outside # this range should not be achievable. _LOWEST_POSSIBLE_RATING = 0 _HIGHEST_POSSIBLE_RATING = 3000 # Fundamental constants for use in the chess rating formula. The keys to # these values are tuples giving the rating ranges for which these # K-factors are valid. _K_MULTIPLIERS = { (_LOWEST_POSSIBLE_RATING, 2099): 0.04, (2100, 2399): 0.03, (2400, _HIGHEST_POSSIBLE_RATING): 0.02} _K_ADDERS = { (_LOWEST_POSSIBLE_RATING, 2099): 16, (2100, 2399): 12, (2400, _HIGHEST_POSSIBLE_RATING): 8} ================================================================================= The test code in test_main.py is: ================================================================================= #!/usr/bin/env python3 """Module to test all functions and methods of main.py.""" import unittest import rating_calculator.main as main class TestRatingCalculatorConstants(unittest.TestCase): # Check that the constants in RatingCalculator have the proper values. def setUp(self): # Create instance of RatingCalculator for use in the following tests. # Create tuple of test-value pairs to interate over in subtests. self.rating_calculator = main.RatingCalculator() self.test_value_pairs = ( (self.rating_calculator._LOWEST_POSSIBLE_RATING, 0), (self.rating_calculator._HIGHEST_POSSIBLE_RATING, 3000), (self.rating_calculator._K_MULTIPLIERS[( self.rating_calculator._LOWEST_POSSIBLE_RATING, 2099)], 0.04), (self.rating_calculator._K_MULTIPLIERS[(2100, 2399)], 0.03), (self.rating_calculator._K_MULTIPLIERS[(2400, self.rating_calculator._HIGHEST_POSSIBLE_RATING)], 0.02), (self.rating_calculator._K_ADDERS[( self.rating_calculator._LOWEST_POSSIBLE_RATING, 2099)], 16), (self.rating_calculator._K_ADDERS[(2100, 2399)], 12), (self.rating_calculator._K_ADDERS[(2400, self.rating_calculator._HIGHEST_POSSIBLE_RATING)], 8)) def test_class_constants(self): # Check that all class constants have the correct values. for tested_item, expected_value in self.test_value_pairs: with self.subTest(): self.assertEqual(tested_item, expected_value) if __name__ == '__main__': unittest.main() ================================================================================= Instead of doc strings in the test code, I have used comments based on something I read online. The point of doing this was so the doc strings would _not_ show up in the test run output. Is this worthwhile advice to follow? I'm looking forwards to everyone's thoughts. TIA! -- boB _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor