I made a program which has one function. This function has a file as an input and function writes result to output. I need to test if the my result is the same as expected. Below you can find a code of a program:
import os
def username(input):
with open(input, 'r') as file:
if os.stat(input).st_size == 0:
print('File is empty')
else:
print('File is not empty')
for line in file:
count = 1
id, first, middle, surname, department = line.split(":")
first1 = first.lower()
middle1 = middle.lower()
surname1 = surname.lower()
username = first1[:1] + middle1[:1] + surname1
username1 = username[:8]
if username1 not in usernames:
usernames.append(username1)
data = id + ":" + username1 + ":" + first + ":" + middle + ":" + surname + ":" + department
else:
username2 = username1 + str(count)
usernames.append(username2)
data = id + ":" + username2 + ":" + first + ":" + middle + ":" + surname + ":" + department
count += 1
with open("output.txt", "a+") as username_file:
username_file.write(data)
usernames = []
if __name__ == '__main__':
username("input_file1.txt")
username("input_file2.txt")
username("input_file3.txt")
with open("output.txt", "a+") as username_file:
username_file.write("\n")
How do I write an unittest on this type of program? I tried this but it gave me this error "TypeError: expected str, bytes or os.PathLike object, not _io.TextIOWrapper" . Code of my test is below:
import unittest
import program.py
class TestProgram(unittest.TestCase):
def test_username(self):
i_f = open("input_file1.txt", 'r')
result = program.username(i_f)
o_f = open("expected_output.txt", 'r')
self.assertEqual(result, o_f)
if __name__ == '__main__':
unittest.main()
I would be really happy if you could help me!!!
You didn't read the file, just pass the IO object.
Edit the TestProgram and add .read()
class TestProgram(unittest.TestCase):
def test_username(self):
i_f = open("input_file1.txt", 'r').read() # read the file
result = program.username(i_f)
o_f = open("expected_output.txt", 'r').read()
self.assertEqual(result, o_f)
you can also use with-as for automatic closing the file.
Related
I am made a file where i can reference functions and i thought that it would be fun to make a program to add text to the file, and when i try to open the file, it doesn't show any errors, but when i go and check the file there's nothing there.
My code:
ime_funk = input("Ime funkcije: ")
x = 0
funk = ""
while True:
vseb_funk = input("Kopiraj eno, pa po eno vrstico funkcije, ko si končal napiši končano: ")
if vseb_funk == "končano":
break
else:
funk += "\n "+vseb_funk
mark = open("test.txt", "a")
mark.write("\n" + ime_funk + "\n" + funk)
Don't pay attention to the variable names and strings, as that's not important.
Also I am using replit if that's important.
I have no idea why it doesn't work.
i have tried mark = open("test.txt", "w") but same story.
you need to add this line to your code
mark.close()
or what you can do I replace this part of the code
mark = open("test.txt", "a")
mark.write("\n" + ime_funk + "\n" + funk)
with this code:
with open("test.txt", "a") as mark:
mark.write("\n" + ime_funk + "\n" + funk)
A file write in python does not happen untill you call file.flush(). This is usually called automatically when you close the file but in your example you are never closing the file. Try:
ime_funk = input("Ime funkcije: ")
x = 0
funk = ""
while True:
vseb_funk = input("Kopiraj eno, pa po eno vrstico funkcije, ko si končal napiši končano: ")
if vseb_funk == "končano":
break
else:
funk += "\n "+vseb_funk
mark = open("test.txt", "a")
mark.write("\n" + ime_funk + "\n" + funk)
mark.close()
or even better try using the with statement:
with open("test.txt", "a") as mark:
mark.write("\n" + ime_funk + "\n" + funk)
this way close() is called automatically
I'm parsing data from a text file ('placlog.txt') that is continuously being updated. As I run the code everything prints as expected, but if there are any updates to the placlog file while the code is running it is not printed.
The placlog file is being updated by a third-party program and I am using the above code to read the file and print any updates.
Once formatted, the text should be sent via a Telegram API. This part is also working initially.
import urllib.parse
import time
import requests
import os
def post_to_telegram(msg):
#print(msg)
base_url = 'https://api.telegram.org/bot&text="{}'.format(msg)
requests.get(base_url)
def check_url_inMsgList(stringToMatch, msgList):
for i in msgList:
if (stringToMatch in i):
return False
return True
try:
f = open("oldFile.txt", "r")
msgList = f.read().split("\n")
f.close()
except:
f = open("oldFile.txt", "w")
msgList = []
f.close()
selections = []
urr = ""
name = ""
pie = ""
ourLines = 2400
url_found = 0
name_found = 0
pie_found = 0
while (True):
file1 = open('placlog.txt', 'r')
Lines = file1.readlines()
file1.close()
while (True):
# print("-------------------------------")
if (ourLines == len(Lines)):
break
elif (ourLines > len(Lines)):
ourLines = 0
else:
txt = Lines[ourLines].strip()
tlist = txt.split("&")
ourLines = ourLines + 1
for subtxt in tlist:
if "eventurl=" in subtxt:
a = subtxt[9:len(subtxt) - 3]
url = "www.awebsite.com/%23" + a.replace("%23", "/")
#url = url.replace("%23", "#")
for i in range(10):
if "F" + str(i) + "/" in url:
url = url.split("F" + str(i) + "/")[0] + "F" + str(i) + "/"
urr = url
url_found = 1
elif "bit=" in subtxt:
name = urllib.parse.unquote(subtxt[4:len(subtxt)])
name_found = 1
elif "pie\":" in subtxt:
a = subtxt.split("price")[1]
pie = a.split("\"")[2]
pie = float(pie)
pie = round(pie, 1)
pie = str(pie)
pie_found = 1
selections.append(url + name + pie)
msg = (url + " " + name + " " + pie)
stringToFind = url + " " + name
if (check_url_inMsgList(stringToFind, msgList)):
post_to_telegram(msg)
msgList.append(msg)
print(msg)
f = open("oldFile.txt", "a+")
f.write(msg + "\n")
f.close()
time.sleep(0.5)
elif "minodds=" in subtxt:
a = subtxt.split("minodds=")[1]
pie = a.split("&")[0]
pie = float(pie)
rie = round(pie, 1)
pie = str(pie)
pie_found = 1
selections.append(url + name + pie)
msg = (url + " " + name + " " + pie)
stringToFind = url + " " + name
if (check_url_inMsgList(stringToFind, msgList)):
post_to_telegram(msg)
msgList.append(msg)
print(msg)
f = open("oldFile.txt", "a+")
f.write(msg + "\n")
f.close()
time.sleep(0.5)
time.sleep(1)
I would recommend using watchdog, and seeing if that helps your situation. It can monitor for file system changes, so you could define a function which is executed when the placlog.txt file is changed/updated.
A good guide can be found here: http://thepythoncorner.com/dev/how-to-create-a-watchdog-in-python-to-look-for-filesystem-changes/
From that guide, you can simply change the functions defined to suit your needs i.e.
def on_modified(event):
if event.src_path == "path/to/placlog.txt":
with open('placlog.txt', 'r') as placlog:
lines = file1.readlines()
Could you try this out and see if it helps? I still recommend the with statement for file i/o since you always want your file to close no matter what.
This link might also be useful since they are also monitoring a single .txt file: Python Watchdog - src_path inconsistent
watchdog documentation: https://pythonhosted.org/watchdog/
Note: Deleted the old answer since you clarified the question.
I am new in programming. Just bought a book for beginners in Python. In it I got this code:
name = input("name")
email = input("whats ure email:)
favoriteband = input("ure fav band")
outputString = name + "|" email + "|" + favoriteband
fileName = name + ".txt"
file = open(fileName, "wb")
file.write (outputString)
print (outputString , " saved in ", fileName)
file.close ()
According to book its fine but I got this error:
TypeError: a bytes-like object is required, not 'str'
I got no clue how to fix it and book isn't explaining this as well.
Let's go through this:
name = input("Your name: ")
email = input("Your email: ")
The close quotes are needed as has been pointed out.
outputString = name + "|" + email + "|" + favoriteband
outputString was missing a + before email
Finally, we need to rewrite you file management:
with open(fileName, "a") as file:
file.write (outputString)
print (outputString , " saved in ", fileName)
Writing this as a with statement guarantees it will close. Using open(..., "a") opens the file in "append" mode and lets you write multiple strings to a file of the same name.
Finally, if I can editorialize, I am not a fan of this book so far.
Edit: here is the whole code with fixes, in hopes of getting you there.
name = input("name")
email = input("whats ure email:")
favoriteband = input("ure fav band")
outputString = name + "|" + email + "|" + favoriteband
fileName = name + ".txt"
with open(fileName, "a") as file:
file.write (outputString)
print (outputString , " saved in ", fileName)
You can verify it works with:
with open(fileName, "r") as file:
print(file.read())
I did some editing (closing quotes and a missing +):
name = input("name:")
email = input("whats ure email:")
favoriteband = input("ure fav band:")
outputString = name + " | " + email + " | " + favoriteband
fileName = name + ".txt"
file = open(fileName, "w") #opened in write mode but not in binary
file.write (outputString)
print (outputString , " saved in ", fileName)
file.close()
You're getting that error because you're writing in binary mode, hence the b in wb for
file = open(fileName, "wb")
Try this instead :
file = open(fileName, "w")
Now I have a text file which i outputted to 3 times using the following code.
def Final_Output():##// Edited
with open('A Class, A.T.I..txt', "a") as file_out:
file_out.write("Full_Name :> " + str(Sur_Name) + ', ' + str(Name) + '\n')
file_out.write("Date: >: " + str(Date) + "\n")
file_out.write("Class: >: " + str(Class) + '\n')
file_out.write("Range >: " + str(Range_Limit) + "\n")
file_out.write("Score :> " + str(N) + '\n')
file_out.write("Score_Percent :> " + str(Score_Percent) + '\n')
Name = "MohKale"
Sur_Name = "MohKale Surname"
Date = "16/9/2015 11:7:52"
Class = "A"
Range_Limit = "10765"
N = "10"
Score_Percent = "0.0"
Final_Output()
Then I created a program which reads the text file continuously (until the end) and then saves them to variables.
a = 0
with open('A Class, A.T.I..txt', "r") as file_out:
for line in file_out:
a = a + 1
Name2 = file_out.readline()
print(Name2)
Sur_name2 = file_out.readline()
print(Sur_name2)
Date2 = file_out.readline()
print(Date2)
Class2 = file_out.readline()
print(Class2)
Range_Limit2 = file_out.readline()
print(Range_Limit2)
N2 = file_out.readline()
print(N2)
Score_Percent2 = file_out.readline()
print(Score_Percent2)
Now technically the program does read the text file, and saves to variables, but the problem is the first time it reads the text file it skips the first line for some reason, the second time it looped it also skipped the first line but also the second one, then the third time it looped it read the 2nd line but skipped the third, this continuously happened skipping the next read file.
can anyone understand and explain the problem
furthermore by putting
print(line)
it does print the missing lines, but this is way too random, is there anyway to prevent such an event
The problem seems to be that you are using a for loop AND iterating over the lines, use just one :)
I suggest that you remove the for loop and do just the file_out.readline()'s
with open('A Class, A.T.I..txt', "r") as file_out:
a = a + 1
Name2 = file_out.readline()
print(Name2)
Sur_name2 = file_out.readline()
print(Sur_name2)
Date2 = file_out.readline()
print(Date2)
Class2 = file_out.readline()
print(Class2)
Range_Limit2 = file_out.readline()
print(Range_Limit2)
N2 = file_out.readline()
print(N2)
Score_Percent2 = file_out.readline()
print(Score_Percent2)
The issue is that your for loop is consuming some of the lines in the file independently of your other .readline() calls. Rather than doing
for line in file_out:
You will want to do something like
try:
while True:
a += 1
Name2 = next(file_out)
print(Name2)
# ...
Score_Percent2 = next(file_out)
print(Score_Percent2)
except StopIteration:
print("Done!")
I successfully simplified a python module that imports data from a spectrometer
(I'm a total beginner, somebody else wrote the model of the code for me...)
I only have one problem: half of the output data (in a .csv file) is surrounded by brackets: []
I would like the file to contain a structure like this:
name, wavelength, measurement
i.e
a,400,0.34
a,410,0.65
...
but what I get is:
a,400,[0.34]
a,410,[0.65]
...
Is there any simple fix for this?
Is it because measurement is a string?
Thank you
import serial # requires pyserial library
ser = serial.Serial(0)
ofile = file( 'spectral_data.csv', 'ab')
while True:
name = raw_input("Pigment name [Q to finish]: ")
if name == "Q":
print "bye bye!"
ofile.close()
break
first = True
while True:
line = ser.readline()
if first:
print " Data incoming..."
first = False
split = line.split()
if 10 <= len(split):
try:
wavelength = int(split[0])
measurement = [float(split[i]) for i in [6]]
ofile.write(str(name) + "," + str(wavelength) + "," + str(measurement) + '\n')
except ValueError:
pass # handles the table heading
if line[:3] == "110":
break
print " Data gathered."
ofile.write('\n')
do this:
measurement = [float(split[i]) for i in [6]]
ofile.write(str(name) + "," + str(wavelength) + "," + ",".join(measurement) + '\n')
OR
ofile.write(str(name) + "," + str(wavelength) + "," + split[6] + '\n')