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

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

Към профила на Иво Яков

Резултати

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

Код

MELTING_POINTS = {
'water' => 0,
'ethanol' => -114,
'gold' => 1064,
'silver' => 961.8,
'copper' => 1085
}
BOILING_POINTS = {
'water' => 100,
'ethanol' => 78.37,
'gold' => 2700,
'silver' => 2162,
'copper' => 2567
}
CONVERSION_FORMULAS = {
'C to K' => ->(x) { x + 273.15 },
'C to F' => ->(x) { x * 1.8 + 32 },
'K to C' => ->(x) { x - 273.15 },
'K to F' => ->(x) { x * 1.8 - 459.67 },
'F to C' => ->(x) { (x - 32) / 1.8 },
'F to K' => ->(x) { (x + 459.67) * 5.0 / 9 }

Интересно решение с ламбдите :) Тук има възможност за подобрение - помисли как можеш да направиш преобразуванията на 2 стъпки.

В този вариант ако искаш да добавиш нова мерна единица трябва да добавиш 6 функции

}
# the following methods do not have below absolute zero checks
# and wrong input checks
def convert_between_temperature_units(value, from_unit, to_unit)
return value if from_unit == to_unit
CONVERSION_FORMULAS[from_unit + ' to ' + to_unit].call(value)
end
def melting_point_of_substance(substance, unit)
convert_between_temperature_units(MELTING_POINTS[substance], 'C', unit)
end
def boiling_point_of_substance(substance, unit)
convert_between_temperature_units(BOILING_POINTS[substance], 'C', unit)
end

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

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

Finished in 0.01255 seconds
17 examples, 0 failures

История (3 версии и 6 коментара)

Иво обнови решението на 15.10.2016 01:06 (преди над 7 години)

+# Using these hashes makes it easy to add more conversion
+# formulas and more substances to the solution
+
+# Hash with melting points of some substances
+MELTING_POINTS = {
+ 'water' => 0,
+ 'ethanol' => -114,
+ 'gold' => 1064,
+ 'silver' => 961.8,
+ 'copper' => 1085
+}
+
+# Hash with boiling points of some substances
+BOILING_POINTS = {
+ 'water' => 100,
+ 'ethanol' => 78.37,
+ 'gold' => 2700,
+ 'silver' => 2162,
+ 'copper' => 2567
+}
+
+# Hash with lambda functions representing
+# formulas for conversion from one unit to another
+CONVERSION_FORMULAS = {
+ 'C to K' => ->(x) { x + 273.15 },
+ 'C to F' => ->(x) { x * 1.8 + 32 },
+ 'K to C' => ->(x) { x - 273.15 },
+ 'K to F' => ->(x) { x * 1.8 - 459.67 },
+ 'F to C' => ->(x) { (x - 32) / 1.8 },
+ 'F to K' => ->(x) { (x + 459.67) * 5.0 / 9 }
+}
+
+# This method converts a value from one temp unit to another
+# but doesn't comply with the laws of thermodynamics
+# (no absolute zero check) and no wrong input checks
+def convert_between_temperature_units(value, from_unit, to_unit)
+ return value if from_unit == to_unit
+ CONVERSION_FORMULAS[from_unit + ' to ' + to_unit].call(value)
+end
+
+# These two methods get the values out of the tables without
+# checking for input correctness.It's easy to add new substances
+# to the hashes and the functions will give back their temps.
+def melting_point_of_substance(substance, unit)
+ convert_between_temperature_units(MELTING_POINTS[substance], 'C', unit)
+end
+
+def boiling_point_of_substance(substance, unit)
+ convert_between_temperature_units(BOILING_POINTS[substance], 'C', unit)
+end
+

Иво обнови решението на 15.10.2016 01:07 (преди над 7 години)

# Using these hashes makes it easy to add more conversion
# formulas and more substances to the solution
# Hash with melting points of some substances

М, да, очевидно. Този коментар е излишен :) Харесва ми, че си се сетил да пишеш коментари, но няма смисъл да коментираш очевидни неща. Тук името на константата е достатъчно ясно без да се налага да чета още едно изречение за него :)

MELTING_POINTS = {
'water' => 0,
'ethanol' => -114,
'gold' => 1064,
'silver' => 961.8,
'copper' => 1085
}
# Hash with boiling points of some substances
BOILING_POINTS = {
'water' => 100,
'ethanol' => 78.37,
'gold' => 2700,
'silver' => 2162,
'copper' => 2567
}
# Hash with lambda functions representing
# formulas for conversion from one unit to another
CONVERSION_FORMULAS = {
'C to K' => ->(x) { x + 273.15 },
'C to F' => ->(x) { x * 1.8 + 32 },
'K to C' => ->(x) { x - 273.15 },
'K to F' => ->(x) { x * 1.8 - 459.67 },
'F to C' => ->(x) { (x - 32) / 1.8 },
'F to K' => ->(x) { (x + 459.67) * 5.0 / 9 }

Интересно решение с ламбдите :) Тук има възможност за подобрение - помисли как можеш да направиш преобразуванията на 2 стъпки.

В този вариант ако искаш да добавиш нова мерна единица трябва да добавиш 6 функции

}
# This method converts a value from one temp unit to another
# but doesn't comply with the laws of thermodynamics
# (no absolute zero check) and no wrong input checks
def convert_between_temperature_units(value, from_unit, to_unit)
return value if from_unit == to_unit
CONVERSION_FORMULAS[from_unit + ' to ' + to_unit].call(value)
end
# These two methods get the values out of the tables without
# checking for input correctness.It's easy to add new substances
# to the hashes and the functions will give back their temps.
def melting_point_of_substance(substance, unit)
convert_between_temperature_units(MELTING_POINTS[substance], 'C', unit)
end
def boiling_point_of_substance(substance, unit)
convert_between_temperature_units(BOILING_POINTS[substance], 'C', unit)
end
-

Съжалявам, не съм сигурен дали последния ред е празен или не, защото малко не разбирам preview-то в сайта. Принципно трябва да е празен :D и също from_unit + to_unit може да го превърна в символ за да е по-хубаво написан хеша (без ракета и след нея ->), но не съм сигурен кой вариант ще е по-четим (същото и за другите 2 хеша за температурите)

Кода е доста подреден, браво! Също, много е хубаво, че си помислил за коментари, просто някои от тях са доста очевидни от самия код. Аз лично имам следния алгоритъм, когато ми се поиска да коментирам нещо:

  1. Ако има възможност - променям имената на променливи/константи/функции, така че да описват по-добре кода.
  2. Ако има възможност - изнасям код в отделна функция или променлива - името й описва кода.
  3. Мисля как да променя структурата на кода, така че да е по-ясно от кода.
  4. Ако горните три вече са изпълнени - тогава пиша коментар :)

За празния ред - предполагам говориш за новия ред на края на файла? Той не би трябвало да се вижда като празен ред.

За хеша - ползвай каквото е по-удобно за използване. В случая това е хеш със стрингове за ключове. Иначе ще трябва да викаш .to_sym

Благодаря за feedback-а
Някой от коментарите в случая не са необходими, но съм свикнал да пиша доста коментари, защото съм свикнал да пиша код за хора, които може да не го разбират изобщо.В случая даже ми е трудно да измисля коментарите, защото то просто си е ясно от кода, но аз го пиша все едно е за някой, който няма да схване за какво е тоя хеш или изобщо какво е хеш :D ще ги променя следвайки вашият алгоритъм и ще премахна част от тях за финалната версия.Относно идеята за смятането на две стъпки, замислих се и наистина стигнах до 3 възможни решения, но не съм сигурен кое или дали някое от тях би било по-добро относно четимост на кода и простота на добавяне на нови мерни единици.
Едното е да използвам този вид хеш:
CONVERSION_FORMULAS = {
'CK or KC' => ->(x, conv_select) { conv_select == 1 ? x + 273.15 : x - 273.15 },
'CF or FC' => ->(x, conv_select) { conv_select == 1 ? x * 1.8 + 32 : (x - 32) / 1.8 },
'KF or FK' => ->(x, conv_select) { conv_select == 1 ? x * 1.8 - 459.67 : (x + 459.67) * 5.0 / 9 },
}
и да повиквам от метода чрез:
key=CONVERSION_FORMULAS.keys.find{ |key| key.include? from_unit + to_unit }
if key.index(from_unit + to_unit) == 0
CONVERSION_FORMULAS[key].call(value, 1)
else
CONVERSION_FORMULAS[key].call(value, 2)
end
Второто е чрез eдин прост case, в който да слагам формулите една след друга
case fromUnit+toUnit
when "CK" then 273.15+value
when "CF" then 1.8value+32
when "KC" then value-273.15
when "KF" then value
1.8-459.67
when "FC" then (value-32)/1.8
when "FK" then (value+459.67)*5.0/9
else nil
end

А за третото просто мислих, че може превръщанията да станат като верига, например в хеша оставяме само формули за превръщане от C->K, от K->C, от F->K и от K->F и така премахваме директната връзка между фаренхайт и целзии F->C и C->F и просто влизаме в хеша с ключ който е като променливите, които сме избрали за конвертиране, например, за да конвертираме от C към F правим конвертиране от C към K и после от K към F и това цялото се извършва в един цикъл в метода и така би било по-лесно да се добави нова мерна единица Z, защото тогава ще трябва да напишем само 2 формули за връзката и само с последната мерна единица в случая F и винаги за Z ще са само две формули независимо дали сме сложили 100 мерни единици в хеша, обаче, ако имаме много мерни единици и много превръщания това би забавило бързодействието, но пък на една лекция ни казахте да не мислим толкова за бързодействие и за това се сетих и за този метод :D Не съм сигурен до колко това ще направи решението на простата ни задача по-просто, това решение би дало единствено перспектива за разширяване :D
Не съм сигурен дали да остана с този вариант за финалната версия, защото малко не схванах идеята с пресмятането на 2 стъпки и май доста се отклоних в мислите си :D

Иво обнови решението на 17.10.2016 13:40 (преди над 7 години)

-# Using these hashes makes it easy to add more conversion
-# formulas and more substances to the solution
-
-# Hash with melting points of some substances
MELTING_POINTS = {
'water' => 0,
'ethanol' => -114,
'gold' => 1064,
'silver' => 961.8,
'copper' => 1085
}
-# Hash with boiling points of some substances
BOILING_POINTS = {
'water' => 100,
'ethanol' => 78.37,
'gold' => 2700,
'silver' => 2162,
'copper' => 2567
}
-# Hash with lambda functions representing
-# formulas for conversion from one unit to another
CONVERSION_FORMULAS = {
'C to K' => ->(x) { x + 273.15 },
'C to F' => ->(x) { x * 1.8 + 32 },
'K to C' => ->(x) { x - 273.15 },
'K to F' => ->(x) { x * 1.8 - 459.67 },
'F to C' => ->(x) { (x - 32) / 1.8 },
'F to K' => ->(x) { (x + 459.67) * 5.0 / 9 }
}
-# This method converts a value from one temp unit to another
-# but doesn't comply with the laws of thermodynamics
-# (no absolute zero check) and no wrong input checks
+# the following methods do not have below absolute zero checks
+# and wrong input checks
def convert_between_temperature_units(value, from_unit, to_unit)
return value if from_unit == to_unit
CONVERSION_FORMULAS[from_unit + ' to ' + to_unit].call(value)
end
-# These two methods get the values out of the tables without
-# checking for input correctness.It's easy to add new substances
-# to the hashes and the functions will give back their temps.
def melting_point_of_substance(substance, unit)
convert_between_temperature_units(MELTING_POINTS[substance], 'C', unit)
end
def boiling_point_of_substance(substance, unit)
convert_between_temperature_units(BOILING_POINTS[substance], 'C', unit)
end