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

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

Към профила на Константин Димитров

Резултати

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

Код

def convert_between_temperature_units(temperature, current_unit, desired_unit)
case [current_unit, desired_unit]
when ['C', 'K']
temperature + 273.15
when ['K', 'C']
temperature - 273.15
when ['C', 'F']
temperature * 1.8 + 32
when ['F', 'C']
((temperature.to_f - 32) * 5) / 9
when ['K', 'F']
temperature * 1.8 - 459.67
when ['F', 'K']

Това е интересно. Харесва ми, че си използвал case и си проучил как може да се подават и други неща освен прости стойности :)

Можеш ли да се сетиш как да направиш вместо един case с комбинации да имаш два case-а с по-малко неща? Тоест вместо да правиш сметката на един път, да я направиш на две стъпки - така ще ти е много по-лесна логиката и ще имаш N + N случая вместо N * N :)

((temperature + 459.67) * 5) / 9
end
end
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}
# temperaturs are in celsuse
def melting_point_of_substance(substance, type)
if type == 'C'
MELTING_POINTS[substance.to_sym]
else
convert_between_temperature_units(MELTING_POINTS[substance.to_sym], 'C', type)
end
end
def boiling_point_of_substance(substance, type)
if type == 'C'
BOILING_POINTS[substance.to_sym]
else
convert_between_temperature_units(BOILING_POINTS[substance.to_sym], 'C', type)
end
end

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

F................

Failures:

  1) #convert_between_temperature_units can convert to the same unit
     Failure/Error: expect(actual_to_value).to be_within(0.0001).of(expected_to_value)
     ArgumentError:
       The actual value (nil) must respond to `-`
     # /tmp/d20161018-13513-19or2b/spec.rb:57:in `expect_conversion'
     # /tmp/d20161018-13513-19or2b/spec.rb:3:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:7:in `block (2 levels) in <top (required)>'

Finished in 0.0084 seconds
17 examples, 1 failure

Failed examples:

rspec /tmp/d20161018-13513-19or2b/spec.rb:2 # #convert_between_temperature_units can convert to the same unit

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

Константин обнови решението на 15.10.2016 19:28 (преди около 8 години)

+def convert_between_temperature_units(num, pas, fut)

Тези имена на аргументи за функцията не ми казват почти нищо. Важно е да си именуваме добре променливите, за да не се "губим" надолу в кода и да трябва постоянно да гледаме нагоре кое трибуквено съкращение какво точно означава. В конкретния случай, имена като temperature, current_unit, desired_unit биха били многократно по-разбираеми и кодът би бил доста по-четим. :)

+ case [pas, fut]
+ when ['C', 'K']
+ num + 273.15
+ when ['K', 'C']
+ num - 273.15
+ when ['C', 'F']
+ num * 1.8 + 32
+ when ['F', 'C']
+ ((num.to_f - 32) * 5) / 9
+ when ['K', 'F']
+ num * 1.8 - 459.67
+ when ['F', 'K']

Това е интересно. Харесва ми, че си използвал case и си проучил как може да се подават и други неща освен прости стойности :)

Можеш ли да се сетиш как да направиш вместо един case с комбинации да имаш два case-а с по-малко неща? Тоест вместо да правиш сметката на един път, да я направиш на две стъпки - така ще ти е много по-лесна логиката и ще имаш N + N случая вместо N * N :)

+ ((num + 459.67) * 5) / 9
+ end
+end
+
+MELTINGS = {water: 0, ethanol: -114, gold: 1064, silver: 961.8, copper: 1085}
+BOILINGS = {water: 100, ethanol: 78.37, gold: 2700, silver: 2162, copper: 2567}

Тук горе-долу разбирам за какво става дума от имената. Супер е че са дефинирани като константи, а не са забити в методите като локални променливи. Все пак, биха могли да се казват MELTING_POINTS и BOILING_POINTS, с цел да е по-ясно какво съдъжрат.

+# temperaturs are in celsuse
+
+def melting_point_of_substance(sub, typ)

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

+ if typ == 'C'
+ MELTINGS[sub.to_sym]

Ето тук, например, sub.to_sym е напълно криптично. Какво е sub? Substitution? Substance? Subject? Може би Submarine? Също, може да си спестиш всичките конверсии до символи по методите, като си дефинираш ключовете на хешовете като стрингове директно. Без да се притесняваш че тогава ще ти се наложи да ползваш ракетка вместо двуеточие. :)

+ else
+ convert_between_temperature_units(MELTINGS[sub.to_sym], 'C', typ)
+ end
+end
+
+def boiling_point_of_substance(sub, typ)
+ if typ == 'C'
+ BOILINGS[sub.to_sym]
+ else
+ convert_between_temperature_units(BOILINGS[sub.to_sym], 'C', typ)
+ end
+end

Явно имам проблем с именоването на променливите. Ползвах typ а не type ,зашото мислех че type e запазена дума. pas e съкратено past ;fur e съкратено от future Първоначално MELDINGS ´BOILINGS бяха със стрингове но всеки нов стринг е различен обект с различо Id и командата MELDING['water'] не намира нищо.

Ще гледам да оправя домашното навреме преди крайния срок.

Константин обнови решението на 17.10.2016 04:53 (преди около 8 години)

-def convert_between_temperature_units(num, pas, fut)
- case [pas, fut]
+def convert_between_temperature_units(temperature, current_unit, desired_unit)
+ case [current_unit, desired_unit]
when ['C', 'K']
- num + 273.15
+ temperature + 273.15
when ['K', 'C']
- num - 273.15
+ temperature - 273.15
when ['C', 'F']
- num * 1.8 + 32
+ temperature * 1.8 + 32
when ['F', 'C']
- ((num.to_f - 32) * 5) / 9
+ ((temperature.to_f - 32) * 5) / 9
when ['K', 'F']
- num * 1.8 - 459.67
+ temperature * 1.8 - 459.67
when ['F', 'K']
- ((num + 459.67) * 5) / 9
+ ((temperature + 459.67) * 5) / 9
end
end
-
-MELTINGS = {water: 0, ethanol: -114, gold: 1064, silver: 961.8, copper: 1085}
-BOILINGS = {water: 100, ethanol: 78.37, gold: 2700, silver: 2162, copper: 2567}
+
+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}
# temperaturs are in celsuse
-def melting_point_of_substance(sub, typ)
- if typ == 'C'
- MELTINGS[sub.to_sym]
+def melting_point_of_substance(substance, type)
+ if type == 'C'
+ MELTING_POINTS[substance.to_sym]
else
- convert_between_temperature_units(MELTINGS[sub.to_sym], 'C', typ)
+ convert_between_temperature_units(MELTING_POINTS[substance.to_sym], 'C', type)
end
end
-def boiling_point_of_substance(sub, typ)
- if typ == 'C'
- BOILINGS[sub.to_sym]
+def boiling_point_of_substance(substance, type)
+ if type == 'C'
+ BOILING_POINTS[substance.to_sym]
else
- convert_between_temperature_units(BOILINGS[sub.to_sym], 'C', typ)
+ convert_between_temperature_units(BOILING_POINTS[substance.to_sym], 'C', type)
end
end