How to import external python file to another python file? - python

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.

Related

Issue With Math Function Called From Another File

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")

Python: Trying to convert string to int, get error to int invalid literal for int() with base 10: ''

I am new to Python, so I apologize if this is a simple fix. I have been stuck on a Codeval problem (Happy Numbers) for quite some time and I am not sure what is going wrong.
Problem Description:
Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1, or it loops endlessly in a cycle which does not include 1.Those numbers for which this process ends in 1 are happy, while those that do not end in 1 are unhappy.
For example:
7 is a happy number (7->49->97->130->10->1)
22 is not a happy number (22->8->64->52->29->85->89->145->42->20->4->16->37->58->89 ...)
My test input and expected outcome:
1 --> 1
7 --> 1
22 --> 0
If the number is a happy number, print out 1. If not, print out 0.
Here is the full Traceback:
Traceback (most recent call last):
File "/happy_number.py", line 58, in <module>
happy_number_check("happy_numbers.txt")
File "/happy_number.py", line 55, in happy_number_check
happy_or_not(line)
File "/happy_number.py", line 33, in happy_or_not
i = int(i)
ValueError: invalid literal for int() with base 10: ''
Here is my code:
# test = 7
def happy_or_not(number):
number = str(number)
if number == 1:
print 1
else:
new_num = 0
for i in number:
i = int(i)
if i == " ":
continue
else:
new_num += i**2
if new_num == 10 or new_num == 10:
print 1
else:
try:
happy_or_not(new_num)
except RuntimeError:
print 0
# happy_or_not(test)
def happy_number_check(file):
f = open(file, 'r+')
for line in f:
if line == "":
continue
else:
happy_or_not(line)
happy_number_check("happy_numbers.txt")
What I have already tried:
Based on what I gathered from other similar questions, the issue may be that I am not able to convert a str into an int when I hit the line i = int(i). It is my understanding that I have to convert the str type into an int type before doing any math on it, yet it looks like that is where it is failing.
I tested the happy_or_not function by itself, and it does print out the value that I expect it to. It seems like to me that the issue comes when I try and call that happy_or_not function inside of the happy_number_check function, which is reading my txt file (containing a list of numbers to test). I must not be grasping a larger principle here, so any explanations would be helpful.
This is also my first real attempt at a recursive function and there probably is a better way to structure this, so any suggestions on how to change things up to be more effective is most welcome.
Thank you in advance!
Try changing happy_number_check like this (validate each line is an integer):
def happy_number_check(file):
with open(file, 'r+') as f: # Safer way to open a file. Will automatically close for you even if something goes wrong
for line in f:
if line.strip().isdigit():
happy_or_not(line.strip())
The strip() will also make it so that you can remove this code:
if i == " ":
continue
else:
By the way, you also have a bug in your logic. You are relying on a RuntimeError - a Stack Overflow interestingly enough :-) - to terminate a test. You should really keep track of what numbers have been tried, and if you try the same number again, return 0.
Don't click this link if you don't want a straight up solution to the problem, but if you do, here is an iterative solution: http://rosettacode.org/wiki/Happy_numbers#Python

Code trouble with python

I'm having some trouble here. For my CS assignment, I have to have python take data from a file on my pc and run the data through my program.
So, this code works fine on http://repl.it/languages/Python, but not in python. I'm assuming because my line of code has some Python 2.0 lines of code? I can't seem to fix it. Can you guys help? And, another small question except this one. I have to input some code in my program to take data from a file and run it through my program as I stated above. I have this.
import math
def mean(values):
average = sum(values)*1.0/len(values)
return average
def deviation(values):
length = len(values)
m = mean(values)
total_sum = 0
for i in range(length):
total_sum += (values[i]-m)**2
root = total_sum*1.0/length
return math.sqrt(root)
def median(values):
if len(values)%2 != 0:
return sorted(values)[len(values)/2]
else:
midavg = (sorted(values)[len(values)/2] + sorted(values)[len(values)/2-1])/2.0
return midavg
def main():
x = [15, 17, 40, 16, 9]
print mean(x)
print deviation(x)
print median(x)
main()
How do I specifically have the program take data from the file and run it through my program? The data is just a bunch of numbers, by the way. It's been giving me trouble for some hours now. Thanks if you can help out.
This is what I know about the opening/closing file stuff so far
f = open("filename.txt")
data = f.readlines()
f.close()
Apparently you are using python2.x:
I'm assuming because my line of code has some Python 2.0 lines of code?
So yes, you do have a problem: In python3.x, print became a function.
Thus, your prints need to be changed:
print mean(x)
print deviation(x)
print median(x)
Becomes
print(mean(x))
print(deviation(x))
print(median(x))
Also, your part about opening and closing files is unclear.

How to put random lines from a file into a string in python?

what i want to do is write a code that has a file (in the code, no need to be input by user), and the code picks a random line from the file - whatever it is, a long line, an ip or even a word and at the end of the loop puts it into a string so i could use that in other parts of the code.
i tried using randomchoice(lines) but wasn't sure how to continue from here.
after that i tried using:
import random
def random_line(afile):
line = next(afile)
for num, aline in enumerate(afile):
if random.randrange(num + 2): continue
line = aline
return line
which also for some reason didnt work for me.
The last method you posted worked for me. Maybe you are not opening the file correctly. Here is another approach, using random.choice
import random
def random_line(f):
return random.choice([line for line in f])
f = open("sample.txt", 'r')
print random_line(f)
Edit:
Another way would be (thanks to #zhangxaochen):
def random_line(f):
return random.choice(f.readlines())
Translating another answer of mine from C:
def random_line(afile):
count = 0
kept_line = None
for line in afile:
if random.randint(0, count) == 0:
kept_line = line
count += 1
return kept_line
Edit: This appears to do the same thing as random.choice. I wonder if they use the same algorithm?
Edit 2: from the comments and a little experimentation it appears random.choice uses a different algorithm, which will be much more efficient if all of the elements are already in memory. This isn't usually the case for files unless you use readlines. There will be a tradeoff between having to keep the entire file in memory vs. having to calculate n random numbers.

.txt File Not Reading and Writing Correctly in Python 3.3.3

Anyway, I have been trying to read and write to a text file in Python 3.3.3, and it has not been working. My code is as follows:
import math
pFile=open('/Users/Username/Desktop/Programming:Design/Program Access Files/primes.txt')
pList=[]
for line in pFile:
pList=pList+(int(line.strip()))
def testPrime(num,pList):
if num<=1:
return False
testList=[]
place=0
sqrt=math.sqrt(num)-((math.sqrt(num))%1)
p=pList[place]
while p<=sqrt:
testList.append(p)
place=place+1
p=pList[place]
for i in testList:
if i%num==0:
return False
return True
print('Hello and Welcome to the Prime Finder 000!')
end=int(input('What integer would you like me to go to today?'))
for j in range(pList[-1],end+1):
if testPrime(j,pList)==True:
pList.append(j)
print(j)
pFile.close()
pFile=open('/Users/Username/Desktop/Programming:Design/Program Access Files/primes.txt','w')
for k in pList:
pFile.write(str(k))
pFile.write('\r\n')
pFile.close()
This program is supposed to search through all positive integers to find prime numbers. The text file I am trying to store found primes in is 'primes.txt', in the directory shown when I try to open it. However, something must be wrong with my method of reading the file, namely this:
pFile=open('/Users/Username/Desktop/Programming:Design/Program Access Files/primes.txt')
pList=[]
for line in pFile:
pList=pList+(int(line.strip()))
I am certain that my function for finding primes works, but they are not storing correctly. Currently, what the program does is wipes the text file 'primes.txt' and prints out every number from 2 to the number inputted by the user as a prime, in an order I haven't found yet.
Ya, as #maurelio79 and #DSM said, looks like you're reading from and writing to the same file here and you're adding an int to list...which should be impossible. Also, using with to open files is cleaner:
pList = []
with open(fle_path, 'r') as fle:
for line in fle:
pList.append(int(line.rstrip("\n")))
#find and append new primes to pList using pList.append(<new prime>)
with open(fle_path, 'a') as fle:
for item in pList:
fle.write(str(item)+"\n")
Use 'r' to read the file, 'w' to start a with a blank file every time, use 'a' to append to the existing file. You can use the same file, but use the 'a' argument to append newly found primes.
Using with statements automatically closes the file when it exists the loop.
I have (roughly) rewritten your example to show you what are considered better idioms.
First, your prime finder probably is great by I used one based on testing just a single number:
def isprime(n):
'''check if integer n is a prime'''
# make sure n is a positive integer
n = abs(int(n))
# 0 and 1 are not primes
if n < 2:
return False
# 2 is the only even prime number
if n == 2:
return True
# all other even numbers are not primes
if not n & 1:
return False
# range starts with 3 and only needs to go up the squareroot of n
# for all odd numbers
for x in range(3, int(n**0.5)+1, 2):
if n % x == 0:
return False
return True
Next, I don't know what is in your source file. Here I just took you same question of 'how far' and then show what is a better way to read and write that file:
print('Hello and Welcome to the Prime Finder 000!')
end=int(input('What integer would you like me to go to today?'))
with open('/tmp/nums.txt', 'w') as fout:
for n in range(1,end+1):
fout.write('{}\n'.format(n))
Finally, read the file in of integers 2-end and test each for primality in turn. Write the primes to a new file prime.txt:
with open('/tmp/nums.txt') as f, open('/tmp/primes.txt', 'w') as fout:
for n in f:
n=int(n)
if isprime(n):
print(n)
fout.write('{}\n'.format(n))
If you want to have a list of primes, here is how you append to the list:
primes=[]
with open('/tmp/nums.txt') as f:
for n in f:
n=int(n)
if isprime(n):
print(n)
primes.append(n)
Several things to note:
Use of with keyword to open a file. Your file will automatically close at the end.
The file is used as an iterator since there is no reason to read the entire file into memory in this case
There is no need to do int(line.strip()) for each line with a carriage return. int strips the whitespace first so int('12\r\n') works fine
pList+(int(line.strip())) is probably a TypeError since you cannot concatenate an int to a list. Use pList.append(int(line)) instead.

Categories

Resources