You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

直角三角形属性计算:最少条件语句与优雅实现方案问询

Cleaner Approach for Right-Angle Triangle Property Calculation

Great question! Those repetitive if/else chains are definitely a pain to maintain—let's break down a cleaner, more scalable approach to solve this problem. The core issue with your original code is that it's handling order-dependent property pairs (like adjacent+opposite and opposite+adjacent as separate cases), which doubles the number of checks needed. We can fix this by normalizing input first, then focusing on unique property combinations.

Step-by-Step Optimized Solution

1. Normalize Input to Eliminate Order Dependency

First, we'll take the input properties and map them to instance variables regardless of their order. This way, we only need to handle each unique pair of properties once, not twice.

2. Separate Calculation Logic into Modular Blocks

We'll move the math logic into a dedicated method, with each block handling one unique combination of known properties. This makes the code easier to debug and extend if needed.

Full Optimized Code

import math

class RightAngleTriangle:
    def __init__(self, prop1_type, prop1_val, prop2_type, prop2_val):
        # Initialize all properties as None (unknown)
        self.adjacent = None
        self.opposite = None
        self.hypotenuse = None
        self.area = None

        # Map input properties to instance variables (ignores order)
        known_properties = {prop1_type: prop1_val, prop2_type: prop2_val}
        for prop_name, value in known_properties.items():
            setattr(self, prop_name, value)

        # Calculate missing properties
        self._calculate_missing()

    def _calculate_missing(self):
        # Case 1: Adjacent + Opposite known
        if self.adjacent is not None and self.opposite is not None:
            self.hypotenuse = math.hypot(self.adjacent, self.opposite)
            self.area = (self.adjacent * self.opposite) / 2

        # Case 2: Adjacent + Hypotenuse known
        elif self.adjacent is not None and self.hypotenuse is not None:
            self.opposite = math.sqrt(self.hypotenuse**2 - self.adjacent**2)
            self.area = (self.adjacent * self.opposite) / 2

        # Case 3: Adjacent + Area known
        elif self.adjacent is not None and self.area is not None:
            self.opposite = (2 * self.area) / self.adjacent
            self.hypotenuse = math.hypot(self.adjacent, self.opposite)

        # Case 4: Opposite + Hypotenuse known
        elif self.opposite is not None and self.hypotenuse is not None:
            self.adjacent = math.sqrt(self.hypotenuse**2 - self.opposite**2)
            self.area = (self.adjacent * self.opposite) / 2

        # Case 5: Opposite + Area known
        elif self.opposite is not None and self.area is not None:
            self.adjacent = (2 * self.area) / self.opposite
            self.hypotenuse = math.hypot(self.adjacent, self.opposite)

        # Case 6: Hypotenuse + Area known (requires quadratic solution)
        elif self.hypotenuse is not None and self.area is not None:
            sum_ao = math.sqrt(self.hypotenuse**2 + 4 * self.area)
            diff_ao = math.sqrt(self.hypotenuse**2 - 4 * self.area)
            self.adjacent = (sum_ao + diff_ao) / 2
            self.opposite = (sum_ao - diff_ao) / 2

        else:
            raise ValueError("Invalid or duplicate property pair provided")

Usage Example

# Original input order
t1 = RightAngleTriangle("adjacent", 10, "opposite", 12)
print(t1.adjacent)   # 10
print(t1.opposite)   # 12
print(t1.hypotenuse) # ~15.6205
print(t1.area)       # 60

# Reversed input order (works the same!)
t2 = RightAngleTriangle("opposite", 12, "adjacent", 10)
print(t2.hypotenuse) # ~15.6205

Key Improvements Over Your Original Code

  • Reduced Redundancy: We went from 12 if/else blocks to 6, since we no longer handle reversed property pairs separately.
  • Better Readability: Logic is grouped by unique property combinations, making it easy to follow or modify individual calculations.
  • Bug Fix: Your original code had an error in the adjacent+hypotenuse case (using + instead of - in the square root)—this approach makes such mistakes easier to catch.
  • Modularity: The calculation logic is isolated in _calculate_missing, so you can update math rules without touching input handling.

Bonus: Even More Scalable Approach (Using a Function Map)

If you want to make the code even more extensible, you can map property pairs to dedicated calculation functions:

import math

class RightAngleTriangle:
    def __init__(self, prop1_type, prop1_val, prop2_type, prop2_val):
        self.adjacent = None
        self.opposite = None
        self.hypotenuse = None
        self.area = None

        known_properties = {prop1_type: prop1_val, prop2_type: prop2_val}
        for prop_name, value in known_properties.items():
            setattr(self, prop_name, value)

        self._calculate_missing()

    def _calc_adj_opp(self):
        self.hypotenuse = math.hypot(self.adjacent, self.opposite)
        self.area = (self.adjacent * self.opposite) / 2

    def _calc_adj_hyp(self):
        self.opposite = math.sqrt(self.hypotenuse**2 - self.adjacent**2)
        self.area = (self.adjacent * self.opposite) / 2

    def _calc_adj_area(self):
        self.opposite = (2 * self.area) / self.adjacent
        self.hypotenuse = math.hypot(self.adjacent, self.opposite)

    def _calc_opp_hyp(self):
        self.adjacent = math.sqrt(self.hypotenuse**2 - self.opposite**2)
        self.area = (self.adjacent * self.opposite) / 2

    def _calc_opp_area(self):
        self.adjacent = (2 * self.area) / self.opposite
        self.hypotenuse = math.hypot(self.adjacent, self.opposite)

    def _calc_hyp_area(self):
        sum_ao = math.sqrt(self.hypotenuse**2 + 4 * self.area)
        diff_ao = math.sqrt(self.hypotenuse**2 - 4 * self.area)
        self.adjacent = (sum_ao + diff_ao) / 2
        self.opposite = (sum_ao - diff_ao) / 2

    def _calculate_missing(self):
        # Get sorted tuple of known properties to handle order
        known_props = tuple(sorted(
            prop for prop in ["adjacent", "opposite", "hypotenuse", "area"] 
            if getattr(self, prop) is not None
        ))

        # Map property pairs to their calculation functions
        calc_map = {
            ("adjacent", "opposite"): self._calc_adj_opp,
            ("adjacent", "hypotenuse"): self._calc_adj_hyp,
            ("adjacent", "area"): self._calc_adj_area,
            ("opposite", "hypotenuse"): self._calc_opp_hyp,
            ("opposite", "area"): self._calc_opp_area,
            ("hypotenuse", "area"): self._calc_hyp_area,
        }

        if known_props in calc_map:
            calc_map[known_props]()
        else:
            raise ValueError("Invalid property pair provided")

This version makes it trivial to add new property combinations (if needed) by just adding a new function and updating the calc_map.

内容的提问来源于stack exchange,提问作者J. Chapman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:45:12