Question
Design a multi-tier decision-making system using if-else statements that can be used to determine the eligibility criteria for a scholarship. The system should take into account multiple factors like grades, extracurricular activities, and financial need.
Thought Process
To design a multi-tier decision-making system for determining scholarship eligibility based on grades, extracurricular activities, and financial need, you need a structured approach to evaluate and assign scholarship amounts. Here’s a step-by-step breakdown of how to create a decision-making system using if-else statements:
Criteria for Scholarship Decision
- Financial Condition: Determines how financially needy the student is.
- Extracurricular Activities: Measures involvement outside academics.
- Grades: Reflects academic performance.
Scholarship Decision Logic
- Determine Financial Need: Check if the student falls into high, medium, or low financial need categories.
- Assess Extracurricular Involvement: Within each financial need category, check how active the student is in extracurricular activities.
- Evaluate Grades: Finally, assess the student’s grades to decide the exact scholarship amount.
Scholarship Amounts
- High Need, High Extracurricular, High Grades: Maximum scholarship.
- High Need, Medium Extracurricular, Medium Grades: Moderate scholarship.
- High Need, Low Extracurricular, Low Grades: Minimal scholarship.
- Medium Need, High Extracurricular, High Grades: Substantial scholarship.
- Medium Need, Medium Extracurricular, Medium Grades: Moderate scholarship.
- Medium Need, Low Extracurricular, Low Grades: Minimal scholarship.
- Low Need, High Extracurricular, High Grades: Moderate scholarship.
- Low Need, Medium Extracurricular, Medium Grades: Small scholarship.
- Low Need, Low Extracurricular, Low Grades: No scholarship.
Solution
def scholarship(financial_cond, extra_act, grades):
if financial_cond >=80:
if extra_act >=80:
if grades >=80:
return 5000
if grades>= 60 and grades <80:
return 3000
if grades>= 40 and grades <60:
return 2000
if extra_act >= 60 and extra_act < 80:
if grades >=80:
return 4000
if grades>= 60 and grades <80:
return 2000
if grades>= 40 and grades <60:
return 1000
if extra_act >= 40 and extra_act <60:
if grades >=80:
return 3000
if grades>= 60 and grades <80:
return 1000
if grades>= 40 and grades <60:
return 000
if financial_cond >=60 and financial_cond <80:
if extra_act >=80:
if grades >=80:
return 4000
if grades>= 60 and grades <80:
return 2000
if grades>= 40 and grades <60:
return 1000
if extra_act >= 60 and extra_act < 80:
if grades >=80:
return 3000
if grades>= 60 and grades <80:
return 1000
if grades>= 40 and grades <60:
return 0000
if extra_act >= 40 and extra_act <60:
if grades >=80:
return 2000
if grades>= 60 and grades <80:
return 0000
if grades>= 40 and grades <60:
return 000
if financial_cond >= 40 and financial_cond <60:
if extra_act >=80:
if grades >=80:
return 3000
if grades>= 60 and grades <80:
return 1000
if grades>= 40 and grades <60:
return 000
if extra_act >= 60 and extra_act < 80:
if grades >=80:
return 2000
if grades>= 60 and grades <80:
return 000
if grades>= 40 and grades <60:
return 000
if extra_act >= 40 and extra_act <60:
if grades >=80:
return 1000
if grades>= 60 and grades <80:
return 000
if grades>= 40 and grades <60:
return 000
else:
return 0
financial_cond = float(input('Enter financial condition in 1 to 100 '))
extrac_act = float(input('Enter the extracurricular participation in 1 to 100 '))
grades= float(input('Enter the grades of the student '))
print(scholarship(financial_cond, extrac_act, grades))
Other Ideas
Idea 1
financial_cond = float(input('Enter financial condition in 1 to 100 '))
extrac_act = float(input('Enter the extracurricular participation in 1 to 100 '))
grades= float(input('Enter the grades of the student '))
def scholarship():
if financial_cond >= 80 and extrac_act >= 80 and grades >= 80:
return 10000
elif financial_cond >= 80 and extrac_act >= 80 and grades >= 60 and grades <80:
return 5000
elif financial_cond >= 80 and extrac_act >= 80 and grades >= 40 and grades < 60:
return 2000
elif financial_cond >= 80 and extrac_act >= 60 and extrac_act < 80 and grades >= 80:
return 5000
elif financial_cond >=80 and extrac_act >=60 and extrac_act < 80 and grades >= 60 and grades < 80:
return 2000
elif financial_cond >= 80 and extrac_act >=50 and extrac_act < 60 and grades >= 60 and grades < 80:
return 1000
elif financial_cond >= 60 and financial_cond < 80 and extrac_act >= 80 and grades >=80:
return 5000
elif financial_cond >=60 and financial_cond < 80 and extrac_act >=60 and extrac_act < 80 and grades >= 80:
return 2000
elif financial_cond >=60 and financial_cond < 80 and extrac_act >= 60 and extrac_act < 80 and grades >= 60 and grades < 80:
return 1000
else:
return 0
scholarship()
Reasons for Rejection:
- Scope and Redundancy: The scholarship() function does not take parameters, so it relies on global variables (financial_cond, extrac_act, grades) that are input directly. This design is less modular and can lead to issues in maintaining and testing the code.
- Overlap and Ambiguity: Some conditions overlap or are redundant. For instance, multiple elif branches check similar conditions with slight differences in thresholds or ranges, which can make the logic confusing and error-prone.
- Logic Complexity: The use of multiple elif statements with overlapping conditions creates a complex structure that is hard to follow. It’s not immediately clear which condition will be true and what the final result will be in various scenarios.
Idea 2
def scholarship(financial_cond, extra_act, grades):
if financial_cond >= 80:
return high_financial(extra_act, grades)
elif financial_cond >= 60:
return medium_financial(extra_act, grades)
elif financial_cond >= 40:
return low_financial(extra_act, grades)
else:
return 0
def high_financial(extra_act, grades):
if extra_act >= 80:
if grades >= 80:
return 5000
elif grades >= 60:
return 3000
elif grades >= 40:
return 2000
elif extra_act >= 60:
if grades >= 80:
return 4000
elif grades >= 60:
return 2000
elif grades >= 40:
return 1000
elif extra_act >= 40:
if grades >= 80:
return 3000
elif grades >= 60:
return 1000
elif grades >= 40:
return 0
def medium_financial(extra_act, grades):
if extra_act >= 80:
if grades >= 80:
return 4000
elif grades >= 60:
return 2000
elif grades >= 40:
return 1000
elif extra_act >= 60:
if grades >= 80:
return 3000
elif grades >= 60:
return 1000
elif grades >= 40:
return 0
elif extra_act >= 40:
if grades >= 80:
return 2000
elif grades >= 60:
return 0
elif grades >= 40:
return 0
def low_financial(extra_act, grades):
if extra_act >= 80:
if grades >= 80:
return 3000
elif grades >= 60:
return 1000
elif grades >= 40:
return 0
elif extra_act >= 60:
if grades >= 80:
return 2000
elif grades >= 60:
return 0
elif grades >= 40:
return 0
elif extra_act >= 40:
if grades >= 80:
return 1000
elif grades >= 60:
return 0
elif grades >= 40:
return 0
financial_cond = float(input('Enter financial condition in 1 to 100: '))
extra_act = float(input('Enter the extracurricular participation in 1 to 100: '))
grades = float(input('Enter the grades of the student: '))
print(scholarship(financial_cond, extra_act, grades))
Reasons for Rejection:
- Code Redundancy: The logic for determining scholarships is repeated across different financial need categories (high_financial, medium_financial, low_financial), leading to redundant code. This could be simplified to avoid repetition and reduce the risk of inconsistencies.
- Complexity in Function Calls: The nested function calls and multiple layers of conditions make the code harder to follow and maintain. The separation into different functions is good for modularity but can be excessive and confusing due to the amount of nested conditions.
- Inconsistent Scholarship Amounts: The decision logic for scholarship amounts between different financial need levels is not always consistent, leading to potential confusion about why certain scholarship amounts are given based on specific conditions.
Idea 3
grades = float(input("Enter the applicant's GPA : "))
extracurriculars = int(input("Enter the number of extracurricular activities: "))
financial_need = input("Is there a financial need? (yes/no): ").strip().lower()
eligible = True
grade_thresholds = [3.5, 3.0, 2.5]
scholarship_level = None
for threshold in grade_thresholds:
if grades >= threshold:
if threshold == 3.5:
scholarship_level = "Full Scholarship"
elif threshold == 3.0:
scholarship_level = "Partial Scholarship"
elif threshold == 2.5:
scholarship_level = "Basic Scholarship"
break
else:
eligible = False
print("Applicant does not meet the minimum grade requirement.")
if eligible:
extracurricular_threshold = 2 # Minimum number of activities required
if extracurriculars < extracurricular_threshold:
eligible = False
print("Applicant does not meet the extracurricular activities requirement.")
if eligible:
while financial_need not in ['yes', 'no']:
financial_need = input("Please enter 'yes' or 'no' for financial need: ").strip().lower()
if financial_need == 'no':
scholarship_level = "Merit-based Scholarship" # Adjust the scholarship type based on no financial need
if eligible:
print(f"The applicant is eligible for the {scholarship_level}.")
else:
print("The applicant is not eligible for the scholarship.")
Reasons for Rejection
- Oversimplification: The approach is too simplistic as it does not account for a range of conditions but rather uses a single threshold for grades and a binary check for financial need. This could overlook important nuances in determining eligibility and scholarship amounts.
- Hard-Coded Values: Scholarship levels are hard-coded based on GPA and a binary check for financial need without considering other factors like the level of extracurricular involvement or more granular financial need assessments.
- Interaction Handling: The loop for handling financial need input could potentially cause an infinite loop if the user does not enter ‘yes’ or ‘no’ (though the infinite loop might be a rare issue in practice, it is a potential flaw).
Reasons for selecting solution and potential flaws in it
Let’s review the proposed solution and analyze the reasons for its selection as well as potential flaws:
Proposed Solution
def scholarship(financial_cond, extra_act, grades):
if financial_cond >=80:
if extra_act >=80:
if grades >=80:
return 5000
elif grades >= 60:
return 3000
elif grades >= 40:
return 2000
elif extra_act >= 60:
if grades >=80:
return 4000
elif grades >= 60:
return 2000
elif grades >= 40:
return 1000
elif extra_act >= 40:
if grades >=80:
return 3000
elif grades >= 60:
return 1000
elif grades >= 40:
return 0
elif financial_cond >=60:
if extra_act >=80:
if grades >=80:
return 4000
elif grades >= 60:
return 2000
elif grades >= 40:
return 1000
elif extra_act >= 60:
if grades >=80:
return 3000
elif grades >= 60:
return 1000
elif grades >= 40:
return 0
elif extra_act >= 40:
if grades >=80:
return 2000
elif grades >= 60:
return 0
elif grades >= 40:
return 0
elif financial_cond >= 40:
if extra_act >=80:
if grades >=80:
return 3000
elif grades >= 60:
return 1000
elif grades >= 40:
return 0
elif extra_act >= 60:
if grades >=80:
return 2000
elif grades >= 60:
return 0
elif grades >= 40:
return 0
elif extra_act >= 40:
if grades >=80:
return 1000
elif grades >= 60:
return 0
elif grades >= 40:
return 0
else:
return 0
financial_cond = float(input('Enter financial condition in 1 to 100 '))
extra_act = float(input('Enter the extracurricular participation in 1 to 100 '))
grades = float(input('Enter the grades of the student '))
print(scholarship(financial_cond, extra_act, grades))
Reasons for Selection
- Structured Approach: The solution uses a multi-tier decision-making process that evaluates financial condition, extracurricular activities, and grades systematically. This structured approach allows for a clear, organized method of determining scholarship eligibility.
- Detailed Evaluation: The solution covers a range of conditions with specific thresholds for financial need, extracurricular involvement, and academic performance, providing a detailed framework for assigning scholarship amounts.
- Modularity: By separating different levels of financial need and evaluating other criteria within these levels, the solution introduces a modular structure that is easier to manage and update.
- Clear Decision Path: The nested
if-else
statements create a clear path of decision-making, making it explicit which conditions lead to which scholarship amounts.
Potential Flaws
- Redundancy and Complexity: The code contains a lot of redundancy. For instance, the checks for grades and extracurricular activities are repeated multiple times. This redundancy increases the complexity of the code and makes it harder to maintain and understand.
- Code Duplication: The decision-making logic for each range of
financial_cond
has similar patterns but with slightly different thresholds. This duplication could be avoided by consolidating common logic and reducing repetitive code blocks. - Hardcoded Values: The scholarship amounts and thresholds are hardcoded, which makes it inflexible. If the criteria or amounts need to change, the code must be updated manually. Using a configuration file or constants would improve flexibility.
- Lack of Input Validation: The code does not validate the inputs to ensure they are within expected ranges or types. For example,
financial_cond
,extra_act
, andgrades
are expected to be between 1 and 100, but the code does not enforce or validate this. - Edge Cases: The solution does not handle edge cases robustly. For example, if
financial_cond
,extra_act
, orgrades
are exactly on the boundary values (e.g., exactly 40, 60, or 80), the handling is somewhat ambiguous. Clearer handling of boundary cases would make the decision logic more precise. - No Feedback or Explanation: The solution only provides the scholarship amount and does not explain why a certain amount was given. Adding feedback or an explanation could improve user understanding and transparency.
Can you improve the proposed solution as per modern standards? [Hint: Refactor Redundancy, Implement Input Validation, Use Constants, and Enhance User Feedback]
Advanced Solution
# Define constants for thresholds and scholarship amounts
HIGH_NEED = 80
MEDIUM_NEED = 60
LOW_NEED = 40
HIGH_EXTRA_ACT = 80
MEDIUM_EXTRA_ACT = 60
LOW_EXTRA_ACT = 40
HIGH_GRADES = 80
MEDIUM_GRADES = 60
LOW_GRADES = 40
SCHOLARSHIP_AMOUNTS = {
'high': {
'high': { 'high': 5000, 'medium': 3000, 'low': 2000 },
'medium': { 'high': 4000, 'medium': 2000, 'low': 1000 },
'low': { 'high': 3000, 'medium': 1000, 'low': 0 }
},
'medium': {
'high': { 'high': 4000, 'medium': 2000, 'low': 1000 },
'medium': { 'high': 3000, 'medium': 1000, 'low': 0 },
'low': { 'high': 2000, 'medium': 0, 'low': 0 }
},
'low': {
'high': { 'high': 3000, 'medium': 1000, 'low': 0 },
'medium': { 'high': 2000, 'medium': 0, 'low': 0 },
'low': { 'high': 1000, 'medium': 0, 'low': 0 }
}
}
def scholarship(financial_cond, extra_act, grades):
# Determine financial need level
if financial_cond >= HIGH_NEED:
need_level = 'high'
elif financial_cond >= MEDIUM_NEED:
need_level = 'medium'
else:
need_level = 'low'
# Determine extracurricular activity level
if extra_act >= HIGH_EXTRA_ACT:
act_level = 'high'
elif extra_act >= MEDIUM_EXTRA_ACT:
act_level = 'medium'
else:
act_level = 'low'
# Determine grades level
if grades >= HIGH_GRADES:
grade_level = 'high'
elif grades >= MEDIUM_GRADES:
grade_level = 'medium'
else:
grade_level = 'low'
# Retrieve scholarship amount
scholarship_amount = SCHOLARSHIP_AMOUNTS[need_level][act_level][grade_level]
return scholarship_amount
def validate_input(prompt, min_value, max_value):
while True:
try:
value = float(input(prompt))
if min_value <= value <= max_value:
return value
else:
print(f"Please enter a value between {min_value} and {max_value}.")
except ValueError:
print("Invalid input. Please enter a numerical value.")
financial_cond = validate_input('Enter financial condition (1 to 100): ', 1, 100)
extra_act = validate_input('Enter extracurricular participation (1 to 100): ', 1, 100)
grades = validate_input('Enter grades (1 to 100): ', 1, 100)
scholarship_amount = scholarship(financial_cond, extra_act, grades)
print(f"The student is eligible for a scholarship of: ${scholarship_amount}")
if scholarship_amount == 0:
print("The student does not qualify for a scholarship.")
else:
print(f"The scholarship amount awarded is based on the following criteria:\n"
f"Financial Condition: {financial_cond}\n"
f"Extracurricular Activities: {extra_act}\n"
f"Grades: {grades}")
Key Improvements:
- Constants and Dictionaries: Constants are used for threshold values and scholarship amounts, making the code more readable and easier to maintain. The nested dictionary
SCHOLARSHIP_AMOUNTS
reduces redundancy and provides a clear mapping for scholarship amounts. - Input Validation: A
validate_input
function ensures that the input values are within the expected range. - Modular Structure: The decision logic is cleanly separated into determining levels for financial condition, extracurricular activities, and grades, followed by retrieving the scholarship amount.
- Enhanced Feedback: The final print statements provide a clear explanation of the awarded scholarship amount and the criteria used for the decision.
- Code Readability: The overall structure is more readable, with reduced redundancy and better modularization.
In the advanced solution, there is still one flaw, can you find it?
Post also available at: https://dev.to/kavya-sahai-god/design-a-multi-tier-decision-making-system-to-determine-the-eligibility-criteria-for-a-scholarship-52m8
Pingback: Design a multi-tier decision-making system to determine the