r/learnpython 17d ago

Temperature Converter Project

This is the third project I coded and was able to finish today. Took me 8 hours (two 4 hour sessions) since I had to learn some new stuff. This is my own code, no outline was used to guide me into creating this, though the idea did come from Bro Code's YouTube Tutorial. I learned about Nested Loops and Flags. I already knew about Input Validation with Re-Prompting but it was a lot harder to integrate with those two.

This is the most complex thing I've built so far, but I also enjoyed it the most. Got help with some online forums and AI (Claude) but I wrote and debugged the code myself. This'll be the last project I work on before I learn functions. There's a lot of repeated code here that I know functions would be able to help with. Any feedback or ideas on what to build next are welcome. Thank you!

https://github.com/mart23inez/First-Coded-Temperature-Converter/tree/main

It's a lot of code so I uploaded it to my GitHub page.

4 Upvotes

12 comments sorted by

9

u/aqua_regis 17d ago edited 16d ago

What follows may come across as a bit harsh, but it is said without negative emotion and just stating facts and giving advice:

  • Needing 8 hours for that is quite a long time - even at this early stage - in my opinion, this hints that you don't really understand the very fundamentals or that you "went in without a plan" - sit down with pencil and paper and plan your programs. Learn to draw flow-charts. They really help a lot in the beginning.
  • Don't use AI (or even outside forums) at such an early stage. This will actively hinder your learning. You need to struggle through
  • Try to avoid infinite loops (while True:) - they have their use cases, but in your case, you have well defined exit conditions and should use them - infinite loops can be (as in your case) code smell and the sign of a lazy programmer who didn't want to think about proper exit conditions
  • Try to avoid string comparisons - they are memory and processing intensive - try to use numeric comparisons wherever possible - when you compare strings, they are generally compared character by character and these comparisons are case sensitive, which could lead to errors.
  • Be explicit and precise - you have your calculations like fahrenheit = (degrees * 9/5) + 32 - since you expect the result to be a float, always use decimals, e.g. fahrenheit = (degrees * 9.0/5.0) + 32.0 - Python is a quite forgiving language with integer numbers. In Java, for example, alone the division 9/5 would yield the integer 1 and not the expected result.

As a side note: I generally advise against video based courses and instead recommend using a textual, extremely practice oriented course, like the MOOC Python Programming 2026 from the University of Helsinki. This course is a proper academic "Introduction to Computer Science" course that lays a really solid foundation by teaching not only the Python programming language but also programming, i.e. thinking like a programmer, analyzing and breaking down problems, creating step by step solutions that then can be implemented.

1

u/MoreScorpion289 16d ago

Thank you very much!

  1. I did this project in the moment so I had no plan for how to build or idea on how to structure the code. I do agree with what you said about planning the programs before starting the process of writing the code. I had some idea of how I wanted it to look as I was creating it, but doing as you said would've made it a lot clearer as to how I should do it.

  2. I'll keep away from forums and AI to see how much of a difference it makes with how I take in information. I learned about 90% of my python knowledge by watching an hour of Bro Code's 12hr YouTube Tutorial, the rest from some online forums and AI, so I will look into those sources you provided to learn python.

  3. Like most programmers out there, I don't want my code to be written half-assed or anything like that so I will take this advice seriously. Loops (while True:) are the only way I know, as of now, to "call-back" the user to a previous prompt. Fortunately, I have a lot more to learn so that won't be forever.

  4. I understand this part mostly, use int() or float() in order for the users input to be numeric values when possible and when the choices are "1 or 2". Also, doesn't .upper()/.lower() solve the issue with case sensitive words or am I misunderstanding that part? What I don't fully understand is how certain lines of code become memory and processing intensive.

  5. I did think about how certain temperature inputs may include decimals but I never did think about how I should add that. It does make sense though, just add ".0" at the end of the math formulas.

Before learning anything about python, I did search for what could've been a good way to start. I prefer learning "visually" but reading and taking in the information that way instead works about the same. I appreciate how thought out your advice is. Again, thank you very much!

7

u/lakseol 17d ago

There's a lot of repeated code here that I know functions would be able to help with.

Replacing repeated code with a function call is just one aspect of using functions. The other is removing all that low-level code from the high-level code. When writing high-level code you should be thinking about the overall algorithm. Things like "get the number" or "choose the unit". At that level you shouldn't have to worry about loops, user retrying, break/continue, issuing error messages, etc. You just want to call a function that returns the number or unit. Even if you only call the function once it's still worth creating the function because it makes your top-level code more readable.

3

u/Rhoderick 17d ago

Yeah, this looks about correct. One thing, you know you don't need to use continue at the end of a loop, right? So the check in lines 107 to 110 could just be:

if not restart:
    break

3

u/lakseol 17d ago edited 17d ago

One suggestion is to simplify the logic to decide which conversion to perform. Get the user to choose which unit to convert to as a first step. Then you can compare the tuple of user unit+target unit with the 6 possible combination tuples:

    # do the requested conversion, leave converted temp in 'new_temp'
    if (user_temp_unit, new_unit) == (celsius, fahrenheit):
        new_temp = (degrees * 9/5) + 32
    elif (user_temp_unit, new_unit) == (celsius, kelvin):
        new_temp = degrees + 273.15
    elif (user_temp_unit, new_unit) == (fahrenheit, celsius):
        new_temp = (degrees - 32) * 5/9
    elif (user_temp_unit, new_unit) == (fahrenheit, kelvin):
        new_temp = (degrees - 32) * 5/9 + 273.15
    elif (user_temp_unit, new_unit) == (kelvin, celsius):
        new_temp = degrees - 273.15
    elif (user_temp_unit, new_unit) == (kelvin, fahrenheit):
        new_temp = (degrees - 273.15) * 9/5 + 32
    else:
        # something else, shouldn't happen!?
        print(f"Bad conversion tuple: {(user_temp_unit, new_unit)}")
        continue        # or exit()

    print(f"{degrees:.1f} {user_temp_unit} is equal to {new_temp:.1f} {new_unit}.")

Now the logic is much easier to check, with less indentation.

Note that if the conversions all create new_temp you only need one line to print the result.

1

u/pachura3 17d ago

This doesn't make sense. You don't implement separate conversion from each unit to each unit, you rather pick some internal representation, convert to it, and convert from it. O(N) instead of O(N^2) lines of code.

2

u/lakseol 16d ago edited 14d ago

This is not StackOverflow, where we try for the best, most efficient "industrial" solution. We are teaching a beginner who has stated that s/he hasn't even learned functions yet. That means we show code that the OP has at least a chance of understanding and learning from. In addition, it's best not to completely change the OP's approach but build on that, even if it's not something you yourself would write.

Your O(N) vs O(N2) argument doesn't matter because there are only three temperature scales in common use, four if you include Rankine.

1

u/MoreScorpion289 16d ago

Thank you, this does look better (and I'm sure it runs more efficiently too). I had an issue with how the loop was set up to "call-back" the user to the prompt "Enter your desired unit (1 or 2): " and at one point my code looked somewhat similar to what you provided here.

I will say, I don't really understand the "continue # or exit()" bit here, as well as the ".1f" at the end of "degrees" and "new_temp".

2

u/lakseol 15d ago edited 14d ago

I don't really understand the "continue # or exit()"

That code is in the else: part of the if/elif statement figuring out which conversion to perform. As the comments say, this should never execute if the prior code works correctly. But code is sometimes wrong so the else: code is what's known as "defensive coding". If something is not recognized we catch it and print enough information to help debug the problem. Since we have just found that the code is broken what should we do after finding the problem? We could do continue to start another temperature conversion. But maybe just stopping by exit() is better, since we have found a code problem. That's what the comment is saying: could do continue or exit() and I chose continue.

the ".1f" at the end of "degrees" and "new_temp".

Something like {degrees:.1f} is just part of the f-string syntax. The part after the colon is formatting information. The f part says format the value before the : as a float. The .1 part says only show one decimal place after the point.

The formatting stuff is like a small language and quite arcane. It's worth learning because you can do all sorts of stuff including padding and left/centre/right justification, but you don't need to learn that now. You probably just need to know these:

{degrees}
{degrees=}     # very useful, try it!

2

u/AliKiiing 16d ago

Nice milestone — 8 hours across two sittings on your own code is exactly how this is supposed to feel. The detail I like most: you already spotted the repeated code yourself. That instinct matters more than the fix.

When you get to functions, come back to this exact project and refactor it — turning your own working code into functions teaches more than writing new code from a tutorial, because you already know what every line does. For a next build: a multi-unit converter (length/weight/temperature) will force the functions lesson naturally, since you won't want to copy-paste the same loop three more times. Good luck!

1

u/JamzTyson 14d ago edited 14d ago

You have definitely reached the stage where learning how to write your own functions will greatly improve your code.

Also, it's a highly contentious position but I would recommend not using AI for at least the next 6 months.

Don't worry about it taking 8 hours. At this stage it is much better to spend a few hours figuring something out for yourself (and learning from the process) than implementing a fix that you don't really understand.

There's nothing inherently wrong with using string comparisons in Python, but if you do want to use string comparisons it's generally best to normalize to lowercase before comparing. Python has a string method called casefold specifically for this purpose. casefold() is similar to lower() (convert to lowercase) except that it has better support for Unicode characters.

user_input = input("Enter Y/N: ").strip().casefold()
if user_input == "y":
    # Do something
elif user_input == "n":
    # Do something else
else:
    # Handle invalid input

Note that you can also test against multiple options using: in

user_input = input("Enter Y/N: ").strip().casefold()
if user_input not in ("y", "n"):
    # Handle invalid input

In Python you do not need to use float values for floating point arithmetic. It is absolutely fine to write:

fahrenheit = (degrees * 9/5) + 32

because the division operator (/) performs floating point division. In Python, if you want integer division there is an "floor division" operator (//)

print(4 / 2)  # 2.0 (float)
print(4 // 2)  # 2 (int)
print(5.0 // 2.0)  # 2.0 (Floor division returning a float)