Here’s the given for the problem I’m trying to solve:
*python Write a function that given a mapping from material to boiling points, and a boiling point temperature, will return :
- the material corresponding to the boiling, if it is within 5% difference
- ‘UNKNOWN’ otherwise
Function signature should look like : boiling_material(boiling_map, boiling_point)
An example boiling_map : Given input : ‘ Butane’ : _0.5, ‘copper’ : 1187, ‘Gold’ : 2660, ‘Mercury’ : 357, ‘Methane’ : _161.7, ‘Nonane’: 150.8, ‘Silver’ : 2197, ‘water’: 100}*
A sample run of the program with the above input:
Enter boiling point > 359 Closest material : Mercury
Enter boiling point > 2000 Closest material : Unknown
I attempted to solve it and it’s returning the right output when the inputs are positive numbers but it’s only returning ‘unknown’ when the inputs are negative. Example: Enter boiling point > -0.475 Expected Closest material : Butane actual output: Unknown
This is my current code.
boiling_map=dict() boiling_map['Butane']=-0.5 boiling_map['Copper']=1187 boiling_map['Gold']=2660 boiling_map['Mercury']=357 boiling_map['Methane']=-161.7 boiling_map['Nonane']=150.8 boiling_map['water']=100 def boiling_material(boiling_map,boiling_point): closest='unknown' for material in boiling_map: if abs(boiling_map[material]) >=abs(boiling_point-(boiling_point*5//100)) and abs(boiling_map[material]-boiling_point)<=abs(boiling_point+(boiling_point*5//100)) : closest=material return closest print(boiling_material(boiling_map,359)) print(boiling_material(boiling_map,-0.475)) print(boiling_material(boiling_map,0))
Advertisement
Answer
You could do something like this. The below is using Python 3.10.4, anything under 3.10 won’t support using the match
keyword. Note that for some test temperatures you get known results on some temperature scales, but not on others. Note that the results here are either “unknown” or a list of candidates.
Added a material and some test temperatures to make things interesting.
from enum import Enum import sys; class TemperatureScale(Enum): CELCIUS = 1 KELVIN = 2 FAHRENHEIT = 3 # boiling points are in kelvin materials = { "Butane": 272.65 , "Copper": 1460.15 , "Gold": 2933.15 , "Mercury": 630.15 , "Methane": 111.45 , "Nonane": 423.95 , "Water": 373.15 , "Propyl Alcohol": 370.65 } def kelvin_to_scale(temp, scale): match scale: case TemperatureScale.KELVIN: return temp case TemperatureScale.CELCIUS: return temp - 273.15 case TemperatureScale.FAHRENHEIT: return 1.8 * (temp - 273.15) + 32 case _: raise Exception('unknown scale') def scale_to_kelvin(temp, scale): match scale: case TemperatureScale.KELVIN: return temp case TemperatureScale.CELCIUS: return temp + 273.15 case TemperatureScale.FAHRENHEIT: return (temp*5//9)+459.67 case _: raise Exception('unknown scale') def test_material(boiling_point, scale = TemperatureScale.KELVIN): print(f'Test temperature: {boiling_point} {scale}') candidates = [] for material in materials: bp = kelvin_to_scale(materials[material], scale) margin = abs(boiling_point)*5//100 print(f'Testing {material} using {bp} +/- {margin}:t{bp - margin} <= {boiling_point} < {bp + margin}') if (bp - margin <= boiling_point) and (bp + margin > boiling_point): candidates += [ material ] return candidates # test values are in celcius test_values = [ 2801, 359, -0.475, 0, 95 ] for test_value in test_values: kelvin_value = scale_to_kelvin(test_value, TemperatureScale.CELCIUS) for scale in [ TemperatureScale.CELCIUS, TemperatureScale.KELVIN, TemperatureScale.FAHRENHEIT ]: print(test_material(kelvin_to_scale(kelvin_value, scale), scale) or 'unknown')