So close yet I can't figure out whats wrong - python

I am taking a course through school and have this challenge on Codio:
For your final challenge in this unit, you will load two files:
The first file F1 will have information about some accounts. It will be pipe-delimited and have one record per line, with these fields:
ACCOUNT NUMBER | PIN CODE | BALANCE
The second file F2 will contain instructions: one on each line. The instructions will look like this:
COMMAND | AMOUNT | ACCOUNT NUMBER | PIN CODE
COMMAND will be either add or sub. If the command is add, you will add AMOUNT to the BALANCE in the account files F1. If the command is sub, you will subtract.
However, there are a number of reasons for which you may need to reject the transaction. If you are asked to subtract an amount that would put the account below zero or if the pin code you are provided does not match the pin code in the account record, the transaction is ignored.
Account Transactions
Given pipe-delimited files F1 and F2 where F1 contains accounts with fields ACCOUNT NUM|PIN|BALANCE and F2 contains transaction instructions COMMAND|AMOUNT|ACCOUNT NUM|PIN, execute the transactions, storing the results back in F1.
The COMMAND field will be add or sub indicating addition or subtraction from the account.
Transactions which do not provide the correct PIN code or attempt to put the account below zero should be ignored.
This is my code for the challenge:
records = []
with open(F1,'r') as account_info:
content = account_info.readlines()
for row in content:
recordList = row.strip("\n").split('|')
records.append(recordList)
records2 = []
with open(F2,'r') as user_input:
content2 = user_input.readlines()
for row in content2:
recordList2 = row.strip("\n").split('|')
records2.append(recordList2)
for i in range(len(records)):
row = records[i]
for i in range(len(records2)):
row = records2[i]
for row in records and records2:
if records[i][1] == records2[i][3] and records2[i][0] == "add":
newBalance = int(records[i][2]) + int(records2[i][1])
records[i][2] = str(newBalance)
elif records2[i][0] == "sub" and int(records[i][2]) >= int(records2[i][1]):
newBalance = int(records[i][2]) - int(records2[i][1])
records[i][2] = str(newBalance)
output_records = ""
i = 0
while i <= len(records):
output_records += '|'.join(records[i])
if i != len(records):
output_records += '\n'
i += 1
if i == len(records):
break
outputFile = open(F1, 'w')
outputFile.write(output_records)
outputFile.close
This is what I'm getting for output which is off by one number.
Your program output did not match the expected output.
Your output:
1000|1234|10000
1020|2222|0
3000|3344|0
2020|1234|90000
Expected output:
1000|1234|11000
1020|2222|0
3000|3344|0
2020|1234|90000
Can someone point me in the direction of where I'm going wrong? Thanks.

Assume amount and balance are integer-valued.
For float change int(...) to float(...) in Code
Code
# Get Records
with open('file1.txt','r') as f1:
records = []
for row in f1:
row = row.rstrip().split('|')
# Strip white space and convert balance to float
row = [x.strip() if i != 2 else int(x.strip()) for i, x in enumerate(row)]
records.append(row)
# Get Transactions
with open('file2.txt', 'r') as f2:
transactions = []
for row in f2:
row = row.rstrip().split('|')
# Strip whitespace and convert balance to float
row = [x.strip() if i != 1 else int(x.strip()) for i, x in enumerate(row)]
transactions.append(row)
# Perform Transactions
for t in transactions:
for record in records:
# check records for matching account & pin
# Brute force search -- okay for records and transactions only in thousands
if t[2:] == record[:2]:
# Found account to update (record account & pin matches transaction)
if t[0] =='add':
record[-1] += t[1] # increment balance
elif t[0] == 'sub':
if record[-1] - t[1] >= 0:
record[-1] -= t[1] # decrement balance
break
# Output updated records
with open('file1.txt', 'w') as f3:
for row in records:
row = [str(x) for x in row]
f3.write(' | '.join(row) + '\n')
Test
Prior to running
File1.txt
1000 | 1234 | 10000
1020 | 2222 | 2500
3000 | 3344 | 3000
2020 | 1234 | 95000
File2.txt
add | 1000 | 1000 | 1234
sub | 1000 | 1020 | 2222
add | 1000 | 3000 | 3344
sub | 1000 | 2020 | 1234
After running
File1.txt
1000 | 1234 | 11000
1020 | 2222 | 1500
3000 | 3344 | 4000
2020 | 1234 | 94000

I think the problem could come from these:
for row in records and records2:
if records[i][1] == records2[i][3] and records2[i][0] == "add":
newBalance = int(records[i][2]) + int(records2[i][1])
records[i][2] = str(newBalance)
elif records2[i][0] == "sub" and int(records[i][2]) >= int(records2[i][1]):
newBalance = int(records[i][2]) - int(records2[i][1])
records[i][2] = str(newBalance)
From what I see, if records[i][1] != records2[i][3] it still run the elif and subtract.

Your code is really messy, i can advise you to delete all and restart from an empty file:
the following lines are meaningless:
for row in records and records2:
for i in range(len(records)):
row = records[i]
for i in range(len(records2)):
row = records2[i]
If you know how to use dictionaries, they might help a bit:
Here there is some pseudo code of a possible type of solution:
accounts = {}
with open(F1,'r') as f:
for line in f:
acc, pin, balance = line.split('|')
accounts[acc] = {'pin': pin, 'balance': int(balance)}
with open(F2,'r') as f:
for line in f:
command, amount, acc, pin = line.split('|')
amount = int(amount)
if accounts[acc]['pin'] != pin:
continue # wrong pin
if command == 'add':
accounts[acc]['balance'] += amount
elif accounts[acc]['balance'] >= amount: # if there is enough balance to sub
accounts[acc]['balance'] -= amount

Related

Parsing a total.txt file by keywords in it

I'm having trouble parsing a file. I have code that parses a file by the word Total: if its value is greater than 20.0 and returns the data. I need to change the search keyword to Tokens eth: with a value greater than 20.0 and output all data between separators ======== and additionally write all sorted values into sort.txt file. I would be grateful for professional help)
Code:
outlist = []
flag = False
def dump(list_, flag_):
if list_ and flag_:
print('\n'.join(list_))
return [], False
with open('total.txt') as file:
for line in map(str.strip, file):
if line.startswith('='):
outlist, flag = dump(outlist, flag)
else:
tokens = line.split()
if len(tokens) == 3 and tokens[1] == 'Total:':
try:
flag = float(tokens[2][:-1]) > 20.0
except ValueError:
pass
outlist.append(line)
dump(outlist, flag)
total.txt
============
| hafuia
| 0xb34a47885262f9d8673dc77de7b583961134f09fb03620b29d282c32ee6932be
| 0xD0b2612a6eE3111114b43b25322C6F08A251D38D
| Total: 47.62874464666479$
|
|
| Tokens eth:
| 20.608732$ MANA
|
| Protocols cro:
| 17.840052$ VVS Finance
| 8.953779$ V3S Finance
============
| asdf
| 0x72e164aa187feaff7cb28a74b7ff800a0dfe916594c70f141069669e9df5a23b
| 0xC7dFe558ed09F0f3b72eBb0A04e9d4e99af0bd0D
| Total: 22.908481672796988$
|
|
| Tokens eth:
| 22.376087$ SOS
============
| asdf
| 0xbce666bca3c862a2ee44651374f95aca677de16b4922c6d5e7d922cc0ac42a3d
| 0x5870923a244f52fF2D119fbf5525421E32EC006e
| Total: 9.077030269778557$
|
|
| Tokens eth:
| 8.942218$ SOS
============
This is how you can parse the file.
def parse_output(filename):
outlist = []
with open(filename) as file:
new_block = False
to_write = False
lines_arr = []
for line in map(str.strip, file):
if line.startswith('======='):
new_block = not new_block
if new_block:
if to_write:
outlist.append(lines_arr)
lines_arr = []
new_block = False
to_write = False
else:
lines_arr.append(line)
if 'Total:' in line:
num = float(line.split()[-1][:-1])
if num > 20:
to_write = True
return outlist
def write_output(outlist, filename):
for block in outlist:
for line in block:
with open(filename, 'a') as out_file:
out_file.write(line + '\n')
with open(filename, 'a') as out_file:
out_file.write('=======' + '\n')
if __name__ == '__main__':
write_output(parse_output('total.txt'), 'output.txt')
I missed the sorted wallet thing. For sorting, while appending array to outlist, you can use another array for order, or prepend the number to array, sort the outputs, and skip first element while writing.
This is written in such a way that it's easy to get fe. the addresses as well. sorting done with a simple lambda function.
from pprint import pprint
wallet_splitter = "============"
wallet_content_start = "Tokens eth:"
wallet_line_start = "|"
with open("totals.txt") as infile:
wallets = infile.read().split(wallet_splitter)
print(wallets)
wallets_above_20 = []
for wallet in wallets:
total = 0
separate = []
contents = False
for line in wallet.splitlines():
if wallet_content_start in line:
contents = True
elif contents:
if "$" in line:
separate.append(line.replace(wallet_line_start, "").split("$")[0])
total += float(separate[-1])
else:
contents = False
for amount in separate:
if float(amount) > 20:
wallets_above_20.append({
"total": total,
"data": wallet
})
pprint(sorted(wallets_above_20, key = lambda i: i['total'],reverse=True))
This is another simple extensible approach you can use to achieve what you need. The comments will explain the code.
# Create a simple representational object with data for every record.
class RateObject:
# You can change the delimiter to whatever you want.
def __init__(self, text_lines: list, delimiter="Tokens eth:"):
self.text_lines = text_lines
index = [i for i, x in enumerate(text_lines) if delimiter in x][0]
# Get the value from delimiter line
self.value = self._get_value(index)
# Override this method, to change the way you extract the value. From same line or different line etc.
def _get_value(self, delimiter_index: int):
# Case of Tokens eth:
value = self.text_lines[delimiter_index + 1]
value = value.strip()
# A bad parsing for numbers, can be improved may be!
number = "".join([x for x in value if x.isdigit() or x == "."])
if number:
return float(number)
else:
# Assume 0 for unknown values
return 0.0
def __str__(self):
# Return the lines as it is
return "".join(self.text_lines)
def __repr__(self):
return "".join(self.text_lines)
# read the source file
with open("src.txt", "r") as src:
line_texts = src.readlines()
# Split the lines into sections, using the delimiter ========
splitters = [index for index, text in enumerate(line_texts) if text == "============\n"]
# Create a list of RateObjects
raw_objects = [RateObject(lt) for lt in [line_texts[splitters[i]:splitters[i + 1]] for i in range(len(splitters) - 1)]]
# Filter the objects, to get only the ones with value > 20
selected_objects = list(filter(lambda x: x.value > 20.0, raw_objects))
# Sort the objects by value
sorted_objects = sorted(selected_objects, key=lambda x: x.value, reverse=True)
# print(selected_objects)
# print(sorted_objects)
# Write the sorted objects to a file
with open("sorted.txt", "w") as dst:
dst.write("\n".join([str(x) for x in sorted_objects]))
Here's a simple generator-based approach.
def items(file):
"""
Generator to yield items from filename
whose "Tokens eth:" is above 20.0
"""
with open(file) as lines:
item = []
tokens = 0
capture = False
for line in lines:
if line == "============\n":
if tokens > 20.0:
yield tokens, item
item = []
tokens = 0
continue
if capture:
tokens = float(line.strip().split()[-2].rstrip("$"))
capture = False
if line.startswith("| Tokens eth:"):
# Set flag to capture next line when we get to it
capture = True
item.append(line)
def main():
import sys
print("============")
for tokens, item in sorted(list(items(sys.argv[1]))):
print("".join(item), end="")
print("============")
if __name__ == "__main__":
main()
For simplicity, I made the generator also perform filtering, though it would be easy to remove items with a lower total on the caller's side if you wanted to make this reusable.
Demo: https://ideone.com/UKuC6C
In fact, I would recommend that you parse this haphazard file format just once, and convert it to a standard format like CSV or JSON for further processing if this is more than a one-off.
Using regular expressions from the re module of the standard library you can, for example, split the text into blocks enclosed by the separator, then find the amount of eth in each block, sort and finally filter them.
# parameters
total_txt = """from question"""
sorted_file_name = 'sort.txt'
THRESHOLD = 20.
as_dicreasing_order = False
# body
separators = re.finditer('='*12, total_txt)
separators = list(separators)
blocks = map(total_txt.__getitem__, [slice(m1.start(), m2.start()) for m1, m2 in zip(separators, separators[1:])])
amount_block_pairs = [(float(re.search(r'Tokens eth:\n\| (\d*\.\d*)\$', block, re.M).group(1)), block) for block in blocks]
# reverse=False for increasing order, True for the opposite
sorted_blocks = sorted(amount_block_pairs, reverse=as_dicreasing_order)
filtered_blocks = [block for amount, block in sorted_blocks if amount >= THRESHOLD]
with open(sorted_file_name, 'w') as fd:
fd.write(''.join(filtered_blocks))
One another option is to use python ttp template to parse your data. In the following code, it checks your total values, finds out the value lower than 20.0. Then, the code asks a value to enter which will replace with the Tokens eth: which is lower than 20.
from ttp import ttp
import json
with open('total.txt') as f:
data_to_parse = f.read()
ttp_template = '''
| Total: {{total}}$
| {{tokens_eth}}$ {{ignore}}
'''
parser = ttp(data=data_to_parse, template=ttp_template)
parser.parse()
# print result in JSON format
results = parser.result(format='json')[0]
#print(results)
#converting str to json.
result = json.loads(results)
# print(result)
for i in result[0]:
# print(i)
if float(i['total']) < 20:
new_tokens_eth = float(input(f"Total value is {i['total']} lower than 20. Enter a new 'Tokens eth:' value: "))
if i['tokens_eth'] in data_to_parse:
data_to_parse = data_to_parse.replace(i['tokens_eth'], str(new_tokens_eth))
print(data_to_parse)
See the parsed data:
See the output after the code is run.

How do you replace segments in a line using fileinput

I am creating a program for counting coins and I want to create a mechanism which essentially scans a specifically written text file and is able to calculate whether it has been falsely counted but also will replace the ending segment of the line with either Y for Yes or N for No.
The txt file reads as such:
Abena,5p,325.00,Y
Malcolm,1p,3356.00,Y
Jane,£2,120.00,Y
Andy,£1,166.25,N
Sandip,50p,160.00,Y
Liz,20p,250.00,Y
Andy,20p,250.00,Y
Andy,50p,160.00,Y
Jane,£1,183.75,N
Liz,£,179.0,N
Liz,50p,170.0,N
Jane,50p,160.0,Y
Sandip,£1,183.0,N
Jane,£2,132.0,N
Abena,1p,3356.0,N
Andy,2p,250.0,N
Abena,£1,175.0,Y
Malcolm,50p,160.0,Y
Malcolm,£2,175.0,N
Malcolm,£1,175.0,Y
Malcolm,1p,356.0,Y
Liz,20p,250.0,Y
Jane,£2,120.0,Y
Jane,50p,160.0,Y
Andy,£1,175.0,Y
Abena,1p,359.56,N
Andy,5p,328.5,N
Andy,£2,108.0,N
Malcolm,£2,12.0,N
as you can see every line is split into 4 segments, I want the fileinput to be able to replace the fourth segment within the specified line.
My program (all the relevant things to see right now) is as follows:
class Volunteer:
def __init__(self, name, coin_type, weight_of_bag, true_count):
self.name = name
self.coin_type = coin_type # a function allowing me to class the data
self.weight_of_bag = weight_of_bag
self.true_count = true_count
just a simple object system to make things easier for later
with open("CoinCount.txt", "r", encoding="'utf-8'") as csvfile:
volunteers = []
for line in csvfile:
volunteers.append(Volunteer(*line.strip().split(',')))
just to create a list as well as an object for easier calculations
def runscan():
with open("CoinCount.txt", "r+", encoding='utf-8') as csvfile:
num_lines = 0
for line in csvfile:
num_lines = num_lines + 1
i = 0
while i < num_lines:
ct = (volunteers[i].coin_type)
wob = float(volunteers[i].weight_of_bag)
if ct == ("£2" or "2"):
accurate_weight = float(12.0)
limit = 10
bag_value = 10 * 12
elif ct == ("£1" or "1"):
accurate_weight = float(8.75)
limit = 20
bag_value = 20 * 8.75
elif ct == "50p":
accurate_weight = float(8)
limit = 20
bag_value = 20 * 8
elif ct == "20p":
accurate_weight = float(5)
limit = 50
bag_value = 5 * 50
elif ct == "10p":
accurate_weight = float(6.5)
limit = 50
bag_value = 6.5 * 50
elif ct == "5p":
accurate_weight = float(3.25)
limit = 100
bag_value = 3.25 * 100
elif ct == "2p":
accurate_weight = float(7.12)
limit = 50
bag_value = 50 * 7.12
elif ct == "1p":
accurate_weight = float(3.56)
limit = 100
bag_value = 3.56 * 100
number_of_bags = wob / bag_value
print("Number of bags on this is" + str(number_of_bags))
import fileinput
line = line[i]
if number_of_bags.is_integer():
with fileinput.FileInput('CoinCount.txt',inplace=True) as fileobj:
for line in fileobj:
x = line.split(',')
for w, word in enumerate(x):
if w == 3 and word == 'N':
print(line[i].replace('N', 'Y'), end='')
i = i + 1
else:
i = i + 1
else:
with fileinput.FileInput('CoinCount.txt',inplace=True) as fileobj:
for line in fileobj:
x = line.split(',')
for w, word in enumerate(x):
if w == 3 and word == 'Y':
print(line[i].replace('Y', 'N'), end='')
i = i + 1
else:
i = i + 1
and finally the thing Im having issues with, the scan function.
the issue is specifically within the last few lines of code here (the replacement part):
import fileinput
if number_of_bags.is_integer():
target, replacement = ('N', 'Y')
else:
target, replacement = ('Y', 'N')
with fileinput.FileInput('CoinCount.txt', inplace=True) as fileobj:
for i, line in enumerate(fileobj):
words = line.rstrip().split(',')
if line.words[3] == target:
line.words[3] = replacement
print(','.join(words))
i = i + 1
f = fileobj.lineno() # Number of lines processed.
print(f'Done, {f} lines processed')
I basically have created a function which goes down each line and calculates the next line down until there aren't anymore lines, the issue with the last part is that I am unable to replace the actual txt file, If I were to run this program right now the result would be a completely blank page. I know that the fix is most likely a simple but tricky discovery but It is really bothering me as this is all that is needed for my program to be complete.
I understand the majority of the coding used but I am very new to fileinput, I want to be able to go from each line and replace the final segment if the segments name (i.e "Y" or "N") given is inaccurate to the actual legitimate segment name as Y is for true and N is for false. Please help, I tried to make sure this question was as easily understandable as possible, please make your example relatable to my program
As far as I understood, the problem is whether the calculation of the weight is correct or not. So just create another file instead of using fileinput. Do you really need it ?
test.csv
Abena,5p,325.00,Y
Malcolm,1p,3356.00,Y
Read the csv and assign some header names
Remove the last column, we don't care if it's correct or not, we will calculate the result anyways
Gather your calculation function in one method, we will apply this to every row
Apply function to every row, if it's correct write "Y" else write "N"
Truncate the whole file and write it over
import pandas as pd
with open("test.csv", "r+") as f:
df = pd.read_csv(f, names=["name", "coin", "weight", "res"])
del df["res"]
def calculate(row):
if row["coin"] == "5p":
return "Y" if 3.25 * 100 == row["weight"] else "N"
elif row["coin"] == "1p":
return "Y" if 3.56 * 100 == row["weight"] else "N"
df["res"] = df.apply(lambda row: calculate(row), axis=1)
f.seek(0)
f.truncate()
df.to_csv(f, index=False, header=False)
test.csv
Abena,5p,325.0,Y
Malcolm,1p,3356.0,N

Parse text for matching key then grab first set of matching table name rows

Trying to do some reconciliations with some large old flat text files(that are honestly messes). Issue I am have is that I find my matching key, I am trying to grab the first set consecutive of rows with a matching table names and ignoring the rest. How would I read what I need and not the rest? Playing around with breaks but the logic is escaping me.
Example: If I was looking for a PK of 101 and table name of drink, from the below list I want to print
drink 25
drink 26
FlatTextFile.txt
pk_tbl 23 100
food 0 0
drink 0 0
dessert 0 0
pk_tbl 101
food 0
drink 25
drink 26
dessert 0
drink 27
drink 28
drink 29
pk_tbl 102
food 0
drink 0
drink 0
drink 0
dessert 0
psuedo code for the example of where I am at essentially
pk_flag = 0
for row in d:
if (row[0]= 'drink') and (pk_flag =='1'):
print(row)
if (row[0]= 'pk_tbl')and (row[2] =='101'):
pk_flag = 1;
elif (row[0]= 'pk_tbl')and (row[2] !='101'):
pk_flag = 0;
A little confusing haha, any help is appreciated.
Thanks!
def get_table_data(file_path = 'FlatTextFile.txt', table_keyword = 'pk_tbl', table_num = '101', data_keyword = 'drink'):
output_ls = []
with open(file_path, 'r') as fh:
table = False
data = False
for line in fh.readlines():
if not len(line.strip()): # Ignoring blank lines
continue
row = line.split()
if not table: # Searching for table keyword and number
if row[0] == table_keyword and row[1] == table_num:
table = True
else:
if row[0] == table_keyword: # I'm already at next table
break
if not data: # Searching for data keyword
if row[0] == data_keyword:
data = True
output_ls.append(line)
else: # Searching for more consecutive data keywords
if row[0] == data_keyword:
output_ls.append(line)
else:
break
return output_ls
Assuming that the patter in the file FlatTextFile.txt is stored as:
table name
food # (none or one or more)
drink # (none or one or more)
desert # (none or one or more)
(food, drink, desert pattern can repeat for a table)
(blank line)
table name (next table name)
(food, drink, desert pattern in any order)
You want to pick the records with drink immediately after you find table pk_tbl 101. The name of the table can be pk_tbl + any string or no string + 101
With the above assumptions, here's the code to pick the specific drinks from table 101.
with open ('FlatTextFile.txt', 'r') as f:
table = False
output = []
line_count = 0
for line in f:
line = line.rstrip()
x = line.split()
if {'pk_tbl','101'} <= set(x): #checks if 'pk_tbl' and '101' are in x
table = True
continue
if table and 'drink' in x: #finds values with drinks
line_count +=1
output.append(line)
continue
if line_count > 0: break #we are past drink in table pk_tbl; stop processing
print (output)
The output of this will be:
['drink 25', 'drink 26']

Reading from a .txt file and printing in a table form

So how can I manipulate a piece of code so that it reads from a .txt file and prints the data in a table format with headings such as 'Resident Number' 'Rent date' 'Price' etc.? The name of the file is Residents.txt
So far, I have this
file = open('Residents.txt','r')
For line in file:
SplitFile = line.split (',')
This is the .txt file-
R1,21/09/2015,C1,440,P,0
R2,21/09/2015,C3,290,A,290
R3,21/09/2015,C4,730,N,0
R4,22/09/2015,C5,180,A,180
R5,22/09/2015,C6,815,A,400
R6,23/09/2015,C7,970,N,0
R7,23/09/2015,C8,1050,P,0
R8,23/09/2015,C9,370,A,200
R9,25/09/2015,C10,480,A,250
R10,25/09/2015,C11,330,A,330
This is the representation of each column in the .txt file-
line.split[0] = Resident Number
line.split[1] = Rent Date
line.split[2] = Customer number
line.split[3] = Rent amount
line.split[4] = (A means Accepted)(N means not accepted)(P means Pending)
line.split[5] = Amount paid
PLEASE NOTE-
if amount paid equals to rent amount, that residents data shouldn't be shown in the table
if status is N or P, that residents data should also not be shown in the table
How can I display a table (WITHOUT importing modules) which has headings of 'Resident number' 'Rent date' 'Customer number' 'Rent amount' 'Amount outstanding'- amount outstanding is just rent amount - amount paid from that line. Also, how can I print a ultimate total of the outstanding amount of money (combined total for everyone that is yet to pay with a status of 'A')
Python 3.5
Thanks
EDIT
for i, word in enumerate(line):
if i == 4 : # We don't print the status
continue
elif i == 2:
continue
print(word.ljust(len(headers[i - (i > 4)(i > 2)])), end=" " * ((i - (i > 4)(i > 2)) != len(headers) - 1))
print()
FURTHER EDIT (15/02)
line = line.strip().split(",")
subtotal = int(line[3]) - int(line[5])
line.append(str(subtotal))
if line[5] == line[3] or line[4] in ("N", "E"):
continue
total += subtotal
You can do this:
headers = ["Resident Number", "Rent Date", "Customer number", "Rent ammount", "Ammount paid", "Outstanding Ammount"]
print(" ".join(headers))
for line in open("test.txt", "r"):
line = line.strip().split(",")
line.append(str(int(line[3]) - int(line[5])))
if line[5] == line[3] or line[4] in ("N", "P"):
continue
for i, word in enumerate(line):
if i == 4:
continue
print(word.ljust(len(headers[i - (i > 4)])), end=" " * ((i - (i > 4)) != len(headers) - 1))
print()
Output:
Resident Number Rent Date Customer number Rent ammount Ammount paid Outstanding Ammount
R5 22/09/2015 C6 815 400 415
R8 23/09/2015 C9 370 200 170
R9 25/09/2015 C10 480 250 230
You may use tabulate
https://pypi.python.org/pypi/tabulate
from the link:
from tabulate import tabulate
table = [["Sun",696000,1989100000],["Earth",6371,5973.6],
["Moon",1737,73.5],["Mars",3390,641.85]]
print tabulate(table)
output:
----- ------ -------------
Sun 696000 1.9891e+09
Earth 6371 5973.6
Moon 1737 73.5
Mars 3390 641.85
----- ------ -------------

getting all of the currecny values out of a text file

im having trouble with getting my python code to read through a text file and add together all of the monetary values. the code seemed to be working fine on my pc, but as soon as i transferred the file to my mac it gave me a whole slew of errors. here is the code
#!usr/bin/python
import sys
def findnum(x):
list = x.split(' ')
index = 0
listindex = -1
numlist = []
sum = 0
for w in list:
if ((w.strip('. n,')).isalpha() != True and w[0].isalpha() != True and w[-2].isdigit() == True):
numlist.append(w)
listindex += 1
while listindex >= 0:
sum += float(numlist[listindex].strip('$ n.'))
listindex -= 1
return sum
def main():
text = open(sys.argv[1])
x = text.readline()
sum = 0
if len(x) > 0:
findnum(x)
while len(x) > 0:
sum += findnum(x)
x = text.readline()
print '{0:.2f}'.format(sum)
if __name__ == '__main__':
main()
here is the text
This is your invoice from the ACME materials
company. You received 50lbs of sand at a
cost of $40. The brick we delivered is 70.5
for the 75Kg. In addition, we delivered 30yards
of sod for $200.00. Delivery charge is $35.
so i need to add 40 + 70.5 + 200 +35
i keep getting a index out of range error..
anyone think they can help me out?
import re
print re.findall('(\$\d+(?:\.\d{2})?)', x)

Categories

Resources