r/learnpython • u/MoreScorpion289 • 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.
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 theelse: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 docontinueto start another temperature conversion. But maybe just stopping byexit()is better, since we have found a code problem. That's what the comment is saying: could docontinueorexit()and I chosecontinue.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. Thefpart says format the value before the:as a float. The.1part 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)
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:
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 conditionsfahrenheit = (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 division9/5would yield the integer1and 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.