Search code examples
pythonif-statementfor-looppyramid

Writing clean code: Nested For/If/Elif in Pyramid


Goal: Trying to print pending results (Assessment.name, e.g. 'Becoming a Leader', 'Something Else', etc...--print whatever a user has NOT completed in all_assessments) and completed results(assessment.name from Assessment_Results.assessment.name, e.g. 'Becoming a Leader' --print what a user has completed as shown in user_results) using a clean and quick for loop with necessary conditionals.

Problem: Current code is not achieving the aforementioned goal.

Any suggestions are highly appreciated! I'm still a newbie, so any guidance is truly welcomed!


Views.py

   def view_assessments(request):
        owner = authenticated_userid(request)
        print 'login owner', owner
        if owner is None:
            raise HTTPForbidden()
        all_assessments = api.retrieve_assessments()
        print 'these are all the assessments:', all_assessments
        print 'and type:', type(all_assessments)
        all_results = api.retrieve_assessment_results() # all the assessment results in a list
    
for x in all_assessments:
    alls = x.name
    if alls is not None: 
        for x in all_results: #found user based on all results
            assessment = x.assessment.name
            user = x.owner.username
            if user == owner:
                print 'completed', assessment
            elif assessment != alls: # DOES NOT WORK
                alls.index(assessment)

return {'assessments': all_assessments, 'assessment_results': all_results, 'loggedin': owner, 'user_results': user_results}

A breakdown of what the api does:

Currently all_assessments prints out a list of all the existing assessment names and text.

all_assessments = [<Assessment(name='Becoming a Leader', text='better decisions')>, <Assessment(name='Good work', text='working on these skills')>, <Assessment(name='Teaching NTS', text='Series 1.1')>]

while all_results prints out all results of every user in a list. Shown here:

all_results [<Assessment_Result(owner='<User(username ='baseball', password='...', firstname ='Jenny', lastname ='Jen', email='dance@aol.com')>', assessment='<Assessment(name='Becoming a Leader', text='better decisions')>')>, <Assessment_Result(owner='<User(username ='donald', password='...', firstname ='Drew', lastname ='James', email='cool@gmail.com')>', assessment='<Assessment(name='Good work', text='working on these skills')>')>]

and finally, user_results prints results found by username (which is based on whomever is logged in).

retrieved by username: [<Assessment_Result(owner='<User(username ='dorisday', password='..', firstname ='Doris', lastname ='Day', email='dorisday@gmail.com')>', assessment='<Assessment(name='Becoming a Leader', text='better decisions')>')>, <Assessment_Result(owner='<User(username ='dorisday', password='..', firstname ='Doris', lastname ='Day', email='dorisday@gmail.com')>', assessment='<Assessment(name='Good work', text='working on these skills')>')>]

Solution

  • I would start with something like this:

    def view_assessments(request):
         logged_in_userid = authenticated_userid(request)
         if logged_in_userid is None:
             raise HTTPForbidden()
         all_assessments = api.retrieve_assessments()
         all_results = api.retrieve_assessment_results()
    
         completed_assessments = []
         pending_assessments = []
    
         for assessment in all_assessments:
             if assessment.name is None: 
                 continue
    
             found_assessment_result = False
             for result in all_results:
                 if result.owner.username == logged_in_userid and result.assessment == assessment:
                     found_assessment_result = True
                     break  # no need to check further
    
             if found_assessment_result:
                 compleded_assessments.append(assessment)
             else:
                 pending_assessments.append(assessment)
    
    
          return {'completed_assessments': completed_assessments, 'pending_assessments': pending_assessments, 'loggedin': owner, 'user_results': user_results}
    

    The trick here, when iterating over two nested lists, is to have a "found" boolean, which you set to False before entering the inner loop - after the inner loop finishes you can check the variable and, depending on its value, push the assessment into one of two lists.

    As you suspected, this code will probably be quite inefficient because it has to iterate over a product of all assessments and all results, so if you have, say, 10 assessments and 10 results it would require 100 iterations, but if you have 100 assessments and 100 results it'll be 10.000 iterations. But it'll do as a learning exercise.