Can you edit a .py script from another? - python

I'm creating a similarity program that calculates the euclidean distance of images, I'm looking for user input so that if they want to use a portion of the code, they can choose so. in that case, a line (specifically 13 in dc2.py) needs to be changed to " ". How can i go about this?
I've attempted using the open function alongside .write, opening a file though open(dc.py).read(), and to no avail.
This converts the image into an array (program dc2.py):
import numpy as np
import imageio
from numpy import array
img = imageio.imread("Machine Screw.jpg")
data = array(img)
with open('test2.txt', 'w') as outfile:
np.savetxt(outfile, data_slice, fmt='%-7.2f')
exec(open("Halfer.py").read())
Here's the failed code to change the previous .py:
inp = input("Want to use halfer?: ")
if inp == 'y':
the_file = open('dc2.py', 'a')
the_file[13].write(' ')
--------------------------------------
I expected:
Process finished with exit code 0
here's what actually happened:
Traceback (most recent call last):
File "C:/Users/User/Desktop/PySimCode/Resources/Ini.py", line 5, in <module>
the_file[13].write(' ')
TypeError: '_io.TextIOWrapper' object is not subscriptable
Thank you for all the help!

Your solution what you want to implement is not too "Pythonic". In my opinion you should import dc2.py file as module to Ini.py script and use parameters based on user-input to manipulate the behavior of dc2.py script.
For example:
dc2.py
import numpy as np
import imageio
import subprocess
from numpy import array
def image_converter(halfer_needed=True):
img = imageio.imread("Machine Screw.jpg")
data = array(img)
with open('test2.txt', 'w') as outfile:
np.savetxt(outfile, data, fmt='%-7.2f')
if halfer_needed:
sp = subprocess.Popen(["python", "Halfer.py"]) # Call Halfer.py script
ret_stdout, ret_stderr = sp.communicate() # These variables contain the STDOUT and STDERR
ret_retcode = sp.returncode # This variable conains the return code of your command
I think you want to call the Halfer.py script if user wants it so I have used the subprocess module to call this script as you can see above. You can see more details and options about this module: https://docs.python.org/3/library/subprocess.html
Ini.py
from dc2 import image_converter # Import your function from "dc2.py" script
inp = str(input("Want to use halfer?: "))
if inp == 'y':
image_converter(halfer_needed=False)
image_converter() # you don't need to define the keyword argument because the default value is True.

Try this:
inp = raw_input("Want to use halfer?: ")
if inp == 'y':
origin_file = open('dc2.py','r').readlines()
the_file = open('dc2.py','w')
origin_file[12] = '\n'
for line in origin_file:
the_file.write(line)
the_file.close()
Some notes I'd like to add:
input reads a block of text and parses it. You should probably always use raw_input.
open does different things, depending on the mode parameter. In my case, I used r for reading, then w for writing. (I don't think there's a way to read and write on the same <open> object). a is append, which only lets you add lines. Read here
To get the contents from an <open>, use .read() or .readlines().
The 13th line is index 12. Also, I changed it to '\n' instead of ' '.
Don't forget to call .close() on your <open> when you are done with it!
Hope this works for you!

You can, but you shouldn't.
You are trying to activate some code based on uer imput, this is doable encapsulating the code in functions, that you can import and axecute based on a condition.
You are trying to achieve this result by reading files and executing them manually, basically you are doing what the Python interpreter should do..
First, you need to chage you modules to something that activates at will, not as soon as the file is loaded, for instance your dc2.py would look like this:
import numpy as np
import imageio
from numpy import array
import Halfer # <- here you import the py file, not open and read
def run(use_halfer):
img = imageio.imread("Machine Screw.jpg")
data = array(img)
with open('test2.txt', 'w') as outfile:
np.savetxt(outfile, data_slice, fmt='%-7.2f')
if use_halfer:
Halfer.run()
..and your Halfer.py file should look like this:
def run():
# ..all your Halfer.py code here inside the run function
..and then your starting point of the script can look like:
import dc2
inp = input("Want to use halfer?: ")
dc2.run(inp == 'y') # <- here you tell dc2 to use halfer or not.

Related

import python module when launching from VBA

It is the first time I write as I really didn't find any solution to my issue.
I want to allow my user to launch some Python program from Excel.
So i have this VBA code at some point:
lg_ErrorCode = wsh.Run(str_PythonPath & " " & str_PythonArg, 1, bl_StopVBwhilePython)
If lg_ErrorCode <> 0 Then
MsgBox "Couldn't run python script! " _
+ vbCrLf + CStr(lg_ErrorCode)
Run_Python = False
End If
str_PythonPath = "C:\Python34\python.exe C:\Users\XXXX\Documents\4_Python\Scan_FTP\test.py"
str_PythonArg = "arg1 arg2"
After multiple testing, the row in error in Python is when I try to import another module (I precise that this VBA code is working without the below row in Python):
import fct_Ftp as ftp
The architecture of the module is as follow:
4_Python
-folder: Scan_FTP
- file: test.py (The one launch from VBA)
-file: fct_Ftp.py
(For information, I change the architecture of the file, and try to copy the file at some other position just to test without success)
The import has no problem when I launch Test.py directly with:
import sys, os
sys.path.append('../')
But from VBA, this import is not working.
So I figured out this more generic solution, that dont work as well from Excel/VBA
import sys, os
def m_importingFunction():
str_absPath = os.path.abspath('')
str_absPathDad = os.path.dirname(str_absPath)
l_absPathSons = [os.path.abspath(x[0]) for x in os.walk('.')]
l_Dir = l_absPathSons + [str_absPathDad]
l_DirPy = [Dir for Dir in l_Dir if 'Python' in Dir]
for Dir in l_DirPy:
sys.path.append(Dir)
print(Dir)
m_importingFunction()
try:
import fct_Ftp as ftp
# ftp = __import__ ("fct_Ftp")
write += 'YAAAA' # write a file YAAAA from Python
except:
write += 'NOOOOOO' # write a file NOOOOO from VBA
f= open(write + ".txt","w+")
f.close()
Can you please help me as it is a very tricky questions ?
Many thanks to you guys.
You are able to start your program from the command line?
Why not create a batch file with excel which you then start in a shell?

How to get CPU serial number on Windows using Python?

I wrote a program in Python-3.6.2 on Windows 10. I want get the CPU serial number.
Here is my code:
def getserial():
# Extract serial from cpuinfo file
cpuserial = "0000000000000000"
try:
f = open('/proc/cpuinfo','r')
for line in f:
if line[0:6]=='Serial':
cpuserial = line[10:26]
f.close()
except:
cpuserial = "ERROR000000000"
return cpuserial
print(getserial())
When I run the program, it prints: ERROR000000000.
How do I fix it?
Your code doesn't let any exception raised. So, you don't see the error: There is no '/proc/cpuinfo' file on Windows.
I have rewrite your code like that:
def getserial():
# Extract serial from cpuinfo file
with open('/proc/cpuinfo','r') as f:
for line in f:
if line[0:6] == 'Serial':
return line[10:26]
return "0000000000000000"
First, I have a with statement to use the file context manager: whenever an exception is raised or not, your file will be closed.
And I simplify the loop: if it found a "Serial" entry, it returns the value.
EDIT
If you have python with a version >= 2.6 you can simply use
import multiprocessing
multiprocessing.cpu_count()
http://docs.python.org/library/multiprocessing.html#multiprocessing.cpu_count
EDIT2
The best solution I found to get the "cpuinfo" is with the py-cpuinfo library.
import cpuinfo
info = cpuinfo.get_cpu_info()
print(info)
But, I think that "Serial" entry is not standard. I can't see it on classic systems.

Using Scanner to print lines from file

Im trying to read a file using a scanner then have my program print the first line of the file then looping over each other individual line throughout the file and printing them as well. This issue is I cant even get it to print a single line from the first file. And I'm not receiving an error so I cant figure out the issue
import sys
import scanner
def main():
log1 = (sys.argv[1])
log2 = (sys.argv[2])
def readRecords(s):
s = Scanner("log1")
print (log1)
main()
I will go out on a limb here and suggest something like:
import sys
import scanner
def readRecords(log):
s = scanner.Scanner(log)
print s.SomeAttribute
def main():
log1 = (sys.argv[1])
log2 = (sys.argv[2])
readRecords(log1)
readRecords(log2)
main()
Your original code has numerous problems though, least of which you are never calling your readRecords function. You are also never defining/importing Scanner, and you are doing nothing with the s variable that you are assigning to (unless merely creating a Scanner object has the desired side-effect).

IndexError: list index out of range [Python]

I've got this piece of code that calculates both the MD5 and SHA1 value of a given file and presents it in the console. It does its job, however i get the error message:
Traceback (most recent call last):
File "C:\Program Files (x86)\Aptana\workspace\Ipfit5\Semi-Definitief\test6.py",
line 64, in <module>
hash_file(woord)
File "C:\Program Files (x86)\Aptana\workspace\Ipfit5\Semi-Definitief\test6.py",
line 29, in hash_file
hash_file(sys.argv[1]);
IndexError: list index out of range
the code looks as following:
import sys, hashlib, os
def hash_file(filename): #Calculate MD5 and SHA1 hash values of a given file
# Create hash objects for MD5 and SHA1.
md5_hash = hashlib.md5()
sha1_hash = hashlib.sha1()
filename = r"C:/this.png"
# Read the given file by 2K blocks. Feed blocks
# into into the hash objects by "update(data)" method.
fp = open(filename,'rb')
while 1:
data = fp.read(2048)
if not data:
break
else:
md5_hash.update(data)
sha1_hash.update(data)
fp.close()
print "The MD5 hash of your file is"
print filename,":", md5_hash.hexdigest();
print "The SHA1 hash of your file is"
print filename,":", sha1_hash.hexdigest();
if __name__ == '__main__':
hash_file(sys.argv[1]);
hash_file(woord)
I call the function for (woord) because that is something defined later on in the script, but it is basically the same image as filename in the function hash_file(filename).
Why do i get this error when it does show me both the hash values and how do i get rid of it ?
EDIT: I know it has somethin to do with the if name == 'main':
hash_file(sys.argv[1]); but i can't figure it out.
Any help is greatly appreciated
There is something wrong with that piece of code, the "if name == 'main':" statement, means that the code inside the "if" only work when the python code is executed and not when it is used as a module.
But inside the "if", a recursive call: hash_file(sys.argv[1]) is used, it means that the code needs an argument, but it will start a infinite recursive loop.
I think that the code:
if __name__ == '__main__':
hash_file(sys.argv[1]);
goes outside the hash_file() function
I think this will work as you want:
import sys, hashlib, os
def hash_file(filename): #Calculate MD5 and SHA1 hash values of a given file
# Create hash objects for MD5 and SHA1.
md5_hash = hashlib.md5()
sha1_hash = hashlib.sha1()
filename = r"C:/this.png"
# Read the given file by 2K blocks. Feed blocks
# into into the hash objects by "update(data)" method.
fp = open(filename,'rb')
while 1:
data = fp.read(2048)
if not data:
break
else:
md5_hash.update(data)
sha1_hash.update(data)
fp.close()
print "The MD5 hash of your file is"
print filename,":", md5_hash.hexdigest();
print "The SHA1 hash of your file is"
print filename,":", sha1_hash.hexdigest();
# other code here
if __name__ == '__main__':
#hash_file(sys.argv[1]);
hash_file(woord)
When running the file, you have to give an extra argument:
$ python myfile.py argument
If you print sys.argv, you will get something like:
['myfile.py`]
But once adding an extra argument, you can get something like:
['myfile.py', 'argument']
And that is what the [1] accesses.
As you know the code more than me, you'll have to figure out what the script is expecting as an argument.

Python: How to ignore # so that the line is not a comment?

I'm having trouble using a config file, because the option starts with #, thus python treats it as a comment (like it should).
The part of the config file that is not working:
[channels]
#channel
As you may see, it's an IRC channel, that is why it needs the #. Now I could use some ugly method of adding the # everytime I need it, but I'd prefer to keep it clean.
So is there any way to ignore this? So that when I were to print the option, it would start with
If your setting that in a python file you can escape the # with \
Otherwise I think that should be in a config file with other syntax that doesn't treat # as a commented line
You are probably using ConfigParser - which you should mention btw - then you have to pre-/postprocess the configfile before feeding it to the parser, because ConfigParser ignores the comment-parts.
I can think of two ways, both of them make use of the readfp, instead of the read-method of the ConfigParser-class:
1) subclass StreamWriter and StreamReader from the codecs-module and use them to wrap the opening-process in a transparent recoding.
2) use StringIO from the io module like:
from io import StringIO
...
s = configfile.read()
s.replace("#","_")
f = StringIO(unicode(s))
configparser.readfp(f)
And if you don't have to use an "ini"-file syntax take a look at the json module. I use it more often then the ini-file for configuration, especially if the config-files shouldn't be manually edited by simple users.
my_config={
"channels":["#mychannel", "#yourchannel"],
"user"="bob",
"buddy-list":["alice","eve"],
}
import json
with open(configfile, 'rw') as cfg:
cfg.write(json.dumps(my_config))
ConfigParser has no way to not ignore lines beginning with '#'.
ConfigParser.py, line 476:
# comment or blank line?
if line.strip() == '' or line[0] in '#;':
continue
No way to turn it off.
In your defense ConfigParser is letting you make this mistake:
import sys
import ConfigParser
config = ConfigParser.RawConfigParser()
config.add_section('channels')
config.set('channels', '#channel', 'true')
config.write(sys.stdout)
Produces this output:
[channels]
#channel = true
However you can give section names that start with a # like so:
import sys
import ConfigParser
config = ConfigParser.RawConfigParser()
config.add_section('#channels')
config.set('#channels', 'channel', 'true')
config.write(sys.stdout)
with open('q15123871.cfg', 'wb') as configfile:
config.write(configfile)
config = ConfigParser.RawConfigParser()
config.read('q15123871.cfg')
print config.get('#channels', 'channel')
Which produces the output:
[#channels]
channel = true
true

Categories

Resources