This may be fairly simple, but i am not able to figure it out.
I am working on a peice of code where i need to loop over a range defined by the string.
Example:
service_range = 'AX000-AX930'
ouput :
'AX000'
'AX001'
'AX002'
'AX003'
'AX004'
.
.
.
'AX929'
'AX930'
I am trying to generate using the code below:
service_range = re.findall(r'\d+', service_range)
print(service_range) # ['000', '930']
for i in range(int(service_range[0]), int(service_range[1] + 1)):
print(i)
count += 1
above code works however the output is not quite what iwant. I want to preserve the digits & code ('AX')
0
1
2
3
.
.
.
.
930
You may concatenate the prefix, and padd-left the value, with a nicer regex that gives
import re
service_range = 'AX000-AX930'
prefix1, start, prefix2, end = re.search(r'([A-Z]+)(\d+)-([A-Z]+)(\d+)',
service_range).groups()
assert prefix1 == prefix2
for i in range(int(start), int(end) + 1):
print(f"{prefix1}{i:03d}")
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
I want to create a text file from python whereby I want the value of a variable to change iteratively inside the for loop. However, I am unable to call the value of the variable inside the loop. Instead it just prints the the variable as string. The code is as follow:
f = open('workfile.txt, 'w')
for i in range (1,152):
a = 1
f.write('BEGIN PERIOD a \n')
f.write('6 1 1200.0 90.0 \n')
f.write('END PERIOD a \n')
a +=1
f.close()
Here, after the BEGIN PERIOD and END PERIOD inside the f.write function, I want the value of ''a'' to change every time the loop runs. However, the program prints ''a'' as a string. Kindly help me out.
Here 'BEGIN PERIOD a \n' is a string. Program cannot recognize that you want to print value of a. What you need to do is to divide your string and specify you variable to get its value: 'BEGIN PERIOD ' + str(a) + '\n'.
But there is one problem, you run a = 1 on each iteration, therefore it does not matter you increase the value or not here a +=1, your code will print a always as 1.
Better not to use a because you already have an iterator i. You can use below code:
f = open('workfile.txt', 'w')
for i in range(1, 152):
f.write('BEGIN PERIOD ' + str(i) + '\n')
f.write('6 1 1200.0 90.0 \n')
f.write('END PERIOD ' + str(i) + '\n')
f.close()
for i in range(1, 152): here for loop iterates variable i starting from 1 (inclusive) to 152 (exclusive).
You can declare a outside the loop:
a = 1
for i in range(1, 152):
...
a += 1
If it is declared inside the loop, every time the loop loops again, there will be a new a. If you want to keep it always online, you need to decalre it outside the loop scope.
And if you want to use a, you can try format:
a = 1
for i in range(1, 152):
...
a += 1
print('a is {}'.format(a))
There are 2 problems.
(i) Initialization of a should be outside the loop
(ii) in f.write() it should be %d formatting and supply the variable name
Working code as below:
f = open('workfile.txt', 'w')
a = 1
for i in range (1,152):
f.write('BEGIN PERIOD %d \n' %(a))
f.write('6 1 1200.0 90.0 \n')
f.write('END PERIOD %d \n' %(a))
a +=1
f.close()
I'm new to Python and I'm trying to output the length of a list as a single integer, eg:
l1 = ['a', 'b', 'c']
len(l1) = 3
However, it is printing on cmdline with 1s down the page, eg:
1
1
1
1
1
1
etc
How can I get it to just output the number rather than a list of 1s?
(Here's the code:)
def Q3():
from datetime import datetime, timedelta
inputauth = open("auth.log", "r")
authStrings = inputauth.readlines()
failedPass = 'Failed password for'
for line in authStrings:
time = line[7:15]
dateHour = line[0:9]
countAttack1 = []
if time in line and failedPass in line:
if dateHour == 'Feb 3 08':
countAttack1.append(time)
length1 = len(countAttack1)
print(length1)
Ideally, I'd like it to output the number in a print so that I could format it, aka:
print("Attack 1: " + length1)
I think you are looping and ifs are inside a loop. If so, just print the length outside loop scope.
Please share the complete code for a better answer
Well as Syed Abdul Wahab said, the problem is that the "list" is getting recreated each loop. This makes so that the print reports "1", as it is the actual length of the list.
The other problem, repetition of the printng is similar - you are actually printing "each time in the loop".
The solution is then simple: you initialize the list outside the loop; and also report outside the loop.
def Q3():
from datetime import datetime, timedelta
inputauth = open("auth.log", "r")
authStrings = inputauth.readlines()
failedPass = 'Failed password for'
countAttack1 = [] # after this line the countAttack will be empty
for line in authStrings:
time = line[7:15]
dateHour = line[0:9]
if time in line and failedPass in line:
if dateHour == 'Feb 3 08':
countAttack1.append(time)
length1 = len(countAttack1)
print("Attack 1: " + str(length1))
I'd also like to take a bit of time to link you to string formatting While the documentation is complex it will make printing much easier, above print is trnasformed into:
print("Attack 1: {0}".format(length1))
Further analysing the code gives some peculiarities, you check if time is in the line string. - However just a few codelines above you create time from a slice of line - so it will always be inside line. (Except for the edge case where line is not of correct length, but that'll error anyways). So that if statement should be simplified to:
if failedPass in line:
Here is the function that prints the the length:
def print_length():
if time in line and failedPass in line:
if dateHour == 'Feb 3 08':
countAttack1.append(time)
length1 = len(countAttack1)
print(length1)
print_length()
>>>Print length of the List.
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.