Skip to content

Commit

Permalink
Fix part of oppia#4374: Add docstrings to the Python files. (oppia#6041)
Browse files Browse the repository at this point in the history
* Add docstrings.

* Made requested changes.

* Modify docstring.

* Made review changes.
  • Loading branch information
vibhor98 authored Jan 4, 2019
1 parent 52a859f commit d2a7fc3
Show file tree
Hide file tree
Showing 13 changed files with 130 additions and 0 deletions.
18 changes: 18 additions & 0 deletions core/controllers/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,15 @@ def post(self):
raise

def _reload_exploration(self, exploration_id):
"""Reloads the exploration in dev_mode corresponding to the given
exploration id.
Args:
exploration_id: str. The exploration id.
Raises:
Exception: Cannot reload an exploration in production.
"""
if constants.DEV_MODE:
logging.info(
'[ADMIN] %s reloaded exploration %s' %
Expand All @@ -213,6 +222,15 @@ def _reload_exploration(self, exploration_id):
raise Exception('Cannot reload an exploration in production.')

def _reload_collection(self, collection_id):
"""Reloads the collection in dev_mode corresponding to the given
collection id.
Args:
collection_id: str. The collection id.
Raises:
Exception: Cannot reload a collection in production.
"""
if constants.DEV_MODE:
logging.info(
'[ADMIN] %s reloaded collection %s' %
Expand Down
9 changes: 9 additions & 0 deletions core/controllers/base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,14 +350,21 @@ def test_logout_page(self):


class I18nDictsTests(test_utils.GenericTestBase):
"""Tests for I18n dicts."""

def _extract_keys_from_json_file(self, filename):
"""Returns the extracted keys from the json file corresponding to the
given filename.
"""
return sorted(json.loads(utils.get_file_contents(
os.path.join(os.getcwd(), self.get_static_asset_filepath(),
'assets', 'i18n', filename)
)).keys())

def _extract_keys_from_html_file(self, filename):
"""Returns the extracted keys from the html file corresponding to the
given filename.
"""
# The \b is added at the start to ensure that keys ending with
# '_I18N_IDS' do not get matched. Instances of such keys can be found
# in learner_dashboard.html.
Expand Down Expand Up @@ -527,9 +534,11 @@ def test_html_in_translations_is_preserved_correctly(self):
class GetHandlerTypeIfExceptionRaisedTests(test_utils.GenericTestBase):

class FakeHandler(base.BaseHandler):
"""A fake handler class."""
GET_HANDLER_ERROR_RETURN_TYPE = feconf.HANDLER_TYPE_JSON

def get(self):
"""Handles get requests."""
raise self.InternalErrorException('fake exception')

def test_error_response_for_get_request_of_type_json_has_json_format(self):
Expand Down
17 changes: 17 additions & 0 deletions core/controllers/creator_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,29 @@ def get(self):
"""Handles GET requests."""

def _get_intro_card_color(category):
"""Returns the intro card color according to the category.
Args:
category: str. The category of the lesson.
Returns:
str. The intro card color according to the category.
"""
return (
constants.CATEGORIES_TO_COLORS[category] if
category in constants.CATEGORIES_TO_COLORS else
constants.DEFAULT_COLOR)

def _round_average_ratings(rating):
"""Returns the rounded average rating to display on the creator
dashboard.
Args:
rating: float. The rating of the lesson.
Returns:
float. The rounded average value of rating.
"""
return round(rating, feconf.AVERAGE_RATINGS_DASHBOARD_PRECISION)

# We need to do the filtering because some activities that were
Expand Down
1 change: 1 addition & 0 deletions core/controllers/creator_dashboard_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ def _rate_exploration(self, exp_id, ratings):
self.process_and_flush_pending_tasks()

def _run_user_stats_aggregator_job(self):
"""Runs the User Stats Aggregator job."""
MockUserStatsAggregator.start_computation()
self.assertEqual(
self.count_jobs_in_taskqueue(
Expand Down
6 changes: 6 additions & 0 deletions core/controllers/editor_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ def test_add_new_state_error_cases(self):
csrf_token = self.get_csrf_token_from_response(response)

def _get_payload(new_state_name, version=None):
"""Gets the payload in the dict format."""
result = {
'change_list': [{
'cmd': 'add_state',
Expand All @@ -213,6 +214,9 @@ def _get_payload(new_state_name, version=None):
return result

def _put_and_expect_400_error(payload):
"""Puts a request with no version number and hence, expects 400
error.
"""
return self.put_json(
'/createhandler/data/0', payload,
csrf_token=csrf_token, expect_errors=True,
Expand Down Expand Up @@ -1794,6 +1798,7 @@ class EditorAutosaveTest(BaseEditorControllerTests):
'new_value': 1}]

def _create_explorations_for_tests(self):
"""Creates the mock explorations for testing."""
self.save_new_valid_exploration(self.EXP_ID1, self.owner_id)
exploration = exp_services.get_exploration_by_id(self.EXP_ID1)
exploration.add_states(['State A'])
Expand All @@ -1802,6 +1807,7 @@ def _create_explorations_for_tests(self):
self.save_new_valid_exploration(self.EXP_ID3, self.owner_id)

def _create_exp_user_data_model_objects_for_tests(self):
"""Creates the ExplorationUserDataModel objects for testing."""
# Explorations with draft set.
user_models.ExplorationUserDataModel(
id='%s.%s' % (self.owner_id, self.EXP_ID1), user_id=self.owner_id,
Expand Down
6 changes: 6 additions & 0 deletions core/controllers/feedback_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,9 @@ def setUp(self):
rights_manager.publish_exploration(self.owner_2, self.EXP_ID)

def _get_messages_read_by_user(self, user_id, thread_id):
"""Gets the ids of messages in the thread read by the user corresponding
to the given user id.
"""
feedback_thread_user_model = (
feedback_models.GeneralFeedbackThreadUserModel.get(
user_id, thread_id))
Expand All @@ -403,6 +406,9 @@ def _get_messages_read_by_user(self, user_id, thread_id):
if feedback_thread_user_model else [])

def _get_message_ids_in_a_thread(self, thread_id):
"""Gets the ids of messages in the thread corresponding to the given
thread id.
"""
messages = feedback_services.get_messages(thread_id)

return [message.message_id for message in messages]
Expand Down
10 changes: 10 additions & 0 deletions core/controllers/reader_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,12 +490,14 @@ def setUp(self):
self.logout()

def _get_exploration_ids_from_summaries(self, summaries):
"""Returns the sorted list of all the exploration ids from summaries."""
return sorted([summary['id'] for summary in summaries])

def _get_recommendation_ids(
self, exploration_id, collection_id=None,
include_system_recommendations=None,
author_recommended_ids_str='[]'):
"""Gets the recommended exploration ids from the summaries."""
collection_id_param = (
'&collection_id=%s' % collection_id
if collection_id is not None else '')
Expand Down Expand Up @@ -523,13 +525,21 @@ def _get_recommendation_ids(
# desirable.

def _set_recommendations(self, exp_id, recommended_ids):
"""Sets the recommendations in the exploration corresponding to the
given exploration id.
"""
recommendations_services.set_recommendations(exp_id, recommended_ids)

def _complete_exploration_in_collection(self, exp_id):
"""Completes the exploration within the collection. Records that the
exploration has been played by the user in the context of the
collection.
"""
collection_services.record_played_exploration_in_collection_context(
self.new_user_id, self.COL_ID, exp_id)

def _complete_entire_collection_in_order(self):
"""Completes the entire collection in order."""
self._complete_exploration_in_collection(self.EXP_ID_19)
self._complete_exploration_in_collection(self.EXP_ID_20)
self._complete_exploration_in_collection(self.EXP_ID_21)
Expand Down
1 change: 1 addition & 0 deletions core/controllers/resources_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class AssetDevHandlerImageTests(test_utils.GenericTestBase):
ASSET_HANDLER_URL_PREFIX = '/assetsdevhandler'

def _get_image_url(self, exp_id, filename):
"""Gets the image URL."""
return str(
'%s/%s/assets/image/%s' %
(self.ASSET_HANDLER_URL_PREFIX, exp_id, filename))
Expand Down
7 changes: 7 additions & 0 deletions core/controllers/skill_editor_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def setUp(self):
[], [], [self.skill_id], [], 1)

def _get_csrf_token_for_put(self):
"""Gets the csrf token."""
csrf_token = None
url_prefix = feconf.SKILL_EDITOR_URL_PREFIX
with self.swap(constants, 'ENABLE_NEW_STRUCTURE_EDITORS', True):
Expand All @@ -58,6 +59,9 @@ def _get_csrf_token_for_put(self):
return csrf_token

def _delete_skill_model_and_memcache(self, user_id, skill_id):
"""Deletes skill model and memcache corresponding to the given skill
id.
"""
skill_model = skill_models.SkillModel.get(skill_id)
skill_model.delete(user_id, 'Delete skill model.')
skill_memcache_key = skill_services._get_skill_memcache_key(skill_id) # pylint: disable=protected-access
Expand All @@ -66,13 +70,16 @@ def _delete_skill_model_and_memcache(self, user_id, skill_id):
def _mock_update_skill_raise_exception(
self, unused_committer_id, unused_skill_id, unused_change_list,
unused_commit_message):
"""Mocks skill updates. Always fails by raising a validation error."""
raise utils.ValidationError()

def _mock_get_skill_rights(self, unused_skill_id, **unused_kwargs):
"""Mocks get_skill_rights. Returns None."""
return None

def _mock_publish_skill_raise_exception(
self, unused_skill_id, unused_committer_id):
"""Mocks publishing skills. Always fails by raising an exception."""
raise Exception()


Expand Down
1 change: 1 addition & 0 deletions core/controllers/topics_and_skills_dashboard_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def setUp(self):
[self.linked_skill_id], [], 1)

def _get_csrf_token_for_put(self):
"""Gets the csrf token."""
csrf_token = None
url_prefix = feconf.TOPICS_AND_SKILLS_DASHBOARD_URL
with self.swap(constants, 'ENABLE_NEW_STRUCTURE_EDITORS', True):
Expand Down
7 changes: 7 additions & 0 deletions core/domain/activity_services_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,21 @@ class ActivityServicesTests(test_utils.GenericTestBase):
COL_ID_2 = 'COL_ID_2'

def _create_exploration_reference(self, exploration_id):
"""Creates and returns the exploration reference corresponding to the
given exploration id.
"""
return activity_domain.ActivityReference(
constants.ACTIVITY_TYPE_EXPLORATION, exploration_id)

def _create_collection_reference(self, collection_id):
"""Creates and returns the collection reference corresponding to the
given collection id.
"""
return activity_domain.ActivityReference(
constants.ACTIVITY_TYPE_COLLECTION, collection_id)

def _compare_lists(self, reference_list_1, reference_list_2):
"""Compares the hashed values of the two given reference lists."""
hashes_1 = [reference.get_hash() for reference in reference_list_1]
hashes_2 = [reference.get_hash() for reference in reference_list_2]
self.assertEqual(hashes_1, hashes_2)
Expand Down
46 changes: 46 additions & 0 deletions core/platform/search/gae_search_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ def add_documents_to_index(documents, index, retries=DEFAULT_NUM_RETRIES):


def _dict_to_search_document(d):
"""Returns and converts the document dict into objects.
Args:
d: dict(str, str). A dict containing field names as keys and
corresponding field values as values.
Returns:
Document. The document containing fields.
Raises:
ValueError: The given document is not in the dict format.
"""
if not isinstance(d, dict):
raise ValueError('document should be a dictionary, got %s' % type(d))

Expand All @@ -118,6 +130,20 @@ def _dict_to_search_document(d):


def _make_fields(key, value):
"""Returns the fields corresponding to the key value pair according to the
type of value.
Args:
key: str. The name of the field.
value: *. The field value.
Returns:
list(*). A list of fields.
Raises:
ValueError: The type of field value is not list, basestring, Number or
datetime.
"""
if isinstance(value, list):
_validate_list(key, value)
return [_make_fields(key, v)[0] for v in value]
Expand Down Expand Up @@ -305,6 +331,18 @@ def search(query_string, index, cursor=None,


def _string_to_sort_expressions(input_string):
"""Returns the sorted expression of the input string.
Args:
input_string: str. The input string to be sorted.
Returns:
list(SortExpression). A list of sorted expressions.
Raises:
ValueError: Fields in the sort expression do not start with '+' or '-'
to indicate sort direction.
"""
sort_expressions = []
s_tokens = input_string.split()
for expression in s_tokens:
Expand Down Expand Up @@ -338,6 +376,14 @@ def get_document_from_index(doc_id, index):


def _search_document_to_dict(doc):
"""Converts and returns the search document into a dict format.
Args:
doc: Document. The document to be converted into dict format.
Returns:
dict(str, str). The document in dict format.
"""
d = {'id': doc.doc_id, 'language_code': doc.language, 'rank': doc.rank}

for field in doc.fields:
Expand Down
1 change: 1 addition & 0 deletions core/platform/users/gae_current_user_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def get_user_id_from_email(email):
Returns None if the email address does not correspond to a valid user id.
"""
class _FakeUser(ndb.Model):
"""A fake user class."""
_use_memcache = False
_use_cache = False
user = ndb.UserProperty(required=True)
Expand Down

0 comments on commit d2a7fc3

Please sign in to comment.