Python - Writing to a specific point in a line - python

I have encountered an error when writing my program and would like some help with it. The program has to replace a specific segment of the line with a calculated value. The segment in which I am talking about is the third index in a line, formatted like this:
Product01, 12346554, 15, 6
I am having the program calculate the value in which I want to replace with the final value but no matter how much I seem to try, my code frequently gives errors. For an example, I have used seek to try and move the cursor to allow myself to edit this value, however with the following code:
Total = 0
receipt = open("Receipt.txt", "w")
while True:
try:
Prod_Code = input("Enter a code or Done to get your final receipt: ")
if len(Prod_Code) == 8:
int(Prod_Code)
with open("Data Base.txt", "r+") as searchfile:
for line in searchfile:
if Prod_Code in line:
print(line)
Quantity = input("What quantity of this product do you want? ")
Total += float(line.split(",")[2]) * int(Quantity)
print(Quantity)
print(Total)
receipt.write(line)
print(line.split(",")[3])
W = int(line.split(",")[3]) - int(Quantity)
print(W)
L = (line)
L.seek(27, 0)
L.write(str(W))
elif Prod_Code == "Done":
receipt.close()
with open("Receipt.txt", "r") as datafile:
for item in datafile:
print(item.split(",")[1])
print(item.split(",")[2])
print("Your total cost is £", Total)
input("Press Enter to exit:")
exit()
else:
print("Incorrect length, try again")
except ValueError:
print("You must enter an integer")
However, when I run it this is the error that I get:
AttributeError: 'str' object has no attribute 'seek'.
I was wondering if anyone could help, and/or provide a different answer to my problem? Thanks in advance.

Related

Remove Bottom 3 scores in file

numberofbands = int(input("How many bands are there in the competition? "))
print("Input each band’s name pressing enter after each one")
file = open("scores.txt","w")
for loop in range(numberofbands):
name = input("\nEnter the name of the band: ")
votes = input("Enter how many votes that band received: ")
file.write(name + "," + votes + "," + "\n")
file.close()
number_of_lines = len(open("scores.txt").readlines( ))
def removebottom3():
#code to remove bottom 3 here
removebottom3()
The first part writes the band's name and score to the file.
I want the code to remove the lowest 3 scoring bands from the file. There will be a function for that.
How can I do this?
Thanks in advance.
You are quite off. Let me help you.
First, consider using Counter, it is meant for this kind of cases.
Second, try dividing the script logic into blocks (divide and conquer!), first get the data, then sort and remove the last 3, and only at the end write the results to a file.
Here is an example of the implementation.
from collections import Counter
numberofbands = int(input("How many bands are there in the competition? "))
print("Input each band’s name pressing enter after each one")
scores = Counter()
for n in range(numberofbands):
name = input("\nEnter the name of the band: ")
vote = input("Enter how many votes that band received: ")
scores.update({name:int(votes)})
#remove the last 3
final = scores.most_common()[:-3]
#write to file
with open('scores.txt', 'w') as f:
for name, vote in final:
f.write(f'{name},{vote}\n')
since you are already reading all the lines from the file,
number_of_lines = len(open("scores.txt").readlines( ))
you can use sorted to sort your lines by score,
lines = open("scores.txt").readlines()
sorted(lines,
key=lambda x : float(x.split(",")[1]),
reverse = True)

Error trapping combined with a counter not working

I'm making a code that makes a user enter RLE line by line. I then send the entered data to a function that decodes it. Within the function, I've included some basic error trapping.
My error is that when the user can only enter incorrect data the number of times they choose (they choose the amount of lines they want to enter). i.e. if the user enters 2 (out of 3) correct lines of RLE and then enters an incorrect line, the code won't ask to enter the RLE again, but if they enter an incorrect line at the first or second input it works.
Code:
if line_amount>2:
print ("Please enter the compressed data one line at a time")
while line_amount > counter:
compressed_data = input('->') #ENTER RLE DATA
counter+=1
RLEtoASCII(compressed_data,counter)
RLEtoASCII:
def RLEtoASCII(compressed_data,counter):
try:
pairs = [(int(compressed_data[i:i+2]), compressed_data[i+2]) for i in range(0, len(compressed_data), 3)]
global text
text = ''.join(n * c for n, c in pairs)
RLE_Inputs = open("Entered Data.txt", 'a+') #File that lists all the inputs
#[etc all the file writing]
except:
print('THERE WAS A PROBLEM WITH THE VALUES Please re-enter values.\n')
If I try calling RLEtoASCII after the except, it creates a loop. counter -=1 doesn't appear to work after the except either...
By moving the error handling out of your function and into the if loop, we can more easily control the iteration:
if line_amount>2:
print ("Please enter the compressed data one line at a time")
while line_amount > counter:
compressed_data = input('->') #ENTER RLE DATA
if compressed_data != '':
try:
RLEtoASCII(compressed_data)
counter+=1
except:
print('THERE WAS A PROBLEM WITH THE VALUES Please re-enter values.\n')
RLEtoASCII:
def RLEtoASCII(compressed_data):
pairs = [(int(compressed_data[i:i+2]), compressed_data[i+2]) for i in range(0, len(compressed_data), 3)]
global text
text = ''.join(n * c for n, c in pairs)
RLE_Inputs = open("Entered Data.txt", 'a+') #File that lists all the inputs
#[etc all the file writing]
Try changing the > in while line_amount > counter: to >=. This is because when you get to the third line it is testing for if 3>3 which is false, while 3>=3 is true.
The problem seems to be that counter is incremented even when you catch an error. I changed counter to a global so that it effectively is't incremented when there is an error. just make sure you put global counter above your definition. Let me know if this works for you.
if line_amount>2:
print ("Please enter the compressed data one line at a time")
while line_amount > counter:
compressed_data = input('->') #ENTER RLE DATA
counter+=1
RLEtoASCII(compressed_data)
RLEtoASCII:
def RLEtoASCII(compressed_data):
global counter
try:
pairs = [(int(compressed_data[i:i+2]), compressed_data[i+2]) for i in range(0, len(compressed_data), 3)]
global text
text = ''.join(n * c for n, c in pairs)
RLE_Inputs = open("Entered Data.txt", 'a+') #File that lists all the inputs
#[etc all the file writing]
except:
print('THERE WAS A PROBLEM WITH THE VALUES Please re-enter values.\n')
counter-=1

Python while loop + check if integer or not, then saving to a file

I've been stuck on this for some time now. I'm making a quiz app, and I need to save the users score. The app will ask the users to enter a number from 1 to 3 so that they can save their score into a file, that will either save it in file 1, 2 or 3 (for 3 different classes).
If the user enters a letter then they will be asked to enter a number, and if the number isn't between 1 and 3 then it will ask them again until there's input is valid. Then it will save their score into the file.
classname = int(input("\nEnter [1] for class 1 \nEnter [2] for class 2 \nEnter [3] for class 3"))
invalid = True
while invalid = True:
classname = int(raw_input("Please enter a number in the range 1 to 3: "))
if int(classname) >= 1 and int(classname) <= 3:
invalid = False:
while invalid = False:
if int(classname) == 1:
score = str(score)
f = open("class 1.txt", "a")
f.write(str(name+': '))
f.write(str(score))
f.write('\n')
f.close()
elif int(classname) == 2:
score = str(score)
f = open("class 2.txt", "a")
f.write(str(name+': '))
f.write(str(score))
f.write('\n')
f.close()
elif int(classname) == 3:
score = str(score)
f = open("class 3.txt", "a")
f.write(str(name+': '))
f.write(str(score))
f.write('\n')
f.close()
else: #not sure what to put here
I didn't know what to put for else. I am new to Python and I really need help with this as I just want to complete it. If someone could fix my code that would be greatly appreciated.
I think I need to use type(classname) but I'm not sure.
You don't need an else statement.
Since you are taking the classname as an integer, you can catch the all errors with try-except. So basically you will check the input is an integer or not.
try:
classname = int(input("\nEnter [1] for class 1 \nEnter [2] for class 2 \nEnter [3] for class 3"))
except:
print ("It's not a number, please try again.")
continue
if 3 < classname or classname < 1:
print ("Please enter a number between 1 and 3.")
continue
The continue statement will pass all over the things until the user enter a number, then it will check is the number between 1 and 3. If it's not between 1 and 3, then it will pass all over the things until user enter an acceptable number.
you should learn about regular expressions and the re module:
import re
only_numbers=re.compile("^[0-9]+$")
good_one=re.compile("^[1-3]$")
usr_input=str(raw_input("Please enter a number in the range 1 to 3: ")
while True:
while not only_numbers.match(usr_input):
usr_input=str(raw_input("a NUMBER in the range 1 to 3: ")
if good_one.match(usr_input):
break
else:
usr_input=str(raw_input("in the RANGE 1 to 3: ")
outint=int(usr_input)
For your example, you don't even need to check if it is a letter. I am assuming that if the answer given is anything but a 1, 2, or 3, you will reject it. So, all you need is an else statement, and just put the code that you want to do if they enter an invalid response.
If you really want to check the type of the answer, you can either check if the input is a letter:
if isalpha(classname):
//Do stuff here
Or check if it is not an integer in general:
if type(classname) != int:
//Do stuff here
However, if the user enters a letter, your program will not even get to this conditional to check it, because you immediately attempt to convert the input to an integer at the top. If the input is a letter, this will immediately throw an error. Therefore, GLHF's answer above would be an ideal solution to fix your code.

How to append a list with raw_input in Python and print min and max values

I am trying to build a list with raw inputs.
while True:
inp = raw_input("Enter a number: ")
#edge cases
if inp == "done" : break
if len(inp) < 1 : break
#building list
try:
num_list = []
num = int(inp)
num_list.append(num)
except:
print "Please enter a number."
continue
#max and min functions
high = max(num_list)
low = min(num_list)
#print results
print "The highest number: ", high
print "The lowest number: ", low
print "Done!"
At the moment it seems to only save one of the inputs at a time and therefore the the last raw input is printed as both the max and min.
Any ideas? I am new to Python and could use some direction. So far I have been unable to find the answer in StackOverflow or in the Python documentation.
Thanks in advance!
That's because you keep erasing the list with each iteration. Put num_list = [] outside the while loop:
num_list = []
while True:
...
You should also put these two lines:
high = max(num_list)
low = min(num_list)
outside the loop. There is no reason to keep executing them over and over again.

My loop and File I/O

How do I get my loop to write to the file until I stop the loop?
For example
outFile = "ExampleFile.txt", "w"
example = raw_input(" enter number. Negative to stop ")
while example >= 0:
example = raw_input("enter number. Negative to stop")
outFile.write("The number is", example,+ "\n")
I feel like im hitting it close but I'm not sure. I wasn't sure how to search for this question in paticular. Sorry, I keep getting a error stating that the function takes 1 argument, when I enter more than 2.
import os.path
outFile = open("purchases.txt","w")
quantity = float(raw_input("What is the quantity of the item :"))
cost = float(raw_input("How much is each item :"))
while quantity and cost >= 0:
quantity = float(raw_input("What is the quantity of the item :"))
cost = float(raw_input("How much is each item :"))
total = quantity * cost
outFile.write("The quantity is %s\n"%(quantity))
outFile.write("the cost of the previous quality is $s\n" %(cost))
outFile.close()
outFile = open("purchases.txt","a")
outFile.write("The total is ",total)
outFile.close()
when you write:
outFile = "ExampleFile.txt", "w"
you create a tuple, not a file object.
You probably meant to write:
outFile = open('ExampleFile.txt','w')
Of course, you could do this a little better using a context manager:
with open('ExampleFile.txt','w') as outFile:
#...
Your code has a second error:
outFile.write("The number is", example,+ "\n")
baring the SyntaxError (,+), file.write takes only 1 argument. You probably wanted something like:
outFile.write("The number is {0}\n".format(example))
or using the old style of string formatting (as requested):
outFile.write("The number is %s\n"%(example))

Categories