What it does

  • Converts melting point and boiling point from degrees celsius to kelvin
  • These are in a dict which is in a tuple as no changes should be made to it
  • No user input


Learning exercise to understand classes and OOP

What I need help with

  • Is this how you do classes?
  • Is this correct OOP?
  • Suggest any improvements?


from typing import Dict

class ConvertToKelvin:
    def __init__(self, substance: str, data: Dict[str, int]):
        self.substance = substance
        self.data = data

    def to_kelvin(self, celsius: int) -> int:
        return celsius + 273

    def __str__(self):
        sub = self.substance
        mp = self.to_kelvin(self.data["mp"])
        bp = self.to_kelvin(self.data["bp"])
        return f'{sub}:\n mp: {mp}K\n bp: {bp}K\n'

data = (
            'bp': 0,
            'mp': 100
           'bp': 30,
           'mp': 120

print('\n'.join(str(i) for i in data))


 mp: 373K
 bp: 273K

 mp: 393K
 bp: 303K
  • \$\begingroup\$ to_kelvin(self, celsius: int) seems more like a general utility function rather than a method related to or acting on ConvertToKelvin. If this was more integrated, I might expect ConvertToKelvin to have a property celsius similar to substance and that one would get the converted value via to_kelvin(self). \$\endgroup\$
    – JonSG
    Commented Jun 14, 2021 at 17:08
  • \$\begingroup\$ That’s right, it’s because I’m so used to just using functions to do things having a hard time grasping OOP as for some things I just don’t get how they can be used as a ‘blueprint’ \$\endgroup\$
    – Nickotine
    Commented Jun 14, 2021 at 19:21
  • \$\begingroup\$ Is bp = "boiling point" and mp = "melting point"? Do you have those switched? \$\endgroup\$
    – Teepeemm
    Commented Jun 15, 2021 at 0:04

2 Answers 2

  • ConvertToKelvin sounds like a method (it's a verb), when you actually need a noun
  • You're actually capturing two different things - a temperature, and a substance
  • The figure of 273 is incorrect and should actually be 273.15
  • Avoid dictionaries for the purposes of internal state representation
  • These are simple enough that a dataclass is well-suited, and should be immutable given the nature of your data hence why frozen is set
  • Your use of int should probably be float instead. Temperatures are not discrete values.


from dataclasses import dataclass

class Temperature:
    celsius: float

    def kelvin(self) -> float:
        return self.celsius + 273.15

    def __str__(self):
        return f'{self.kelvin} K'

class Substance:
    name: str
    melt: Temperature
    boil: Temperature

    def __str__(self):
        return (
            f' melt: {self.melt}\n'
            f' boil: {self.boil}\n'

substances = (
        '2-methylobenzenol (o-cresol)',

print('\n'.join(str(i) for i in substances))
  • \$\begingroup\$ Thank you, I used your last answer as a base to get familiar with classes and also to understand what you done which was impressive as all the guides deal only with user input like setting a value manually. There’s just one thing I don’t get how would you implement this as a ‘blueprint’? Thanks for correcting me on the precise value of converting to K, since you seem to be a man who loves precision, I think it’s just K Rather than degrees K :) but it was a good point for using a float thanks again \$\endgroup\$
    – Nickotine
    Commented Jun 14, 2021 at 19:19
  • \$\begingroup\$ You're right; I never knew that! Per Wikipedia, Unlike the degree Fahrenheit and degree Celsius, the kelvin is not referred to or written as a degree. \$\endgroup\$
    – Reinderien
    Commented Jun 14, 2021 at 19:53
  • \$\begingroup\$ As for a "blueprint", there's a large collection of strategies for class representation in Python and which to use varies widely based on circumstance. \$\endgroup\$
    – Reinderien
    Commented Jun 14, 2021 at 19:58
  • \$\begingroup\$ I’m just curious how you know some of the stuff you come out with, can’t find any guides that show the cool things you’ve shown me \$\endgroup\$
    – Nickotine
    Commented Jun 14, 2021 at 21:11
  • 1
    \$\begingroup\$ Stop using dicts. Don't name a class Calculate - that's the name of a method (verb), not a class (noun) \$\endgroup\$
    – Reinderien
    Commented Jun 18, 2021 at 0:07

Very nice question and great use of types! Let us step through your questions one at a time

Is this how you do classes

I would argue no, but let us take a step back and look at how brilliant classifies as a class:

In object-oriented programming, a class is a blueprint for creating objects (a particular data structure), providing initial values for state (member variables or attributes), and implementations of behavior (member functions or methods).

The user-defined objects are created using the class keyword. The class is a blueprint that defines a nature of a future object. An instance is a specific object created from a particular class. Classes are used to create and manage new objects and support inheritance—a key ingredient in object-oriented programming and a mechanism of reusing code. enter image description here

So my problem with your class is that it is really not describing an object is it? It is really describing a function (please convert my temperature from X to Y).

Is this correct OOP?

As mentioned above I would not use classes in the way you are using them from a design standpoint. However, your implementation seems good. You are using types and overall it looks good.

Suggest any improvements?

Ok. So if ConvertToKelvin does not describe an object, what would? Something that comes to my mind is Kelvin, Celsius or even Temperature

Something like ought to do the trick

class Celsius:
    absolute_zero = -273.15

    def __init__(self, temperature=0):
        self.temperature = temperature

    def to_fahrenheit(self):
        return (self.temperature * 1.8) + 32

    def to_kelvin(self):
        return self.temperature - self.absolute_zero

    def temperature(self):
        return self._temperature_C

    def temperature(self, value):
        if value < self.absolute_zero:
            raise ValueError(f"Temperature below {self.absolute_zero} is not possible")
        self._temperature_C = value
        self._temperature_F = self.to_fahrenheit()
        self._temperature_K = self.to_kelvin()

    def __str__(self):
        return f"""Temperature:
  Celcius: {self._temperature_C}
  Fahrenheit: {self._temperature_F}
  Kelvin: {self._temperature_K} 

The @property lets us even raise an error if the temperature is not valid. As can be seen by running something like

    outside = Celsius(50)
    outside.temperature = 25
    # outside.temperature = -300
    # print(outside)
  • \$\begingroup\$ You’re right because all I really know are functions, I just thought how the hell can this be a blueprint for something but I seen some people using classes where I would just use functions, thanks a lot for the tips :) I’m starting to get it more now \$\endgroup\$
    – Nickotine
    Commented Jun 14, 2021 at 19:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.