How to print all the highest value places - python-3.x

I cannot figure out how to get python to print all the highest values as it only prints the first one it encounters.
It takes standard input from a file that has on a few lines the following:
89 Michael Dunne (grade name)
I know I can use the zip function but I cannot figure out how only print the name from it
If I add "highstudents = sorted(zip(grade,name),reverse=True)" it sorts from high to low but I do not know how to filter the name out as it prints as "(89, 'Pepe')"
The code below is the following attempt so far.
import sys
def topgrade(x):
s = max(x)
return s
def main():
s = sys.argv[1]
grade=[]
name = []
try:
with open(s,'r') as studata:
for line in studata:
try:
line = line.strip()
grade.append(int(line[0:2]))
name.append(line[3::])
except ValueError:
print("Invalid mark",line[0:2],"encountered. Skipping.")
top = topgrade(grade)
a = grade.index(top)
print("Best students:",name[a])
print("Best mark:",top)
except FileNotFoundError:
print("File not found:",s)
if __name__ == '__main__':
main()

Rather than trying to keep the students and marks in 2 separate lists (with the risk that they get out of step) it is better to use a dictionary - where the key is the mark and the value is a list of the student(s) who obtained that mark.
Then it is a simple task of just printing out the highest key, and the associated list of students. I'm using defaultdict as an easier option than having to create or append to the list for each value.
from collections import defaultdict
import sys
def main():
s = sys.argv[1]
grades = defaultdict(list)
try:
with open(s,'r') as studata:
for line in studata:
try:
line = line.strip()
grades[int(line[0:2])].append(line[3::])
except ValueError:
print("Invalid mark",line[0:2],"encountered. Skipping.")
top_mark = max(grades.keys())
print("Best students:{}".format(','.join(grades[top_mark])))
print("Best mark: {}".format(top_mark))
except FileNotFoundError:
print("File not found:",s)
if __name__ == '__main__':
main()

Related

How to determine the number of columns per row variably in a CSV File with Python?

I am analyzing xml-structured Textfiles about insider dealings. I wrote some code to parse through the XML-structure and write my output in a CSV file. The results of the files are written per line and the analyzed information is written in individual columns. But in some files information is present in multiple times and my code override the information in the cells, in the end only one date is in the cell of my CSV-File.
import csv
import glob
import re
import string
import time
import bs4 as bs
# User defined directory for files to be parsed
TARGET_FILES = r'D:\files\'
# User defined file pointer to LM dictionary
# User defined output file
OUTPUT_FILE = r'D:\ouput\Parser.csv'
# Setup output
OUTPUT_FIELDS = [r'Datei', 'transactionDate', r'transactionsCode', r'Director', r'Officer', r'Titel', r'10-% Eigner', r'sonstiges', r'SignatureDate']
def main():
f_out = open(OUTPUT_FILE, 'w')
wr = csv.writer(f_out, lineterminator='\n', delimiter=';')
wr.writerow(OUTPUT_FIELDS)
file_list = glob.glob(TARGET_FILES)
for file in file_list:
print(file)
with open(file, 'r', encoding='UTF-8', errors='ignore') as f_in:
soup = bs.BeautifulSoup(f_in, 'xml')
output_data = get_data(soup)
output_data[0] = file
wr.writerow(output_data)
def get_data(soup):
# overrides the transactionDate if more than one transactions disclosed on the current form
# the number determine the column for the output
_odata = [0] * 9
try:
for item in soup.find_all('transactionDate'):
_odata[1] = item.find('value').text
except AttributeError:
_odata[1] = ('keine Angabe')
try:
for item in soup.find_all('transactionAcquiredDisposedCode'):
_odata[2] = item.find('value').text
except AttributeError:
_odata[2] = 'ka'
for item in soup.find_all('reportingOwnerRelationship'):
try:
_odata[3] = item.find('isDirector').text
except AttributeError:
_odata[3] = ('ka')
try:
_odata[4] = item.find('isOfficer').text
except AttributeError:
_odata[4] = ('ka')
try:
_odata[5] = item.find('officerTitle').text
except AttributeError:
_odata[5] = 'ka'
try:
_odata[6] = item.find('isTenPercentOwner').text
except AttributeError:
_odata[6] = ('ka')
try:
_odata[7] = item.find('isOther').text
except AttributeError:
_odata[7] = ('ka')
try:
for item in soup.find_all('ownerSignature'):
_odata[8] = item.find('signatureDate').text
except AttributeError:
_odata[8] = ('ka')
return _odata
if __name__ == '__main__':
print('\n' + time.strftime('%c') + '\nGeneric_Parser.py\n')
main()
print('\n' + time.strftime('%c') + '\nNormal termination.')
Actually the code works, but overwrites columns if, for e.g. more than one transacion date is given in the file. So I need a code that automatically uses the next column for each transaction date. How could this work?
I would be glad if someone have a solution for my problem. Thanks a lot!
Your issue is that you are iterating over the result of
soup.find_all()
and every time you are writing to the same value. You need to do something with
_odata in each iteration, otherwise you will only end up with whatever is written to it the last time.
If you can show us what the data you're trying to parse actually looks like, perhaps we could give a more specific answer.

CRUD program to read,write and append the details in txt file

It's a school assignment, an event management system. It will write the data to a txt file and retrieve it. Its mostly a CRUD program but not sure why it is not running. It shows space as an error on VS CODE IDE.
It will Create a customer, ask for the seats that he want to book. He can also delete the seats as per ref number before 24 hours.
import random
print("Welcome to the Event System")
def menu():
print("Choose the number from menu")
print("1:Create Customer")
print("2:Reserve a seat")
print("3.Cancel the seat")
print("4.Exit the Event System")
option = input("put down the number")
return option
def executingmenuinputchoice(option):
if(option == 1):
createcust()
elif(option == 2):
reserveseat()
elif(option == 3):
cancelseat()
elif(option == 4):
exit()
else:
print('you have chose a wrong option')
menu()
def createcust():
print('Provide Customer details')
name = input('Full name? --> ')
pno = input('phone number? -> ')
email = input('Email Id? --> ')
try:
file = open("cust.txt", "r")
lines = file.read().splitlines()
last_lines = lines[-1]
content = last_lines.split()
refno = random.randint(10001, 99999)
file.close()
file = open("cust.txt", "a")
file.write("\n"+" "+name+" "+pno+" "+email+" "+refno)
file.close()
print(refno + 'is your reference number')
print('Added Customer to file')
except IOError:
print("File doesn't exist at location")
except TypeError:
print('input proper data')
return createcust()
def customerexist(refno):
try:
file = open("cust.txt", "r")
for line in file:
content = line.split()
if (refno == int(content[4])):
file.close()
return True,int(content[5])
except IOError:
print("File doesn't exist")
file.close()
return False,0
def reserveseat():
referencenumber=input("Enter the Reference Number-->")
refexist =referenceexist(referencenumber)
if(refexist==True):
seatsyouwantbook=input("Number of seats you want to book? ->")
date=datetime.datetime.now()
seats=seats+seatsyouwantbook
newline=""
try:
file=open("cust.txt","r")
lines=file.read().splitlines()
last_linesno=len(lines)
currentLine=1
for line in lines:
content=line.split
if(currentline!=last_linesno):
if(refno==int(content[4])):
file.close()
return True,int(content[5])
except IOError:
print("FIle never existed")
file.close()
return False,0
def cancelseat():
try:
file=open("cust.txt","r")
for line in file:
content=line.split()
if (refno==int(content[4])):
file.close()
return True,int(content[5])
except IOError:
print("File doesn't exist")
file.close()
return False,0
invalid syntax (<unknown>, line 41)
I want it to run properly so, I can submit it again.
I haven't checked your whole code, but at least got it running to the point that you could further rectify it:-
import random
print("Welcome to the Event System")
def customerexist(refno):
try:
file = open("cust.txt", "r")
for line in file:
content = line.split()
if (refno == int(content[4])):
file.close()
return True,int(content[5])
except IOError:
print("File doesn't exist")
file.close()
return False,0
def reserveseat():
referencenumber=input("Enter the Reference Number-->")
refexist =referenceexist(referencenumber)
if(refexist==True):
seatsyouwantbook=input("Number of seats you want to book? ->")
date=datetime.datetime.now()
seats=seats+seatsyouwantbook
newline=""
try:
file=open("cust.txt","r")
lines=file.read().splitlines()
last_linesno=len(lines)
currentLine=1
for line in lines:
content=line.split
if(currentline!=last_linesno):
if(refno==int(content[4])):
file.close()
return True,int(content[5])
except IOError:
print("FIle never existed")
file.close()
return False,0
def cancelseat():
try:
file = open("cust.txt","r")
for line in file:
content=line.split()
if (refno==int(content[4])):
file.close()
return True,int(content[5])
except IOError:
print("File doesn't exist")
file.close()
return False,0
def createcust():
print('Provide Customer details')
name = input('Full name? --> ')
pno = input('phone number? -> ')
email = input('Email Id? --> ')
try:
file = open("cust.txt", "r")
lines = file.read().splitlines()
last_lines = lines[-1]
content = last_lines.split()
refno = random.randint(10001, 99999)
file.close()
file = open("cust.txt", "a")
file.write("\n"+" "+name+" "+pno+" "+email+" "+refno)
file.close()
print(refno + 'is your reference number')
print('Added Customer to file')
except IOError:
print("File doesn't exist at location")
except TypeError:
print('input proper data')
return createcust()
def menu():
print("Choose the number from menu")
print("1:Create Customer")
print("2:Reserve a seat")
print("3.Cancel the seat")
print("4.Exit the Event System")
option = input("put down the number")
return option
def executingmenuinputchoice(option):
option = int(option)
if(option == 1):
createcust()
elif(option == 2):
reserveseat()
elif(option == 3):
cancelseat()
elif(option == 4):
exit()
else:
print('you have chose a wrong option')
menu()
executingmenuinputchoice(menu())
REASON FOR ERRORS:-
Your indentation was all over the place, python language
prioritizes indentation as it uses it to figure out a block span, so you should
keep a consistent indentation scheme throughout your code.
Python uses top down approach for ~interpreting the
program, i.e. It only keeps track of the stuff that it had already
encountered. In your code, the function executingmeninputchoice()
and menu() (the two primary functions used for UI) were stacked
above all other function, therefore when you tried to call other
function from these two function, they aren't called. As the program
doesn't know whether these functions exists or not (as it hasn't
encountered them yet)
A logical error existed in function
executingmenuinputchoice(option) as you were trying to take in
input a string and were comparing it with integer values, and
therefore every time the operation failed and the control got shifted
to the else block, therefore every time you got the same output
'you have chose a wrong option' regardless of whether the input was
legal or not
P.S.:- I haven't tested your full code, as this isn't a code for me service, other logical errors may also exist, so I would recommend you to find and fix those too.

Python object serialization

I am trying to mimic a dict by using that as the base class. The objective is to meet these conditions:
If 2 arguments on the command line, set a key and value in the object's dictionary;
if 1 argument on the command line, treat it as a key and show the value; if no arguments on the command line, show all keys and values.
Here is my code:
import pickle,os,sys
class ConfigDict(dict):
def __init__(self, filename):
self._filename = filename
if not os.path.exists(self._filename):
with open(self._filename,"wb") as fh:
pickle.dump({}, fh)
with open(self._filename,"rb") as fh:
self.update(pickle.load(fh))
def __setitem__(self, key, value):
dict.__setitem__(self,key,value)
with open(self._filename,"wb") as fh:
pickle.dump(self, fh)
def __getitem__(self,key):
return dict.__getitem__(self,key)
cd = ConfigDict('first.pickle')
# if 2 arguments on the command line,
# set a key and value in the object's dictionary
if len(sys.argv) == 3:
key, value = sys.argv[1], sys.argv[2]
print('writing data: {0}, {1}'.format(key, value))
cd[key] = value
# if 1 argument on the command line, treat it as a key and show the value
elif len(sys.argv) == 2:
print('reading a value')
key = sys.argv[1]
print('the value for {0} is {1}'.format(sys.argv[1], cd[key]))
# if no arguments on the command line, show all keys and values
else:
print('keys/values:')
for key in cd.keys():
print(' {0} = {1}'.format(key, cd[key]))
I am able to write to the file, however, when i try to retrive the value for a given key, i hit the error (only the end of stack trace shown):
with open(self._filename,"wb") as fh:
AttributeError: 'ConfigDict' object has no attribute '_filename'
But, i already set the _filename in __init__. What am i missing ?
Well, this is a tricky one - the problem seems to be with
pickle.load(fh) and NOT with self.update(
try this in two lines
...
with open(self._filename,"rb") as fh:
tmp = pickle.load(fh)
self.update(tmp)
...
this would fail at tmp =, so it's the object you're un-pickling that's failing. An easy fix would be to do pickle.dump(dict(self), fh), when serialising your things. Though this whole approach seems "forced" to me. Fully working version:
import pickle,os,sys
class ConfigDict(dict):
def __init__(self, filename):
self._filename = filename
if not os.path.exists(self._filename):
with open(self._filename,"wb") as fh:
pickle.dump({}, fh)
with open(self._filename,"rb") as fh:
self.update(pickle.load(fh))
def __setitem__(self, key, value):
dict.__setitem__(self,key,value)
with open(self._filename,"wb") as fh:
pickle.dump(dict(self), fh)
def __getitem__(self,key):
return dict.__getitem__(self,key)
cd = ConfigDict('first.pickle')
# if 2 arguments on the command line,
# set a key and value in the object's dictionary
if len(sys.argv) == 3:
key, value = sys.argv[1], sys.argv[2]
print('writing data: {0}, {1}'.format(key, value))
cd[key] = value
# if 1 argument on the command line, treat it as a key and show the value
elif len(sys.argv) == 2:
print('reading a value')
key = sys.argv[1]
print('the value for {0} is {1}'.format(sys.argv[1], cd[key]))
# if no arguments on the command line, show all keys and values
else:
print('keys/values:')
for key in cd.keys():
print(' {0} = {1}'.format(key, cd[key]))

Write a program that wraps a file to a given line length

I am trying to get it to read the file and convert the lines to words then append the word to a line of a given length. and return the text. This is what I have so far.
def file(file_name):
''' gets users file and checks its validity'''
try:
open(file_name).readlines()
except IOError:
print('File not found')
else:
file = file_name.split()
return file
def column_length(width):
'''gets column width and checks its validity'''
try:
if int(width) >= 1:
return int(width)
else:
print('illegal value')
except ValueError:
print('Illegal value')
def main():
file_name = input('Input file name? ')
width = input('column width? ')
lines = []
line = ''
for i in file_name:
if len(i) + len(line) > int(width):
lines.append(line)
line = ''
line = line + i + ' '
if i is file_name[-1]: lines.append(line)
return '\n'.join(lines)
if __name__ == "__main__":
main()
When I run the code, it seems to skip out the first two functions and doesn't return any text.
If you know where I'm going wrong please let me know.
Thank you.
this uses a great answer from here
def chunks(l, n):
""" Yield successive n-sized chunks from l.
"""
for i in xrange(0, len(l), n):
yield l[i:i+n]
with open('in_file.txt') as in_file, open('out_file.txt', 'w') as out_file:
for in_line in in_file:
for out_line in chunks(in_line, width)
out_file.write(out_line + '\n')
Also, very interesting read is the implementation of text justification using dynamic programing. MIT has some great lecture slides online about the subject but this stack thread has most of it. It's similar to the algorithm latex uses to make all text look "pretty". It expands on your idea of text wrapping and adds the feature of justification (it adds whitespaces to make it look as best as possible).
Your code does skip the first two functions, it only defines them. You need to call them from somewhere afterwards, like you did with themain() function. There's no apparent output because the code never does anything with the lines themain()function returns (such asprintthem).
You might want to consider using Python's built-in moduletextwrapto do this sort of text processing. Here's a simple example illustrating its use:
import os
import textwrap
def get_file_name():
""" Get file name and checks its validity. """
file_name = input('Input file name? ')
if not os.path.isfile(file_name):
raise FileNotFoundError('"%s"' % file_name)
return file_name
def get_column_width():
""" Get column width and checks its validity. """
width = int(input('Column width? '))
if width < 1:
raise ValueError('column width must be greater than zero')
return width
def line_wrap(file_name, width):
""" Read blank line delimited paragraphs of text from file and wrap them to
the specified width.
"""
wrapped_lines = []
with open(file_name) as input_file:
lines = ''
for line in input_file:
lines += line
if not line.rstrip(): # blank line?
wrapped_lines.extend(textwrap.wrap(lines, width) + ['\n'])
lines = ''
if lines: # last paragraph need not be followed by blank line
wrapped_lines.extend(textwrap.wrap(lines, width))
return wrapped_lines
def main():
file_name = get_file_name()
width = get_column_width()
wrapped_lines = line_wrap(file_name, width)
print('\n'.join(wrapped_lines))
if __name__ == "__main__":
main()

Functions and Dictionary in Python

def build_dictionary(infile):
count_dict={}
for line in infile:
line=line.strip()
if len(line) and line[0]!="-":
lst=line.split(",")
lastname=lst[0].strip()
for lastname in lst:
if lastname not in count_dict:
count_dict[lastname]=1
else:
count_dict[lastname]=count_dict[lastname]+1
return count_dict
def main():
import os.path
while True:
try:
name1=input("Enter input name:")
infile=open(name1,"r")
result=build_dictionary(infile)
print(result)
break
except:
print("Error in code")
main()
I have this program and I want it to take a file that contains last name,first name, take the last names and see how many times they appear in the dict. the only problem i have is it counts the first lastname then stops, whyy isnt it going through the entire dictionary
Replace your build_dictionary method with this:
def build_dictionary(infile):
count_dict={}
for line in infile:
line=line.strip()
if len(line) and line[0]!="-":
lst=line.split(",")
lastname=lst[0].strip()
if lastname not in count_dict:
count_dict[lastname]=1
else:
count_dict[lastname]=count_dict[lastname]+1
return count_dict

Resources