save print value into a text file python - python

I have this 2 program:
def calculate1():
a4canon = (int(input('A4 paper (canon):')))*8.9
a4rainbow = (int(input('A4 paper (rainbow):')))*7.5
lruler = (int(input('Long ruler:')))*0.85
sruler = (int(input('Short ruler:')))*0.55
blue = (int(input('Blue pen:')))*0.65
red = (int(input('Red pen:')))*0.65
black = (int(input('Black pen:')))*0.65
pencil = (int(input('2B Pencil:')))*2.4
total = a4canon + a4rainbow + lruler + sruler + blue + red + black + pencil
a4canon1 = str(a4canon)
a4rainbow1 = str(a4rainbow)
lruler1 = str(lruler)
sruler1 = str(sruler)
blue1 = str(blue)
red1 = str(red)
black1 = str(black)
pencil1 = str(pencil)
total1 = str(total)
return('A4 paper (canon):',a4canon1)
return('A4 paper (rainbow):',a4rainbow1)
return('Long ruler :',lruler1)
return('Short ruler:',sruler1)
return('Blue pen:',blue1)
return('Red pen:',red1)
return('Black pen:',black1)
return('Pencil:',pencil1)
return('Total:',total1)
and the other:
import calculate
def display1():
file = open('sample.txt','w')
file.write(calculate.calculate1())
display1()
The problem is that it prints:
TypeError: write() argument must be str, not tuple
Am I missing something although I have change the value into string because I want it to save into text file something like this:
A4 paper(canon):1 ~ 8.9
A4 paper(rainbow):1 ~ 7.5
Long ruler:1 ~ 0.85
Short ruler:1 ~ 0.55
Blue pen:1 ~ 0.65
red pen:1 ~ 0.65
Black pen:1 ~ 0.65
2B pencil:1~ 2.4
Total:22.149999999999995
Help and suggestion please. Thanks
it seems that when i use the:
file.write(str(calculate.calculate1()))
it only save:
('A4 paper (canon):', 8.9)

File write will accept strings only that's why you are getting the error. So when you are returning you can return like this
return("A4 paper (canon):" + str(a4canon1)) which will return a string and you can use it for file.write
or while using return value you can convert it to string
file.write(str(calculate.calculate1()))
Also in your definition,you have multiple return statements . Nothing will be executed after first return statement. Remove all your return statements and return a list of string instead of returning multiple strings
return[('A4 paper (canon):',a4canon1),('A4 paper (rainbow):',a4rainbow1),('Long ruler :',lruler1),('Short ruler:',sruler1),('Blue pen:',blue1),('Red pen:',red1),('Black pen:',black1),('Pencil:',pencil1),('Total:',total1)]
And in when capturing return value change like this
import calculate
def display1():
file = open('sample.txt','w')
lst=calculate.calculate1()
for i in lst:
file.write(" ".join(list(i)))
display1()
And also it is not advised to take inputs inside the function definition. You may need to rework on it

File.write accepts string but in your case the it returns a tuple, so instead of writing tuple to file you need to convert it into string by using str() and then write it to file.
You may want to learn more about file operations and also type conversions.
file.write(str(calculate.calculate1()))

Related

How can I extract a floating point value from a string, in python 3?

string = probability is 0.05
how can I extract 0.05 float value in a variable? There are many such strings in the file,I need to find the average probability, so
I used 'for' loop.
my code :
fname = input("enter file name: ")
fh = open(fname)
count = 0
val = 0
for lx in fh:
if lx.startswith("probability"):
count = count + 1
val = val + #here i need to get the only "float" value which is in string
print(val)
import re
string='probability is 1'
string2='probability is 1.03'
def FindProb(string):
pattern=re.compile('[0-9]')
result=pattern.search(string)
result=result.span()[0]
prob=string[result:]
return(prob)
print(FindProb(string2))
Ok, so.
This is using the regular expression (aka Regex aka re) library
It basically sets up a pattern and then searches for it in a string.
This function takes in a string and finds the first number in the string, then returns the variable prob which would be the string from the first number to the end.
If you need to find the probability multiple times then this might do it:
import re
string='probability is 1'
string2='probability is 1.03 blah blah bllah probablity is 0.2 ugggggggggggggggg probablity is 1.0'
def FindProb(string):
amount=string.count('.')
prob=0
for i in range(amount):
pattern=re.compile('[0-9]+[.][0-9]+')
result=pattern.search(string)
start=result.span()[0]
end=result.span()[1]
prob+=float(string[start:end])
string=string[end:]
return(prob)
print(FindProb(string2))
The caveat to this is that everything has to have a period so 1 would have to be 1.0 but that shouldn't be too much of a problem. If it is, let me know and I will try to find a way

replace values in a float with a string- python

I wanted to replace dot in a float with a string
for example if I have a float 15.444 I need print it something like below 15 eggs 444 chicken
If take I take a real example,here is the code
enter code here
name = "chris"
height_cm = 175
height = (height_cm * 1/2.54) * 1/12
weight = 79
print "He is %s" % name
print "His height is %.2f" %height, "inches"
print "His weight is %d" % weight
the second print line will give the output "my height is 5.7 inches" here how do I replace "." with a string. In this case I need to replace the "." with a string "feet"
++++++++++++++++++output++++++++++++++++++++++++
He is chris
His height is 5.7 inches
His weight is 79
+++++++++++++++++++output+++++++++++++++++++++++
I don't code python but you may want to do something along the line of this(java):
float input = 15.444f;
int[] split = (input+"").split(".");
System.out.println(split[0]+" eggs and "+split[1]+" chickens");
But why would you ever need to do something like this. A float is a horrible method of storage for 2 integer values. Try using an array instead.

re.sub python to gather height

I am writing a python program to parse some user data from a txt file.
One of the rows in the text file will contain the user's height.
I have specified an order that the user is expected to follow like
First line of the file should contain name, the next line, date of birth,
3rd line, height etc.
I have also given a sample file to the user which looks like this
Name: First Name Last Name
DOB: 16.04.2000
Age: 16
Height: 5 feet 9 inch
When I read the file, I looked at each line and split it using ':' as a separator.
The first field is my column name like name, dob, age, height.
In some cases, users forget the ':' after Name or DOB, or they will simply send data like:
Height 5 feet 9 inch
5 feet 9 inch
5ft 9 in
5feet 9inches
The logic I have decided to use is:
Look for ':' on each line; if one is found, then I have my field.
Otherwise, try to find out what data it could be.
The logic for height is like this:
if any(heightword in file_line.upper() for heightword in ['FT', 'HEIGHT', 'FEET', 'INCH', 'CM'])
This if condition will look for words associated with height.
Once I have determined that the line from the file contains the height, I want to be able to convert that information to inches before I write it to the database.
Please can someone help me work out how to convert the following data to inches.
Height 5 feet 9 inch
5 feet 9 inch
5ft 9 in
5feet 9inches
I know since I am trying to cater to variety of user inputs. This list is not exhaustive; I am trying to use these as an example to understand, and then I will keep adding code if and when I find new patterns.
pyparsing is a nice module for simple parsing situations like this, especially when trying to process less-than-predictable-but-still-fairly-structured human input. You can compose your parser using some friendly-named classes (Keyword, Optional, OneOrMore, and so on) and arithmetic operators ('+' for sequence, '|' for alternatives, etc.), to assemble smaller parsers into larger ones. Here is a parser built up from bits for your example (also support ' and " for feet and inches, and fractional feet and inch values too). (This sample uses the latest version of pyparsing, version 2.1.4):
samples = """\
Height 5 feet 9 inch
5 feet 9 inch
5ft 9 in
5feet 9inches
5'-9-1/2"
5' 9-1/2"
5' 9 1/2"
6'
3/4"
3ft-6-1/4 in
"""
from pyparsing import CaselessKeyword, pyparsing_common, Optional
CK = CaselessKeyword
feet_units = CK("feet") | CK("ft") | "'"
inch_units = CK("inches") | CK("inch") | CK("in") | '"'
# pyparsing_common.number will parse an integer or real, and convert to float
integer = pyparsing_common.number
fraction = integer + '/' + integer
fraction.addParseAction(lambda t: t[0]/t[-1])
qty = fraction | (integer + Optional(fraction)).addParseAction(lambda t:sum(t))
# define whole Height feet-inches expression
HEIGHT = CK("height") | CK("ht")
inch_qty = qty("inches")
feet_qty = qty("feet")
height_parser = Optional(HEIGHT) + (inch_qty + inch_units |
feet_qty + feet_units + Optional(inch_qty + inch_units))
# use parse-time callback to convert feet-and-inches to inches
height_parser.addParseAction(lambda t: t.get("feet", 0.0)*12 + t.get("inches", 0.0))
height_parser.ignore("-")
height_parser.runTests(samples)
# how to use the parser in normal code
height_value = height_parser.parseString(samples.splitlines()[0])[0]
print(height_value, type(height_value))
Prints:
Height 5 feet 9 inch
[69.0]
5 feet 9 inch
[69.0]
5ft 9 in
[69.0]
5feet 9inches
[69.0]
5'-9-1/2"
[69.5]
5' 9-1/2"
[69.5]
5' 9 1/2"
[69.5]
6'
[72.0]
3/4"
[0.75]
3ft-6-1/4 in
[42.25]
69.0 <type 'float'>
In JavaScript, there is an operation called "computed access", done as object[key], where the object property read is determined through the result of a given expression, as an alternative to the normal . operator. Personally, I mostly use it for iteration and reading properties with hyphens and stuff, but it can also be used to get associated wanted results from an input string.
So after an entire afternoon of Googling and figuring out Python syntax, etc. I was able to write a short program to do this.
import re
import string
h = 0
r = re.compile(r'(\d+)\s*(\w+)\b')
def incr( m ):
h+=m.group(1)*({'in':1,'inches':1,'inch':1,'foot':12,'feet':12,'cm':0.3937,'centimeter':0.3937,'centimeters':0.3937}[string.lower(m.group(2))]||1) # etc. etc.
return ''
re.sub(r, incr, input)
print h
You may want to restrict the keywords usable to keep the dict from getting too big.
I tried out Stephen's code in the first comment on python 3.6 and had to tweak it to work for me:
import re
h = 0
input = '5 feet 9 inches'
r = re.compile(r'(\d)\s*(\w+)\b')
measures ={'in':1,'inches':1,'inch':1,'foot':12,'feet':12,'ft':12,'cm':0.3937,'centimeter':0.3937,'centimeters':0.3937}
def incr(m):
global h
h+=int(m.group(1))*measures[m.group(2)]
return ''
re.sub(r, incr, input)
print(h)

Python formatting: How to insert blank spaces in between array data elements of data type float

I have a question regarding formatting. I am trying to extract relevant data and insert this data into a fortran file. Thankfully, I am using python to accomplish this task. It just so happens that the fortran file is sensitive to the number of spaces between text. So, this brings me to my question. My array array data looks like:
[[ -1.80251269 12.14048223 15.47522331]
[ -2.63865822 13.1656285 15.97462801]
[ -1.76966256 11.35311123 16.13958474]
[ -0.76320052 12.45171386 15.34209158]
[ -2.12634889 11.84315415 14.48020468]]
[[-14.80251269 1.14048223 1.47522331]
[ -2.63865822 13.1656285 15.97462801]
[ -1.76966256 11.35311123 16.13958474]
[ -0.76320052 12.45171386 15.34209158]
[ -2.12634889 11.84315415 14.48020468]]
[[ -0.80251269 0.14048223 0.47522331]
[ -2.63865822 13.1656285 15.97462801]
[ -1.76966256 11.35311123 16.13958474]
[ -0.76320052 12.45171386 15.34209158]
[ -2.12634889 11.84315415 14.48020468]]
These elements are floats, not strings. For example, I wanted the the first row (and every row thereafter) of the data to look like:
-1.80251269 12.14048223 15.47522331
How would I accomplish this? To be specific, there are 5 white spaces that seperate the left margin from the 1st number, -1.80251269, and 5 white spaces that seperate each of the three numbers. Notice also that I need the array brackets gone, but I suspect I can do this with a trim function. Sorry for my lack of knowledge guys; I do not even know how to begin this problem as my knowledge in Python syntax is limited. Any help or tips would be appreciated. Thanks!
EDIT: this is the code I am using to generate the array:
fo = np.genfromtxt("multlines.inp")
data=scipy.delete(fo, 0, 1)
txt = np.hsplit(data,3)
all_data = np.vsplit(data, 4)
i=0
num_molecules = int(raw_input("Enter the number of molecules: "))
print "List of unaltered coordinates:"
while i < (num_molecules):
print all_data[i]
If you are using NumPy, you can use np.savetxt:
np.savetxt('a.txt', a.reshape(15,3), '%16.8f')
To get
-1.80251269 12.14048223 15.47522331
-2.63865822 13.16562850 15.97462801
-1.76966256 11.35311123 16.13958474
...
(You need to reshape your array into 2-dimensions to do what I think you want).
If you have your data formatted as a list, then I suspect that #kamik423's answer will help you. If it if formatted as a string, you may wish to try something like the following.
def properly_format(line):
nums = line.strip(' []\t').split()
spaces = ' '
return spaces + nums[0] + spaces + nums[1] + spaces + nums[2]
lines = my_array_string.splitlines() #if your data is a multiline string
for line in lines:
formatted_line = properly_format(line)
# do something with formatted_line
Edit: forgot to split the string.
If you don't care about the length of each block you can just do
for i in whateverYouArrayIsCalled:
print str(i[0]) + " " + str(i[1]) + " " + str(i[2])
if you however want to have all the elements to be inline try
for i in whateverYouArrayIsCalled:
print (str(i[0]) + " ")[:20] + (str(i[1]) + " ")[:20] + str(i[2])
where the 20 is the length of each block
(for 2.7)
I will assume that the data array is saved in a data.txt file and you want to save the result into fortran.txt, then:
fortran_file = open('fortran.txt','w') # Open fortran.txt for writing
with open('data.txt',r) as data_file: #Open data.txt for reading
while True:
line = data_file.readline()
if not line: break # EOF
result = line.strip('[]').split()
result = " " + " ".join(result)
fortran_file.write(result)
fortran_file.close()
try this:
import numpy
numpy.set_printoptions(sign=' ')

python & pyparsing newb: how to open a file

Paul McGuire, the author of pyparsing, was kind enough to help a lot with a problem I'm trying to solve. We're on 1st down with a yard to goal, but I can't even punt it across the goal line. Confucius said if he gave a student 1/4 of the solution, and he did not return with the other 3/4s, then he would not teach that student again. So it is after almost a week of frustation and with great anxiety that I ask this...
How do I open an input file for pyparsing and print the output to another file?
Here is what I've got so far, but it's really all his work
from pyparsing import *
datafile = open( 'test.txt' )
# Backaus Nuer Form
num = Word(nums)
accessionDate = Combine(num + "/" + num + "/" + num)("accDate")
accessionNumber = Combine("S" + num + "-" + num)("accNum")
patMedicalRecordNum = Combine(num + "/" + num + "-" + num + "-" + num)("patientNum")
gleason = Group("GLEASON" + Optional("SCORE:") + num("left") + "+" + num("right") + "=" + num("total"))
patientData = Group(accessionDate + accessionNumber + patMedicalRecordNum)
partMatch = patientData("patientData") | gleason("gleason")
lastPatientData = None
# PARSE ACTIONS
def patientRecord( datafile ):
for match in partMatch.searchString(datafile):
if match.patientData:
lastPatientData = match
elif match.gleason:
if lastPatientData is None:
print "bad!"
continue
print "{0.accDate}: {0.accNum} {0.patientNum} Gleason({1.left}+{1.right}={1.total})".format(
lastPatientData.patientData, match.gleason
)
patientData.setParseAction(lastPatientData)
# MAIN PROGRAM
if __name__=="__main__":
patientRecord()
It looks like you need to call datafile.read() in order to read the contents of the file. Right now you are trying to call searchString on the file object itself, not the text in the file. You should really look at the Python tutorial (particularly this section) to get up to speed on how to read files, etc.
It seems like you need some help putting it together. The advice of #BrenBarn is spot-on, work with problem of simple complexity before you put it all together. I can help by giving you a minimal example of what you are trying to do, with a much simpler grammar. You can use this as a template to learn how to read/write a file in python. Consider the input text file data.txt:
cat 3
dog 5
foo 7
Let's parse this file and output the results. To have some fun, let's mulpitply the second column by 2:
from pyparsing import *
# Read the input data
filename = "data.txt"
FIN = open(filename)
TEXT = FIN.read()
# Define a simple grammar for the text, multiply the first col by 2
digits = Word(nums)
digits.setParseAction(lambda x:int(x[0]) * 2)
blocks = Group(Word(alphas) + digits)
grammar = OneOrMore(blocks)
# Parse the results
result = grammar.parseString( TEXT )
# This gives a list of lists
# [['cat', 6], ['dog', 10], ['foo', 14]]
# Open up a new file for the output
filename2 = "data2.txt"
FOUT = open(filename2,'w')
# Walk through the results and write to the file
for item in result:
print item
FOUT.write("%s %i\n" % (item[0],item[1]))
FOUT.close()
This gives in data2.txt:
cat 6
dog 10
foo 14
Break each piece down until you understand it. From here, you can slowly adapt this minimal example to your more complex problem above. It's OK to read the file in (as long as it is relatively small) since Paul himself notes:
parseFile is really just a simple shortcut around parseString, pretty
much the equivalent of expr.parseString(open(filename).read()).

Categories