Python coinflip code problem: How to delete lines in .text files? - python-3.x

So I'm tring to write a basic coinflip program that I will implement in a web i need the three .text files : heads, crowns and total to keep the overal values. Is there an algorithm or a module that lets u delete the privius content of the file?
(sorry for anything wrong with my question it is my first time asking in stack)
I tried runing the code and it works. My problem is that after it read and tries to write the new number the new number gets writen after the previous one. My only expirience with file handling was in c and in c if u write it makes a new file.
def main():
tot_num = open('total.txt', 'r+')
while True:
try:
x = input('Flip(F) or Exit(E)').lower()
except ValueError:
print('You had ur options try again')
else:
if x == 'f' or x == 'flip':
cf = coin_flip()
if cf == 'head':
print('Coin --> HEAD')
heads = open('heads.txt', 'r+')
h_num = int(heads.read())
heads.write(f'{h_num + 1}')
tn = int(tot_num.read())
tot_num.write(f'{tn + 1}')
heads.close()
show_coin_flip_num()
elif cf == 'crown':
print('Coin --> CROWN')
crowns = open('crown.txt', 'r+')
c_num = int(crowns.read())
crowns.write(f'{c_num + 1}')
tn = int(tot_num.read())
tot_num.write(f'{tn + 1}')
crowns.close()
show_coin_flip_num()
else:
break
else:
print('Exiting...')
break
The error is basically there cuz after the new number is added it goes next to the previous one it can read it normally the next time. It takes '012'
from the file.
Traceback (most recent call last):
File "file_path", line 462, in <module>
main()
File "file_path", line 442, in main
tn = int(tot_num.read())
ValueError: invalid literal for int() with base 10: ''

I made my program work but it is peculiar that there is not function to delete a specific line from file. I will try to make one myself and post it here because all the answers in
https://stackoverflow.com/q/4710067/7987118 are used to remove specific strings from a text file.

Related

Updating values in an external file only works if I restart the shell window

Hi there and thank you in advance for your response! I'm very new to python so please keep that in mind as you read through this, thanks!
So I've been working on some code for a very basic game using python (just for practice) I've written out a function that opens another file, selects a variable from it and adjusts that variable by an amount or if it's a string changes it into another string, the funtion looks like this.
def ovr(file, target, change):
with open(file, "r+") as open_file:
opened = open_file.readlines()
open_file.close()
with open(file, "w+") as open_file:
position = []
for appended_list, element in enumerate(opened):
if target in element:
position.append(appended_list)
if type(change) == int:
opened[position[0]] = (str(target)) + (" = ") + (str(change)) + (str("\n"))
open_file.writelines(opened)
open_file.close()
else:
opened[position[0]] = (str(target)) + (" = ") + ("'") + (str(change)) + ("'") + (str("\n"))
open_file.writelines(opened)
open_file.close()
for loop in range(5):
ovr(file = "test.py", target = "gold", change = gold + 1)
At the end I have basic loop that should re-write my file 5 times, each time increasing the amount of gold by 1. If I write this ovr() funtion outside of the loop and just run the program over and over it works just fine increasing the number in the external file by 1 each time.
Edit: I should mention that as it stands if I run this loop the value of gold increases by 1. if I close the shell and rerun the loop it increases by 1 again becoming 2. If I change the loop to happen any number of times it only ever increases the value of gold by 1.
Edit 2: I found a truly horrific way of fixing this isssue, if anyone has a better way for the love of god please let me know, code below.
for loop in range(3):
ovr(file = "test.py", target = "gold", change = test.gold + 1)
reload(test)
sleep(1)
print(test.gold)
The sleep part is because it takes longer to rewrite the file then it does to run the full loop.
you can go for a workaround and write your new inforamtion into a file called: file1
So you can use ur working loop outside of the write file. Anfter using your Loop you can just change the content of your file by the following steps.
This is how you dont need to rewrite your loop and still can change your file content.
first step:
with open('file.text', 'r') as input_file, open('file1.txt', 'w') as output_file:
for line in input_file:
output_file.write(line)
second step:
with open('file1.tex', 'r') as input_file, open('file.tex', 'w') as output_file:
for line in input_file:
if line.strip() == '(text'+(string of old value of variable)+'text)':
output_file.write('text'+(string of new value of variable)+' ')
else:
output_file.write(line)
then you have updated your text file.

How can I modify this plugin to use mp3 tags instead of lrc files?

The music player "QuodLibet" contains a plugin that synchronizes lyrics to the currently playing song. It achieves this by parsing the data from a .lrc file. This data however could also be stored in the file metadata, and I want to modify it to account for that.
I did some digging through the pc and I found the .py file containing the plugin. I looked through the code in hopes it would be easy, but I never programmed with python and there's some code that I don't understand. It doesn't look too complicated tho, so I was thinking if you guys could decypher it.
def _build_data(self):
self.text_buffer.set_text("")
if app.player.song is not None:
# check in same location as track
track_name = app.player.song.get("~filename")
new_lrc = os.path.splitext(track_name)[0] + ".lrc"
print_d("Checking for lyrics file %s" % new_lrc)
if self._current_lrc != new_lrc:
self._lines = []
if os.path.exists(new_lrc):
print_d("Found lyrics file: %s" % new_lrc)
self._parse_lrc_file(new_lrc)
self._current_lrc = new_lrc
It seems like it stores the data in new_lrc, so I tried to change that line in an attempt to have it fetched from the tags:
new_lrc = os.path.splitext(track_name)[0] + ".lrc"
Changed to this:
new_lrc = app.player.song.get("~lyrics")
I verified that ~lyrics is indeed the correct way to reference the tag since that's the way it's used in other parts of the code.
This worked to some extent. It was an improvement from previous test in the way that it didn't told me there was something undefined, here is what the program tells me when I boot it up:
TypeError: stat: path should be string, bytes, os.PathLike or integer not NoneType
------
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/quodlibet/plugins/events.py", line 141, in __invoke
handler(*args)
File "/usr/lib/python3/dist-packages/quodlibet/ext/events/synchronizedlyrics.py", line 282, in plugin_on_song_started
self._build_data()
File "/usr/lib/python3/dist-packages/quodlibet/ext/events/synchronizedlyrics.py", line 195, in _build_data
if os.path.exists(new_lrc):
File "/usr/lib/python3.6/genericpath.py", line 19, in exists
os.stat(path)
TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType
I'll let you decide what you make out of that. Here's another snippet of code that is the other part of the puzzle:
def _parse_lrc_file(self, filename):
with open(filename, 'r', encoding="utf-8") as f:
raw_file = f.read()
raw_file = raw_file.replace("\n", "")
begin = 0
keep_reading = len(raw_file) != 0
tmp_dict = {}
compressed = []
while keep_reading:
next_find = raw_file.find("[", begin + 1)
if next_find == -1:
keep_reading = False
line = raw_file[begin:]
else:
line = raw_file[begin:next_find]
begin = next_find
# parse lyricsLine
if len(line) < 2 or not line[1].isdigit():
continue
close_bracket = line.find("]")
t = datetime.strptime(line[1:close_bracket], '%M:%S.%f')
timestamp = (t.minute * 60000 + t.second * 1000 +
t.microsecond / 1000)
words = line[close_bracket + 1:]
if not words:
compressed.append(timestamp)
else:
tmp_dict[timestamp] = words
for t in compressed:
tmp_dict[t] = words
compressed = []
keys = list(tmp_dict.keys())
keys.sort()
for key in keys:
self._lines.append((key, tmp_dict[key]))
del keys
del tmp_dict
That's the part that made things get difficult, and that's where I'm stuck now. The way I see it, the code is expecting to deal with a file, not a tag, so when it makes it's calls they are not working. Any clues to what I can try?
Doesn't matter guys, I already modified it myself and it works as I want now. Here's a link so you can download it and check it out if you want: GitHub issue

Python 3.6.1: Code does not execute after a for loop

I've been learning Python and I wanted to write a script to count the number of characters in a text and calculate their relative frequencies. But first, I wanted to know the length of the file. My intention is that, while the script goes from line to line counting all the characters, it would print the current line and the total number of lines, so I could know how much it is going to take.
I executed a simple for loop to count the number of lines, and then another for loop to count the characters and put them in a dictionary. However, when I run the script with the first for loop, it stops early. It doesn't even go into the second for loop as far as I know. If I remove this loop, the rest of the code goes on fine. What is causing this?
Excuse my code. It's rudimentary, but I'm proud of it.
My code:
import string
fname = input ('Enter a file name: ')
try:
fhand = open(fname)
except:
print ('Cannot open file.')
quit()
#Problematic bit. If this part is present, the script ends abruptly.
#filelength = 0
#for lines in fhand:
# filelength = filelength + 1
counts = dict()
currentline = 1
for line in fhand:
if len(line) == 0: continue
line = line.translate(str.maketrans('','',string.punctuation))
line = line.translate(str.maketrans('','',string.digits))
line = line.translate(str.maketrans('','',string.whitespace))
line = line.translate(str.maketrans('','',""" '"’‘“” """))
line = line.lower()
index = 0
while index < len(line):
if line[index] not in counts:
counts[line[index]] = 1
else:
counts[line[index]] += 1
index += 1
print('Currently at line: ', currentline, 'of', filelength)
currentline += 1
listtosort = list()
totalcount = 0
for (char, number) in list(counts.items()):
listtosort.append((number,char))
totalcount = totalcount + number
listtosort.sort(reverse=True)
for (number, char) in listtosort:
frequency = number/totalcount*100
print ('Character: %s, count: %d, Frequency: %g' % (char, number, frequency))
It looks fine the way you are doing it, however to simulate your problem, I downloaded and saved a Guttenberg text book. It's a unicode issue. Two ways to resolve it. Open it as a binary file or add the encoding. As it's text, I'd go the utf-8 option.
I'd also suggest you code it differently, below is the basic structure that closes the file after opening it.
filename = "GutenbergBook.txt"
try:
#fhand = open(filename, 'rb')
#open read only and utf-8 encoding
fhand = open(filename, 'r', encoding = 'utf-8')
except IOError:
print("couldn't find the file")
else:
try:
for line in fhand:
#put your code here
print(line)
except:
print("Error reading the file")
finally:
fhand.close()
For the op, this is a specific occasion. However, for visitors, if your code below the for state does not execute, it is not a python built-in issue, most likely to be: an exception error handling in parent caller.
Your iteration is inside a function, which is called inside a try except block of caller, then if any error occur during the loop, it will get escaped.
This issue can be hard to find, especially when you dealing with intricate architecture.

How can i check to see if somethings already written to a txt and give an error if so python

I am doing a school project and I have to make a voting system that uses a voting code. I need help with the code that opens up the 2 files, checks to see if the code is there and gives a value error if it is.
while True:
Code = input("Enter your 6 digit code: ")
try:
Code = int(Code)
if "0" in str(Code): break
if len(str(Code)) != 6 : raise ValueError
else: break
readt = open("Trump.txt" , "r")
readh = open("Clinton.txt" , "r")
readhh = readh.read()
readtt = readt.read()
if Code in str(readtt) or Code in str(readhh): raise ValueError
else: break
readt.close()
readh.close()
except ValueError:
print("Invalid")
Here are a couple pointers to fix your program:
The if len ... else part seems to leave the while loop either through raise or break. The code that does open is never executed.
Also you call open a lot of times. This will become problematic because leaking file descriptors is a problem. Use the with open(...) statement for this. This way, you cannot leave the file open by accident. Your close statements are behind another if ... else construction that will leave the loop in every case.
Your variable names are a bit opaque, perhaps you want to invent some more telling ones.
Why are there two files? Shouldn't there be only one file that contains all the used codes?
Assuming that you presented all the information in your question this is the solution for your problem:
def code_checker():
codes = []
with open('Trump.txt', 'r') as f1:
for line in f1:
codes.append(line.rstrip())
with open('Clinton.txt', 'r') as f2:
for line in f2:
codes.append(line.rstrip())
code = input('Enter your 6 digit code:\n')
while True:
if '0' in code or len(code) != 6:
print('Invalid code\n')
code = input()
continue
elif code in codes:
raise ValueError
code_checker()

Write command removing quotes and adding them at random

So I am programming in python 2.7 and I am trying to copy a text file line by line so that I can modify a few lines and save as a new file. I have everything working except the output file has a whole bunch of quotes(") removed and added? This is what one original line looks like:
"IECKAI" TurbModel - Turbulence model ("IECKAI"=Kaimal, "IECVKM"=von Karman, "GP_LLJ", "NWTCUP", "SMOOTH", "WF_UPW", "WF_07D", "WF_14D", "TIDAL", or "NONE")
When I run
f = open('C:\\Users\\bhansen\\Desktop\\TestEnv\\TurbSim2.inp', 'r')
NewInputFile = open('C:\\Users\\bhansen\\Desktop\\TestEnv\\MyInput.inp', 'wb')
for i in range(0, 66):
line = f.readline()
if i == 31:
num, stf = line.split(" ", 1)
num = '9'
new_line = num + stf
NewInputFile.write(new_line)
elif i == 36:
num, stf = line.split(' ', 1)
num = '8'
new_line = num + stf
NewInputFile.write(new_line)
else:
NewInputFile.write(line)
it gets written to the new file like this
"IECKAI TurbModel - Turbulence model ""(""""IECKAI""""=Kaimal,"" IECVKM=von Karman, GP_LLJ, NWTCUP, SMOOTH, WF_UPW, WF_07D, WF_14D, TIDAL, or NONE)"
Why is it going this and how do I fix it?
P.S. the given line was line 30 of the text file but it also does the same thing for the if statement lines
So I figured it out. After sending the source code and input file to someone else we found that for some reason (only this machine) didn't like reading from a .inp file. So we changed the read in file to a .txt file type but left the output file as a .inp (which it had to be for the program it was being passed to) and it worked just fine.

Resources