Решение на Първа задача - температура и химични елементи от Цветан Христов

Обратно към всички решения

Към профила на Цветан Христов

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 17 успешни тест(а)
  • 0 неуспешни тест(а)

Код

def temperature_units_conversion_formulas(temperature, units_conversion)
conversion_formulas = {
['C', 'K'] => temperature + 273.15,
['C', 'F'] => (temperature * 9 / 5.to_f) + 32,
['K', 'F'] => (temperature * 9 / 5.to_f) - 459.67,
['K', 'C'] => temperature - 273.15,
['F', 'C'] => (temperature - 32) * 5 / 9.to_f,
['F', 'K'] => (temperature + 459.67) * 5 / 9.to_f,
}
conversion_formulas.fetch(units_conversion) if conversion_formulas.key? units_conversion

Тук няма нужда да използваш fetch. По подразбиране предпочитай [], освен ако не си 100% сигурен, че искаш да получиш грешка за несъществуващ ключ.

А конструкцията hash.fetch(key) if hash.key? key се държи по абсолютно същия начин, както и hash[key]. Тоест връща nil, когато го няма ключа.

end
def convert_between_temperature_units(temperature, current_unit, resulting_unit)
temperature = temperature.to_f if temperature.is_a? Numeric
return temperature if current_unit == resulting_unit
temperature_units_conversion_formulas(temperature, [current_unit, resulting_unit])
end
def substance_state_temperature(substance, desired_state, resulting_unit)
substance_temperatures = {
water: { melting: 0, boiling: 100 },
ethanol: { melting: -114, boiling: 78.37 },
gold: { melting: 1_064, boiling: 2_700 },
silver: { melting: 961.8, boiling: 2_162 },
copper: { melting: 1_085, boiling: 2_567 },
}
substance_states = substance_temperatures.fetch(substance.to_sym)
substance_temperature = substance_states.fetch(desired_state.to_sym)

Виж коментара за [] :) Просто в Ruby света fetch се използва изключително рядко. В повечето случаи искаш или да го оставиш да гръмне, или да хвърлиш собствена грешка, свързана с domain логиката ти.

convert_between_temperature_units(substance_temperature, 'C', resulting_unit)
end
def melting_point_of_substance(substance, resulting_unit)
substance_state_temperature(substance, 'melting', resulting_unit)

Тук е по-добре да подадеш директно символа :melting.

http://fmi.ruby.bg/tasks/1/solutions/1#comment-216

Това е част от кода и не го използваш никъде другаде. Освен това ще имаш едно преобразуване по-малко.

Даже в този вариант, ако държиш имената на елементите да са символи, бих предпочел да сложа to_sym тук, вместо в substance_state_temperature. Логиката за това е, че е добре възможно най-рано да преобразуваш данните от външния свят към данните, които използва програмата ти. Освен това, ако ти се наложи да използваш substance_state_temperature от друго място, ще имаш избор какво да дадеш.

end
def boiling_point_of_substance(substance, resulting_unit)
substance_state_temperature(substance, 'boiling', resulting_unit)
end

Лог от изпълнението

.................

Finished in 0.00909 seconds
17 examples, 0 failures

История (4 версии и 11 коментара)

Цветан обнови решението на 16.10.2016 23:53 (преди около 8 години)

+def temperature_units_conversion_formulas(temperature, units_conversion)
+ conversion_formulas = {
+ ['C', 'K'] => temperature + 273.15,
+ ['C', 'F'] => temperature * 9 / 5.to_f + 32,
+ ['K', 'F'] => temperature * 9 / 5.to_f - 459.67,
+ ['K', 'C'] => temperature - 273.15,
+ ['F', 'C'] => (temperature - 32) * 5 / 9.to_f,
+ ['F', 'K'] => (temperature + 459.67) * 5 / 9.to_f,
+ }
+ conversion_formulas.fetch(units_conversion) if conversion_formulas.key? units_conversion
+end
+
+def convert_between_temperature_units(temperature, current_unit, resulting_unit)
+ temperature = temperature.to_f if temperature.is_a? Numeric
+ return temperature if current_unit == resulting_unit
+ temperature_units_conversion_formulas(temperature, [current_unit, resulting_unit])
+end
+
+def substance_temperature(substance, desired_state, resulting_unit)
+ substance_temperatures = {
+ water: {melting: 0, boiling: 100},
+ ethanol: {melting: -114, boiling: 78.37},
+ gold: {melting: 1_064, boiling: 2_700},
+ silver: {melting: 961.8, boiling: 2_162},
+ copper: {melting: 1_085, boiling: 2_567},
+ }
+ substance_states = substance_temperatures.fetch(substance.to_sym)
+ substance_temperature = substance_states.fetch(desired_state.to_sym)
+ convert_between_temperature_units(substance_temperature, 'C', resulting_unit)
+end
+
+def melting_point_of_substance(substance, resulting_unit)
+ substance_temperature(substance, 'melting', resulting_unit)
+end
+
+def boiling_point_of_substance(substance, resulting_unit)
+ substance_temperature(substance, 'boiling', resulting_unit)
+end

Цветан обнови решението на 17.10.2016 00:21 (преди около 8 години)

def temperature_units_conversion_formulas(temperature, units_conversion)
conversion_formulas = {
['C', 'K'] => temperature + 273.15,
- ['C', 'F'] => temperature * 9 / 5.to_f + 32,
- ['K', 'F'] => temperature * 9 / 5.to_f - 459.67,
+ ['C', 'F'] => (temperature * 9 / 5.to_f) + 32,
+ ['K', 'F'] => (temperature * 9 / 5.to_f) - 459.67,
['K', 'C'] => temperature - 273.15,
['F', 'C'] => (temperature - 32) * 5 / 9.to_f,
['F', 'K'] => (temperature + 459.67) * 5 / 9.to_f,
}
conversion_formulas.fetch(units_conversion) if conversion_formulas.key? units_conversion
end
def convert_between_temperature_units(temperature, current_unit, resulting_unit)
temperature = temperature.to_f if temperature.is_a? Numeric
return temperature if current_unit == resulting_unit
temperature_units_conversion_formulas(temperature, [current_unit, resulting_unit])
end
def substance_temperature(substance, desired_state, resulting_unit)
substance_temperatures = {
- water: {melting: 0, boiling: 100},
- ethanol: {melting: -114, boiling: 78.37},
- gold: {melting: 1_064, boiling: 2_700},
- silver: {melting: 961.8, boiling: 2_162},
- copper: {melting: 1_085, boiling: 2_567},
+ water: { melting: 0, boiling: 100 },
+ ethanol: { melting: -114, boiling: 78.37 },
+ gold: { melting: 1_064, boiling: 2_700 },
+ silver: { melting: 961.8, boiling: 2_162 },
+ copper: { melting: 1_085, boiling: 2_567 },
}
substance_states = substance_temperatures.fetch(substance.to_sym)
substance_temperature = substance_states.fetch(desired_state.to_sym)
convert_between_temperature_units(substance_temperature, 'C', resulting_unit)
end
def melting_point_of_substance(substance, resulting_unit)
substance_temperature(substance, 'melting', resulting_unit)
end
def boiling_point_of_substance(substance, resulting_unit)
substance_temperature(substance, 'boiling', resulting_unit)
end

Цветан обнови решението на 17.10.2016 08:35 (преди около 8 години)

def temperature_units_conversion_formulas(temperature, units_conversion)
conversion_formulas = {
- ['C', 'K'] => temperature + 273.15,
+ ['C', 'K'] => temperature + 273.15,
['C', 'F'] => (temperature * 9 / 5.to_f) + 32,
['K', 'F'] => (temperature * 9 / 5.to_f) - 459.67,
- ['K', 'C'] => temperature - 273.15,
+ ['K', 'C'] => temperature - 273.15,
['F', 'C'] => (temperature - 32) * 5 / 9.to_f,
['F', 'K'] => (temperature + 459.67) * 5 / 9.to_f,
}
conversion_formulas.fetch(units_conversion) if conversion_formulas.key? units_conversion
end
def convert_between_temperature_units(temperature, current_unit, resulting_unit)
temperature = temperature.to_f if temperature.is_a? Numeric
return temperature if current_unit == resulting_unit
temperature_units_conversion_formulas(temperature, [current_unit, resulting_unit])
end
-def substance_temperature(substance, desired_state, resulting_unit)
+def substance_state_temperature(substance, desired_state, resulting_unit)
substance_temperatures = {
water: { melting: 0, boiling: 100 },
ethanol: { melting: -114, boiling: 78.37 },
gold: { melting: 1_064, boiling: 2_700 },
silver: { melting: 961.8, boiling: 2_162 },
copper: { melting: 1_085, boiling: 2_567 },
}
substance_states = substance_temperatures.fetch(substance.to_sym)
substance_temperature = substance_states.fetch(desired_state.to_sym)
convert_between_temperature_units(substance_temperature, 'C', resulting_unit)
end
def melting_point_of_substance(substance, resulting_unit)
- substance_temperature(substance, 'melting', resulting_unit)
+ substance_state_temperature(substance, 'melting', resulting_unit)
end
def boiling_point_of_substance(substance, resulting_unit)
- substance_temperature(substance, 'boiling', resulting_unit)
+ substance_state_temperature(substance, 'boiling', resulting_unit)
end

Цветан обнови решението на 17.10.2016 15:03 (преди около 8 години)

def temperature_units_conversion_formulas(temperature, units_conversion)
conversion_formulas = {
['C', 'K'] => temperature + 273.15,
['C', 'F'] => (temperature * 9 / 5.to_f) + 32,
['K', 'F'] => (temperature * 9 / 5.to_f) - 459.67,
['K', 'C'] => temperature - 273.15,
['F', 'C'] => (temperature - 32) * 5 / 9.to_f,
['F', 'K'] => (temperature + 459.67) * 5 / 9.to_f,
}
conversion_formulas.fetch(units_conversion) if conversion_formulas.key? units_conversion

Тук няма нужда да използваш fetch. По подразбиране предпочитай [], освен ако не си 100% сигурен, че искаш да получиш грешка за несъществуващ ключ.

А конструкцията hash.fetch(key) if hash.key? key се държи по абсолютно същия начин, както и hash[key]. Тоест връща nil, когато го няма ключа.

end
def convert_between_temperature_units(temperature, current_unit, resulting_unit)
temperature = temperature.to_f if temperature.is_a? Numeric
return temperature if current_unit == resulting_unit
temperature_units_conversion_formulas(temperature, [current_unit, resulting_unit])
end
def substance_state_temperature(substance, desired_state, resulting_unit)
substance_temperatures = {
- water: { melting: 0, boiling: 100 },
- ethanol: { melting: -114, boiling: 78.37 },
- gold: { melting: 1_064, boiling: 2_700 },
- silver: { melting: 961.8, boiling: 2_162 },
- copper: { melting: 1_085, boiling: 2_567 },
+ water: { melting: 0, boiling: 100 },
+ ethanol: { melting: -114, boiling: 78.37 },
+ gold: { melting: 1_064, boiling: 2_700 },
+ silver: { melting: 961.8, boiling: 2_162 },
+ copper: { melting: 1_085, boiling: 2_567 },
}
substance_states = substance_temperatures.fetch(substance.to_sym)
substance_temperature = substance_states.fetch(desired_state.to_sym)

Виж коментара за [] :) Просто в Ruby света fetch се използва изключително рядко. В повечето случаи искаш или да го оставиш да гръмне, или да хвърлиш собствена грешка, свързана с domain логиката ти.

convert_between_temperature_units(substance_temperature, 'C', resulting_unit)
end
def melting_point_of_substance(substance, resulting_unit)
substance_state_temperature(substance, 'melting', resulting_unit)

Тук е по-добре да подадеш директно символа :melting.

http://fmi.ruby.bg/tasks/1/solutions/1#comment-216

Това е част от кода и не го използваш никъде другаде. Освен това ще имаш едно преобразуване по-малко.

Даже в този вариант, ако държиш имената на елементите да са символи, бих предпочел да сложа to_sym тук, вместо в substance_state_temperature. Логиката за това е, че е добре възможно най-рано да преобразуваш данните от външния свят към данните, които използва програмата ти. Освен това, ако ти се наложи да използваш substance_state_temperature от друго място, ще имаш избор какво да дадеш.

end
def boiling_point_of_substance(substance, resulting_unit)
substance_state_temperature(substance, 'boiling', resulting_unit)
end

@Цветан, оставих малко коментари inline :)

Относно масива за ключ - това е една от малкото добри употреби на това. Разбира се, може да се избегне като:

  • направиш ключа стринг и конкатенираш при търсене
  • промениш логиката, така че да правиш две последователни преобразувания, вместо едно директно

Ако си разгледал решенията на другите сигурно си видял и двата варианта. Масивите и стринговете са ми на кантар, но по-скоро бих предпочел твоя вариант с масивите (ако не съм се сетил за втория).

Двата алтернативни варианта са две нива на промени - едното е на ниво алгоритъм, другото е на ниво структуриране на код.

Ако имаш други въпроси - питай!