Issue With Math Function Called From Another File - python

I'm currently working on a unit conversion calculator, and wanted to make it smoother by calling the math functions from a different file. Currently, Celsius -> Fahrenheit (CF) is put in 'func.py', like this:
# This file has all the math functions that get called by main.py when needed.
# Also, VARIABLES!
num = 0
typ = 0
def CF():
tota = (num * 9/5) + 32
print("Answer: " + str(tota) + " degrees Fahrenheit")
And the code to call it in main.py looks like this:
if (typ == str('C-F')):
num = int(input("Enter the temperature in Celcius: "))
num = num
CF()
I figure that I imported something wrong, but I've edited the import function several times now. I'm not looking for some type of complete correction, I wish for somebody to tell me what I did wrong, so that I can fix it. I used repl.it, if it helps. Even if someone can tell me that it's possible, it'll help.
I couldn't find anything on websites like GeeksforGeeks, which is my main source on research.

This is very odd:
def CF():
You're relying on num being defined at module scope within its module.
Much better to spell it this way, so you're passing in an argument:
def cf(num):
Over in main.py you're doing this, which isn't helpful:
num = num
Much better to pass it in:
cf(num)
The big concept you've been missing is you have two different modules,
and each one has a num variable.
They are different.
Changing one won't automatically affect the other.
Use function parameters instead.

You need to work with function parameters and returns (see this for a tutorial).
# func.py
def CF(num):
return (num * 9/5) + 32
# main.py
if (typ == str('C-F')):
num = int(input("Enter the temperature in Celcius: "))
tota = CF(num)
print("Answer: " + str(tota) + " degrees Fahrenheit")

Related

I need suggestions to fix my python code's bug that involves trying to find watt_hours and amp_hours?

I am very new to programming in python and in general. I am currently trying to practice writing a program for an upcoming project with solar power. I need to be able to enter volts, watts, and amps to calculate amp-hours and watt-hours while having one unknown variable. I would like some suggestions to make my code better and to fix the bugs I have.
I use a -1 in my code when it asks for input for amps, volts, and watts as a way to show an unknown variable. When I know watts and volts and I don't know amps the program runs fine to calculate watt_hours and amp_hours. However, when I enter a -1 for an unknown variable for watts or volts my amp_hours and watt_hours become negative, which is not a real value. I could use suggestions on making this simple program run smoother without any bugs. Any suggestions help! I got stuck on what to do next, but I would like to be able to see how more experienced programmers would approach this slight issue.
FYI: This program is used for a solar build for a campervan:
**My code:**
#defining watts amps volts, amps-hours, and watt-hours.
def watts_calc(x, y):
return amps * volts
def amps_calc(x, y):
return watts/volts
def volts_calc(x, y):
return watts / amps
def amp_hour(x, y):
return amps * hours
def watt_hour(x, y):
return watts * hours
#How many appliances are used in the Van
appliance_number = int(input("How many appliances are you trying to use? "))
#Setting up conditional arguments for while loop
condition = 1
while condition <= appliance_number:
#Defining varibles
amps = float(input("How many Amps does the device use: "))
volts = float(input("How many Volts does the device use: "))
watts = float(input("How many Watts is used: "))
hours = float(input("How many hours of use? "))
print("\n")
#a if/elif statement that takes input of watts, volts, amps in
#to calculate the missing variable indicated by -1
if amps == -1:
print("Amps are: " + str(amps_calc(watts, volts)) + "A")
elif volts == -1:
print("Volts are: " + str(volts_calc(watts, amps)) + "v")
elif watts == -1:
print("Watts are: " + str(watts_calc(amps, hours)) + "W")
else:
print("Invalid Input")
print("Watt-hours for appliance " + str(condition) + ": " + str(watt_hour(watts, hours)))
print("Amp-hours for appliance " + str(condition) + ": " + str(amps_calc(watts, volts) * hours) + "\n")
condition += 1
The problem is that where you have a -1 for an unknown value, you are just printing out what the value should be, but you are not actually updating it for the subsequent calculations. Save the result in the relevant variable, and it should be fine.
if amps == -1:
amps = amps_calc(watts, volts)
print("Amps are: " + str(amps) + "A")
elif volts == -1:
volts = volts_calc(watts, amps)
print("Volts are: " + str(volts) + "v")
elif watts == -1:
watts = watts_calc(amps, hours)
print("Watts are: " + str(watts) + "W")
Someone else's answer spotted an additional problem, which while not the main source of your issue, also needs correcting. That answer has for some reason since been deleted, so I'll mention it here myself. In your functions you are ignoring the x and y parameters in the function and are instead using variables from the outer scope. Whilst you happen to get away with that in this case, it clearly needs fixing also. For example,
def watts_calc(x, y):
return amps * volts
should be:
def watts_calc(amps, volts):
return amps * volts
Then amps and volts will be function parameters rather than variables used from the outer scope. (You could also use x and y but the meanings are then less clear.)
first of all you might want to store those numbers in variables in the methods, you could instead of having them input a number, have them put in a char for each metric they want to use, or one char for the metric they want to find, then just have list of those chars and use for loops, or you could experiment with lamdba instead of using standars syntax for thos functions
It seems like the only way you would have a negative value is if you have multiple inputs that are negative. However, it seems like you wish to only allow one variable to be unknown. Let me know if this isn't the case.
There are a few ways to approach this. One way is to reformat your code to ask for which calculation the user wishes to do and then prompt for values accordingly.
Another would be to use assert within your functions or to check whether one of the values is negative with an if statement.
You may also wish to combine both of these.
Let me know if you have any follow-up questions.

How to import external python file to another python file?

I would like to import one python file into another and then compile the main file. How can I do this?
MWE: Suppose I would like to calculate factorial of a positive integer. It can be done successfully by the following way:
n=5
fact = 1
if n < 0:
print("Sorry, factorial does not exist for negative numbers")
elif n == 0:
print("The factorial of 0 is 1")
else:
for i in range(1,n + 1):
fact = fact*i
print "%d!=%d"%(n,fact)
But I would like to create a secondary file say "auxfile.py" containing:
fact = 1
if n < 0:
print("Sorry, factorial does not exist for negative numbers")
elif n == 0:
print("The factorial of 0 is 1")
else:
for i in range(1,n + 1):
fact = fact*i
print "%d!=%d"%(n,fact)
And another main file say "main.py" containing:
print "Required factorial is given below:"
for n in range(30):
import auxfile.py
How can I do this?
Note: I know defining a function the whole process can be done in a single file. But I have to do a large program where I would like to apply this process.
Simple, just use the import method. To make your life easier simply copy the .py file you would like to import to the same folder that the file you want to import the other code file into is in.
E.g if you wanted to import happy.py to sad.py simply do:
import happy
This would give the following traceback (look at example below):
Hello
Although, this will instantly run everything outside of any def loops in the .py file. Therefore, if you wanted to run a single def loop in the file, then use the following code:
Example contents of happy.py:
print("Hello")
def okay():
print("okay")
If you did:
happy.okay()
This would give you the following traceback:
Hello
okay
TIP FOR YOUR CODE IN MAIN.PY:
You did:
print "Required factorial is given below:"
whereas you forgot the brackets. You should use: print("Required factorial is given below:") This will avoid future errors!
Hope this helps!
you can do it like this:
auxfile.py
def factorial(n):
fact = 1
if n < 0:
print("Sorry, factorial does not exist for negative numbers")
elif n == 0:
print("The factorial of 0 is 1")
else:
for i in range(1,n + 1):
fact = fact*i
print "%d!=%d"%(n,fact)
in your main.py :
from auxfile import factorial
print "Required factorial is given below:"
for n in range(30):
factorial(n)
If you're trying to avoid using a function--maybe you could wrap your entire code in the for loop? If it is not as simple as a for-loop, maybe you could copy your main code into the other file above it.
For example:
Before:
file1: "Your main code that wants to call the code below"
file2: "Your code that is too cumbersome to convert to a function"
After:
file1:
"Your main code that wants to call the code below"
for n in range(30):
"Your code that is too cumbersome to convert to a function"
There's still quite an ugly solution, which is to use the exec built-in function.
First of all, you read the code from your file:
with open("auxiliary.py", 'r') as f:
content = f.readlines()
Then you filter out the lines you don't want, so that content is a string containing your Python code, that is:
# The following evaluates to True
content == 'fact = 1\nif n < 0:\n print("Sorry, factorial does not exist for negative numbers")\nelif n == 0:\n print("The factorial of 0 is 1")\nelse:\n for i in range(1,n + 1):\n fact = fact*i\n print "%d!=%d"%(n,fact)'
Then you can just call the exec function, which will act as if the lines were included in lieu of the call of the function:
exec content # Or exec(content), both seems to work in Python 2.7
See here for a further explanation.
Note that you will have access to fact and every other variables, just as if you had written these lines in your main file.
Be aware that this might get dangerous: if you don't formally identify which lines to execute (like, put a comment as an identifier, or if the auxiliary file never changes), you may end up running some code from your auxiliary file you dont want to.

How do I package two functions into a module?

I have two functions for newtons method to estimate roots of a number that the user inputs, but I am tasked with "packaging these functions into a module". I admit I am struggling to wrap my head around the concept of modules and can't really find any material that helps me.
Have tried saving the functions separately as two different files and using the import command but can't seem to find any success.
[Edit] Trying to get the previous_x to not display once the final estimation established.
[Edit2] Still "None" appears for previous_x
def newtons_fourth(y):
x=1
N=0
previous_x = None
while N < 50:
x=1/4*(3*(x) + y/(x**3))
N=N+1
print('Iteration number:',N)
print('Estimation:',x)
print('Previous x:',previous_x)
print()
if previous_x is not None:
if abs(x - previous_x) < 0.0001:
final=1
print('Difference negligible')
print('Final Estimation:',x)
break
previous_x = x
if final!=1:
return previous_x
Your idea of "saving the functions separately as two different files and using the import command" is correct. Here's one way to just that:
CubedModule.py:
def newtons_cubed(y):
x=1
N=0
previous_x = None
while N < 50:
x=1/3*(2*(x) + y/(x**2))
N=N+1
print('Iteration number:',N)
print('Estimation:',x)
print('Previous x:',previous_x)
print()
if previous_x is not None:
if abs(x - previous_x) < 0.0001:
print('Difference negligible')
print('Final Estimation:',x)
return
previous_x = x
print(previous_x)
FourthModule.py:
def newtons_fourth(y):
x=1
N=0
previous_x = None
final = None
while N < 50:
x=1/4*(3*(x) + y/(x**3))
N=N+1
print('Iteration number:',N)
print('Estimation:',x)
print('Previous x:',previous_x)
print()
if previous_x is not None:
if abs(x - previous_x) < 0.0001:
final=1
print('Difference negligible')
print('Final Estimation:',x)
return
previous_x = x
if final!=1:
print(previous_x)
Then in your main module, named script.py you would import each module into separate namespaces at the top and reference them individually:
import CubedModule as cm
import FourthModule as fm
y= int(input('Enter value for estimations:'))
print()
print('Cubed root estimation:')
print()
cm.newtons_cubed(y)
print()
print('Fourth root estimation:')
print()
fm.newtons_fourth(y)
So yes this gets confusing when you start, I am with you on that. So let me make it super easy.
Functions def in python are containers with code in it. They run once and complete.
Classes are instances that hold a bunch of functions (called methods) inside that can manipulate the data inside the class until the class is closed, or the program is done with the named instance.
x = Classname() #creates an instance of the class now named x
x.start() # runs the function start inside the class. Can pass variables, or use existing variables under the self. notation.
Modules are files with either functions or classes in them. ALL modules are imported.
import os
from os import getcwd #function or class inside the modeul
Then they can be called like this:
print(os.getcwd())
print(getcwd())
Any .py file can be imported. A directory can be imported if it has a file named __init__.py inside of it. The file can be empty. Then the directory name becomes the module name, and the single files are submodules imported like this:
import myfolder.mymodule
from myfolder import mymodule # the same as above
That's about as easy as I can make it. Any more questions, you need to look at the documentation. But your best bet is to experiment, doing it the wrong way until you do it the right way is the best teacher.

How to use def *insert name here* (): functions?

I'm new to python and had a question about to to use more functions in a code besides def main():
My code below works, but I am trying to add new def's to their respective areas.
So like a new def called (def calcPay():), to where the hours enter are calculated (regPay, overtimePay, and total) as 3 separate items.
&
Also add a new def called (def displayOutput():), the function would receive all three of the values from (overtimePay, regPay, and totalPay) and print the message below.
If someone could explain to me how to use new functions besides main, that would be greatly appreciated.
Thanks, here is my code:
def main():
try:
hoursWorked = float(input("How many hours did you work? "))
if hoursWorked > 40:
overtimePay = (hoursWorked - 40) * 15
regPay = 40 *10
totalPay =( overtimePay + regPay)
else:
regPay = hoursWorked * 10
overtimePay = 0
totalPay = (regPay + overtimePay)
print("You earned",'${:,.2f}'.format(regPay),"in regular pay",'${:,.2f}'.format(overtimePay),
"in overtime for a total of",'${:,.2f}'.format(totalPay))
except:
print("Sorry, that wasn't a valid number. Ending program")
main()
You can declare your functions outside of the main function declaration and then use them in the main function (or inside of other functions in the main function).
So you could do something like:
def calcPay(hours):
# Does logic
return [400, 30, 430]
def displayOutput(regPay, overtimePay, totalPay):
# Prints formatted string
def main():
hoursWorked = float(input("How many hours did you work? "))
pay = calcPay(hoursWorked)
displayOutput(pay[0], pay[1], pay[2])
main()
Have a look at these similar questions:
What does it mean to call a function?
How to correctly define a function?
Basic explanation of Python functions?
There's nothing special about the function named main. You can name functions whatever you want.
When you "call" a function you're just jumping from one block of code to another. When the function returns it goes back to the line that called it.
def something():
print('something')
def other():
print('else')
def a_value():
return 100
something()
other()
x = a_value()
print(x)
# ~~~~~ output
something
else
100
In your example a good use of a function would be to calculate the employee's pay.
def total_pay(hours_worked, hourly_rate, overtime_after=40):
base_pay = min(overtime_after, hours_worked) * hourly_rate
overtime_pay = max(0, hours_worked - overtime_after) * (hourly_rate * 1.5)
return base_pay + overtime_pay
This function allows us to define the three things that determine a worker's pay. The base_pay will be, at most, the number of hours before overtime is applied. The overtime_pay will be from 0 to "some other limit" that's not defined here. Overtime is given time and a half (1.5).

Python OOP - object has no attribute

I am attempting to learn how to program. I really do want to learn how to program; I love the building and design aspect of it. However, in Java and Python, I have tried and failed with programs as they pertain to objects, classes, methods.. I am trying to develop some code for a program, but im stumped. I know this is a simple error. However I am lost! I am hoping someone can guide me to a working program, but also help me learn (criticism is not only expected, but APPRECIATED).
class Converter:
def cTOf(self, numFrom):
numFrom = self.numFrom
numTo = (self.numFrom * (9/5)) + 32
print (str(numTo) + ' degrees Farenheit')
return numTo
def fTOc(self, numFrom):
numFrom = self.numFrom
numTo = ((numFrom - 32) * (5/9))
return numTo
convert = Converter()
numFrom = (float(input('Enter a number to convert.. ')))
unitFrom = input('What unit would you like to convert from.. ')
unitTo = input('What unit would you like to convert to.. ')
if unitFrom == ('celcius'):
convert.cTOf(numFrom)
print(numTo)
input('Please hit enter..')
if unitFrom == ('farenheit'):
convert.fTOc(numFrom)
print(numTo)
input('Please hit enter..')
Classes and objects are tools to accomplish a task -- they allow you to encapsulate data or state with a set of methods. However, your data is just a number. There is no need to encapsulate the integer, so there is no need to create a class.
In other words, don't create a class because you think you should, create a class because it makes your code simpler.
import sys
def f_to_c(x):
return (x - 32) * (5/9)
def c_to_f(x):
return x * (9/5) + 32
num_from = float(input('Enter a number to convert: '))
unit_from = input('What units would you like to convert from? ')
unit_to = input('What units would you like to convert to? ')
if (unit_from, unit_to) == ('fahrenheit', 'celsius'):
num_to = f_to_c(num_from)
elif (unit_from, unit_to) == ('celsius', 'fahrenheit'):
num_to = c_to_f(num_from)
else:
print('unsupported units')
sys.exit(1)
print('{} degrees {} is {} degrees {}'
.format(num_from, unit_from, num_to, unit_to))
Enter a number to convert: 40
What units would you like to convert from? celsius
What units would you like to convert to? fahrenheit
40.0 degrees celsius is 104.0 degrees fahrenheit
The convert object and Converter class don't serve any purpose, so the code is simpler and easier to read without them.
1.It should be
def fTOc(self, numFrom):
self.numFrom = numFrom
cTOf method has the same problem.
2.Variable numTo not defined
numTo = convert.cTOf(numFrom)
print (numTo)
You almost got it right.
There is no self.numFrom because it is your parameter. Remove the lines numFrom =self.numFrom and you will be fine.

Categories

Resources