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

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

Към профила на Теодор Филипов

Резултати

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

Код

K_TO_C_DIFFRENCE = 273.15
CONVERSION_FUNCTIONS = {
"f_to_c" => -> (f) { (f - 32) / 1.8 },
"k_to_c" => -> (k) { k - K_TO_C_DIFFRENCE },
"c_to_f" => -> (c) { c * 1.8 + 32 },
"c_to_k" => -> (c) { c + K_TO_C_DIFFRENCE },
}
def convert_between_temperature_units(degree, current_unit, wanted_unit)
degree_buffer = CONVERSION_FUNCTIONS.fetch(
current_unit.downcase + '_to_c', -> (x) { x }
).call(degree)
CONVERSION_FUNCTIONS.fetch(
'c_to_' + wanted_unit.downcase, -> (x) { x }
).call(degree_buffer)
end
SUBSTANCES_MELTING_POINTS = {
"water" => 0,
"ethanol" => -114,
"gold" => 1064,
"silver" => 961.8,
"copper" => 1085,
}
def melting_point_of_substance(substance, degree_unit)
convert_between_temperature_units(
SUBSTANCES_MELTING_POINTS[substance.downcase], 'c', degree_unit
)
end
SUBSTANCES_BOILING_POINTS = {
"water" => 100,
"ethanol" => 78.37,
"gold" => 2700,
"silver" => 2162,
"copper" => 2567
}
def boiling_point_of_substance(substance, degree_unit)
convert_between_temperature_units(
SUBSTANCES_BOILING_POINTS[substance.downcase], 'c', degree_unit
)
end

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

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

Finished in 0.00818 seconds
17 examples, 0 failures

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

Теодор обнови решението на 14.10.2016 23:18 (преди над 7 години)

+# C->K : K = C + 273.15 C = K - 273.15
+# C->F : F = C * 1.8 + 32 C = (F - 32) / 1.8
+# K->F : K = (F + 459.67) * 5 / 9 F = (K * 9 / 5) - 459.67
+def convert_between_temperature_units(degree, current_unit, wanted_unit)
+ return degree if current_unit == wanted_unit
+ k_to_c_diffrence = 273.15
+ f_to_k_diffrence = 459.67
+
+ conversion_functions = {
+ FtoK: -> (f) { (f + f_to_k_diffrence) * 5 / 9.to_r },
+ FtoC: -> (f) { (f - 32) / 1.8.to_r },
+ CtoF: -> (c) { c * 1.8.to_r + 32 },
+ CtoK: -> (c) { c + k_to_c_diffrence },
+ KtoC: -> (k) { k - k_to_c_diffrence },
+ KtoF: -> (k) { (k * 9 / 5.to_r) - f_to_k_diffrence }

Може да си спестиш част от формулите като конвертираш на 2 стъпки, ползвайки някоя мерна единица за междинна - Например вместо k => f да сметнеш k => c => f. Така за всяка нова мерна единица ще трябва да добавяш само формулата за нея от и до целзий, вместо до всички останали температурни скали.

+ }
+
+ conv_func_key = (current_unit.upcase << 'to' << wanted_unit.upcase).to_sym

Този ред ми прилича на C++. :)

  • По-добре използвай + вместо << за конкатенация. Стрелките променят стринга, към който долепяш, докато + генерира нов стринг и запазва съдържанието на аргументите си. В Ruby, за разлика от C++-подобните езици, стринговете не са масиви от знаци и това добавяне в края им изглежда неестествено. А и предпочитаме да не си променяме данните in-place, особено ако е в резултат на страничен ефект на друго наше действие. Може да видиш разликата между двата метода тук: https://ruby-doc.org/core-2.2.0/String.html#method-i-2B
  • Името на тази променлива е малко особено - не е фатално да изпишеш целите думи, например conversion_function_key, ако в замяна ще получиш по-четим код. В Ruby (а и не само) като цяло предпочитаме кодът да прилича повече на естествен език, отколкото да "икономисаме" някой символ дължина на сорса.
  • Малко особено изглеждат имената на ключовете - за предпочитане е да използваме snake_case, например f_to_k.

Също, конвертираш стринга до символ, за да може да достъпваш елементите в хеша, които са с ключове символи. В случая не е фатално вместо това директно да дефинираш хеша така, че ключовете да са стрингове. Въпреки, че така ще се наложи да ползваш ракетки вмсрто двуеточия, ще е по-лесно да се достъпват данните в него по-надолу в кода.

+ conversion_functions[conv_func_key].call(degree)
+end
+
+def melting_point_of_substance(substance, degree_unit)
+ substances_melting_points = {
+ water: 0,
+ ethanol: -114,
+ gold: 1064,
+ silver: 961.8,
+ copper: 1085
+ }
+ convert_between_temperature_units(
+ substances_melting_points[substance.to_sym], 'C', degree_unit
+ )
+end
+
+def boiling_point_of_substance(substance, degree_unit)
+ substances_boiling_points = {
+ water: 100,
+ ethanol: 78.37,
+ gold: 2700,
+ silver: 2162,
+ copper: 2567
+ }
+ convert_between_temperature_units(
+ substances_boiling_points[substance.to_sym], 'C', degree_unit
+ )
+end

Теодор обнови решението на 16.10.2016 20:50 (преди над 7 години)

-# C->K : K = C + 273.15 C = K - 273.15
-# C->F : F = C * 1.8 + 32 C = (F - 32) / 1.8
-# K->F : K = (F + 459.67) * 5 / 9 F = (K * 9 / 5) - 459.67
-def convert_between_temperature_units(degree, current_unit, wanted_unit)
- return degree if current_unit == wanted_unit
- k_to_c_diffrence = 273.15
- f_to_k_diffrence = 459.67
+K_TO_C_DIFFRENCE = 273.15
+CONVERSION_FUNCTIONS = {
+ "f_to_c" => -> (f) { (f - 32) / 1.8 },
+ "k_to_c" => -> (k) { k - K_TO_C_DIFFRENCE },
+ "c_to_f" => -> (c) { c * 1.8 + 32 },
+ "c_to_k" => -> (c) { c + K_TO_C_DIFFRENCE },
+}
- conversion_functions = {
- FtoK: -> (f) { (f + f_to_k_diffrence) * 5 / 9.to_r },
- FtoC: -> (f) { (f - 32) / 1.8.to_r },
- CtoF: -> (c) { c * 1.8.to_r + 32 },
- CtoK: -> (c) { c + k_to_c_diffrence },
- KtoC: -> (k) { k - k_to_c_diffrence },
- KtoF: -> (k) { (k * 9 / 5.to_r) - f_to_k_diffrence }
- }
-
- conv_func_key = (current_unit.upcase << 'to' << wanted_unit.upcase).to_sym
- conversion_functions[conv_func_key].call(degree)
+def convert_between_temperature_units(degree, current_unit, wanted_unit)
+ degree_buffer = CONVERSION_FUNCTIONS.fetch(
+ current_unit.downcase + '_to_c', -> (x) { x }
+ ).call(degree)
+ CONVERSION_FUNCTIONS.fetch(
+ 'c_to_' + wanted_unit.downcase, -> (x) { x }
+ ).call(degree_buffer)
end
+SUBSTANCES_MELTING_POINTS = {
+ "water" => 0,
+ "ethanol" => -114,
+ "gold" => 1064,
+ "silver" => 961.8,
+ "copper" => 1085,
+}
def melting_point_of_substance(substance, degree_unit)
- substances_melting_points = {
- water: 0,
- ethanol: -114,
- gold: 1064,
- silver: 961.8,
- copper: 1085
- }
convert_between_temperature_units(
- substances_melting_points[substance.to_sym], 'C', degree_unit
+ SUBSTANCES_MELTING_POINTS[substance.downcase], 'c', degree_unit
)
end
+SUBSTANCES_BOILING_POINTS = {
+ "water" => 100,
+ "ethanol" => 78.37,
+ "gold" => 2700,
+ "silver" => 2162,
+ "copper" => 2567
+}
def boiling_point_of_substance(substance, degree_unit)
- substances_boiling_points = {
- water: 100,
- ethanol: 78.37,
- gold: 2700,
- silver: 2162,
- copper: 2567
- }
convert_between_temperature_units(
- substances_boiling_points[substance.to_sym], 'C', degree_unit
+ SUBSTANCES_BOILING_POINTS[substance.downcase], 'c', degree_unit
)
end