Python variable input into format string - python

I currently have this code here:
test = 2.432
test_formatted = "{:.2f}".format(test)
print(test_formatted)
Output:
2.43
Is there a way to insert a variable for the number into the format string? Such as:
test = 2.432
te = 2
test_formatted = "{:." + str(te) + "f}".format(test)
print(test_formatted)
Thanks!

Like this:
'{{:.{}f}}'.format(te)
# Result: '{:.2f}'
Or directly convert the number with an f-string (Python 3.6 and newer):
f'{test:.{te}f}'
# Result: '2.43'

Add some parenthesis around the string you are creating and it works!
test = 2.432
te = 3
test_formatted = ("{:." + str(te) + "f}").format(test)
print(test_formatted)

Using f-strings, you can do something like this:
test = 2.432
te = 2
test_formatted = f"{test:.{te}f}"
print(test_formatted)
Output:
2.43

Related

Array printing to textfile with an extra space, cant figure it out. Examples provided

An array is defined to a textfile and it prints out as such:
array1 = 0 0 , 0 , 0 #used commas to depict the extra space
 I need it to be like array1 = 0 0 0 0
when array2 prints it prints how I need it to: array2 = 0 0 0 0
example of the messed up array and the working array:
rssReference = self.ui.rss_reference_textbox.text()
rssEngine_1 = self.ui.rss_engine1_textbox.text()
rssEngine_2 = self.ui.rss_engine2_textbox.text()
rssEngine_3 = self.ui.rss_engine3_textbox.text()
combusterReference = self.ui.numComb_reference_textbox.text()
combusterEngine_1 = self.ui.numComb_engine1_textbox.text()
combusterEngine_2 = self.ui.numComb_engine2_textbox.text()
combusterEngine_3 = self.ui.numComb_engine3_textbox.text()
#**array **1#
postProcess_RSS = (rssReference, rssEngine_1, rssEngine_2, rssEngine_3)
rss = " ".join(postProcess_RSS)
#**array2**#
postProcess_Combustor = (combusterReference, combusterEngine_1, combusterEngine_2, combusterEngine_3)
combustor = " ".join(postProcess_Combustor)
with open(outputDir + '.txt', "w") as text_file:
print(f'#', "\n"f'array1 = {rss}', "\n"f'array2 = {combustor}', file=text_file)
# using str() method to convert to string still returning not desired ouput
Likely that you have extra spaces in your variables.
rssReference, rssEngine_1, rssEngine_2, rssEngine_3
If you cannot remove the spaces from those variables ahead of time, you can remove the extra spaces from rss afterwards with a regex substitution:
rss = re.sub('\s+', ' ', rss)
Here is what your code would look like:
Code:
import re
#**array **1#
postProcess_RSS = (rssReference, rssEngine_1, rssEngine_2, rssEngine_3)
rss = " ".join(postProcess_RSS)
rss = re.sub('\s+', ' ', rss)
...

How to loop one by one when executing full script

below is my some part of python automation code:
Inside def function for loop is there how to takes 1st value from list then continue with starting "kcauto()" then when it comes again in same loop then takes 2nd value from list and continue so on
my code : -
nnlist = [
'3789',
'4567'
]
def kcauto():
ano = '031191'
print(ano)
code = '12'
print(code)
date = '06-Feb-2022'
print(date)
url2 = ('https://www.myweb&nn=')
for nn in nnlist:
callurl2 = print(url2 + nn)
for tn in nnlist:
kcauto()
print(tn)
My output : -
031191
12
06-Feb-2022
https://www.myweb&nn=3789
https://www.myweb&nn=4567
3789
031191
12
06-Feb-2022
https://www.myweb&nn=3789
https://www.myweb&nn=4567
4567
But required output : -
031191
12
06-Feb-2022
https://www.myweb&nn=3789
3789
031191
12
06-Feb-2022
https://www.myweb&nn=4567
4567
You have two loops going on in here. One outside of the kcauto() function and one inside of it. You must remove one of these in order to fix the double link print out.
Something like this might work:
nnlist = ['3789','4567']
def kcauto(items):
for nn in items:
ano = '031191'
print(ano)
code = '12'
print(code)
date = '06-Feb-2022'
print(date)
url2 = ('https://www.myweb&nn=')
callurl2 = print(url2 + nn)
print(nn + "\n")
kcauto(nnlist)

If a string is longer than 10 characters, only return the last 10

In python I am returning numbers but I only want the last 10 numbers
Ex: 221234567890 should return 1234567890
In excel it looks like: if(len(cell) > 10, right (cell,10),.. but don't know how to do this in python
a = 221234567890
result = a % 10000000000
This should work for ints and
a = "221234567890"
result = a[-10:]
should work for strings
a = '123456789abcdefg'
a[-10:]

Python: Evenly space output data with varying string lengths

I am trying to get my output data to look like this:
-------------------------------------------------------
Grade Report for Programs
-------------------------------------------------------
Jacobson, Mark 19.0 <--- 20,17,20
Snurd, Mortimur 16.5 <--- 20,19,18,17,16,15,14,13
Luxemburg, Rosa 15.0 <--- 18,15,20,10,12
Atanasoff, John 20.0 <--- 20,20,20,20,20,20,20
Hopper, Grace 20.0 <--- 20,20,20,20,20,20
-------------------------------------------------------
But I don't know how to deal with the varying name length. My output currently looks like this.
Grade Report for Programs
-------------------------------------------------------
Jacobson, Mark 19.0 <--- 20,17,20
Snurd, Mortimur 16.5 <--- 20,19,18,17,16,15,14,13
Luxemburg, Rosa 15.0 <--- 18,15,20,10,12
Atanasoff, John 20.0 <--- 20,20,20,20,20,20,20
Hopper, Grace 20.0 <--- 20,20,20,20,20,20
-------------------------------------------------------
The program I have written is to take an input file of grade scores and collect the data and neatly print out the average.
The input file looks something like this:
Mark Jacobson,20,17,20
Mortimur Snurd,20,19,18,17,16,15,14,13
Rosa Luxemburg,18,15,20,10,12
John Atanasoff,20,20,20,20,20,20,20
Grace Hopper,20,20,20,20,20,20
And here is my code that collects the name and scores, and prints out the data with last name, first name, average score, then the actual scores that resulted to the average.
file = input("Enter filename: ")
grade_file = open(file, 'r')
print()
print('---------------------------------------------------------')
print('\t\tGrade Report for Programs')
print('---------------------------------------------------------')
for text in grade_file:
end_of_name = text.find(',')
name_seperated = text.find(' ')
first_name = text[0:name_seperated]
last_name = text[name_seperated+1:end_of_name]
name_last_first = last_name + "," + " " + first_name
grades = text[end_of_name+1:]
start = 0
index = 0
sum_n = 0
average= 0
score = 0
count = 0
while index < len(grades):
if grades[index] == ',':
score = int(grades[start:index])
count += 1
sum_n = score + sum_n
start = index + 1
index += 1
count += 1
score = int(grades[start:index])
sum_n = score + sum_n
average = sum_n / count
print(name_last_first, " ", average, "<---", grades)
print('---------------------------------------------------------')
grade_file.close()
I just need to figure out how to have even spaces so it makes an even row and column like the first output. Help is greatly appreciated! Thanks!
One way is to use Python's builtin C-style formatting. Note that a negative field width indicates that the field is to be left-justified:
>>> print("%-30s %4.1f" % ("Jacobson, Mark", 19.0))
Jacobson, Mark 19.0
>>>
Alternatively, you can use the string format method:
>>> print("{:30s} {:4.1f}".format("Jacobson, Mark", 19.0))
Jacobson, Mark 19.0
>>>
You can also use Formatted String Literals (f-strings):
>>> name = "Jacobson, Mark"
>>> average = 19.0
>>> print(f"{name:30s} {average:4.1f}")
Jacobson, Mark 19.0
>>>
Use string formatting with field width specifiers:
print('{:20s} {:4.1f} <--- {}'.format(name_last_first, average, grades))
This uses the str.format() method with the Format String Syntax to slot values into a template.
The first slot formats strings into a field 20 characters wide, the second slots floating point numbers into a field 4 characters wide, using 1 digit after the decimal point (leaving 1 for the decimal point itself plus 2 digits before the point).
If I were you, I'd also look at the csv module to read your data, rather than use string manipulations. You'll get list objects with separate values for each column:
import csv
print('---------------------------------------------------------')
print('\t\tGrade Report for Programs')
print('---------------------------------------------------------')
with open(file, 'r', newline='') as grade_file:
reader = csv.reader(grade_file)
for row in reader:
name = row[0]
name = ' '.join(map(str.strip, reversed(name.split(',')))
grades = [int(g) for g in row[1:])
average = sum(grades) / len(grades)
print('{:20s} {:4.1f} <--- {}'.format(name, average, ','.join(grades)))
print('---------------------------------------------------------')
The answer I find easiest is just using some basic string arithmetic.
For example, say for want the aligned a variable 20 spaces ahead of left-alignment, in your case the "average" variable, you could simply do this
print(name_last_first + (' ' * (20-len(name_last_first))) + average
+ "<----" + grades)
It's just a bit lengthier, but the code is easier to interpret in my opinion.
(Note: this method only works with mono spaced fonts! But most Python output is defaulted to a MS font :-) )
You can use this code :
handle = open('grade.txt')
name= list()
avg = list()
scores = list()
for line in handle:
line = line.strip()
spos = line.find(',')
scores.append(line[spos+1:])
words = line.split(',')
words = words
name.append(words[0])
add = 0
for i in range(1,len(words)):
add = add+int(words[i])
average = add/(len(words)-1)
avg.append(average)
for i in range(len(avg)):
tname = name[i].split()
fname = tname[0]
sname = tname[1]
order = sname+', '+fname
print("%-20s %-3.1f <--- %-30s " %(order,float(avg[i]),scores[i]))
The final line is for displaying it in an organized manner, you're code was lacking it only.

python csv delimiter doesn't work properly

I try to write a python code to extract DVDL values from the input. Here is the truncated input.
A V E R A G E S O V E R 50000 S T E P S
NSTEP = 50000 TIME(PS) = 300.000 TEMP(K) = 300.05 PRESS = -70.0
Etot = -89575.9555 EKtot = 23331.1725 EPtot = -112907.1281
BOND = 759.8213 ANGLE = 2120.6039 DIHED = 4231.4019
1-4 NB = 940.8403 1-4 EEL = 12588.1950 VDWAALS = 13690.9435
EELEC = -147238.9339 EHBOND = 0.0000 RESTRAINT = 0.0000
DV/DL = 13.0462
EKCMT = 10212.3016 VIRIAL = 10891.5181 VOLUME = 416404.8626
Density = 0.9411
Ewald error estimate: 0.6036E-04
R M S F L U C T U A T I O N S
NSTEP = 50000 TIME(PS) = 300.000 TEMP(K) = 1.49 PRESS = 129.9
Etot = 727.7890 EKtot = 115.7534 EPtot = 718.8344
BOND = 23.1328 ANGLE = 36.1180 DIHED = 19.9971
1-4 NB = 12.7636 1-4 EEL = 37.3848 VDWAALS = 145.7213
EELEC = 739.4128 EHBOND = 0.0000 RESTRAINT = 0.0000
DV/DL = 3.7510
EKCMT = 76.6138 VIRIAL = 1195.5824 VOLUME = 43181.7604
Density = 0.0891
Ewald error estimate: 0.4462E-04
Here is the script. Basically we have a lot of DVDL in the input (not in the above truncated input) and we only want the last two. So we read all of them into a list and only get the last two. Finally, we write the last two DVDL in the list into a csv file. The desire output is
13.0462, 3.7510
However, the following script (python 2.7) will bring the output like this. Could any guru enlighten? Thanks.
13.0462""3.7510""
Here is the script:
import os
import csv
DVDL=[]
filename="input.out"
file=open(filename,'r')
with open("out.csv",'wb') as outfile: # define output name
line=file.readlines()
for a in line:
if ' DV/DL =' in a:
DVDL.append(line[line.index(a)].split(' ')[1]) # Extract DVDL number
print DVDL[-2:] # We only need the last two DVDL
yeeha="".join(str(a) for a in DVDL[-2:])
print yeeha
writer = csv.writer(outfile, delimiter=',',lineterminator='\n')#Output the list into a csv file called "outfile"
writer.writerows(yeeha)
As the commenter who proposed an approach has not had the chance to outline some code for this, here's how I'd suggest doing it (edited to allow optionally signed floating point numbers with optional exponents, as suggested by an answer to Python regular expression that matches floating point numbers):
import re,sys
pat = re.compile("DV/DL += +([+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?)")
values = []
for line in open("input.out","r"):
m = pat.search(line)
if m:
values.append(m.group(1))
outfile = open("out.csv","w")
outfile.write(",".join(values[-2:]))
Having run this script:
$ cat out.csv
13.0462,3.7510
I haven't used the csv module in this case because it isn't really necessary for a simple output file like this. However, adding the following lines to the script will use csv to write the same data into out1.csv:
import csv
writer = csv.writer(open("out1.csv","w"))
writer.writerow(values[-2:])

Categories

Resources