Breaking a loop - python

Hello im trying to make an mp3 player. At the moment Im just trying to get it to print the found mp3 file to the console but its stuck in an infinate loop and Im not sure how to break it as im still new to python
def mp3_finder():
times_done = 5
starting = 0
for file in os.listdir(full_dir):
if file.endswith(".mp3"):
while starting < times_done:
starting = starting + 1
print(file)
return mp3_finder()
EDIT:
Sorry i wasnt very clear but what im trying to do is find the mp3 file and print the name to the console 5 times but because it keeps finding the file it keeps printing it to the console until python stops it because it printed hundreds of it

You're calling the function again in the return statement; since you're printing within the function, you can just remove the return entirely.
def mp3_finder():
times_done = 5
starting = 0
for file in os.listdir(full_dir):
if file.endswith(".mp3"):
while starting < times_done:
starting = starting + 1
print(file)
That answers your question about breaking a loop, but perhaps you should ask another one about your code, because I don't think it's going to give you the output you want.

First of all you should probably not call mp3_finder at the end of the function - it will recurse infinitly. Also you probably don't want the inner loop, it wil just print the first file five times. Combined the result will be that the function prints the first file five times, then it calls itself which again prints the first file five times and so on until you reach maximum recursion depth.
What you want to return isn't clear maybe it's OK to just return None (ie skip the return statement entirely). Second you'll need to break out of the loop when you're done.
def mp3_finder():
times_done = 5
starting = 0
for file in os.listdir(full_dir):
if file.endswith(".mp3"):
if starting < times_done:
starting = starting + 1
print(file)
else:
break

def mp3_finder():
times_done = 5
starting = 0
for file in os.listdir(full_dir):
if file.endswith(".mp3"):
while starting < times_done:
starting = starting + 1
print(file)
mp3_finder()
Watch your indent otherwise looks good

Related

Copy specified number of lines to multiple documents with a Python script that can be run from the command line

I am trying to build a script that copies a specified number of lines from one document to multiple other documents. The copied lines are supposed to be appended to the end of the docs. In case I want to delete lines from the end of the docs, the script also has to be able to delete a specified number of lines.
I want to be able to run the script from the command line and want to pass two args:
"add" or "del"
number of lines (counting from the end of the document)
A command could look like this:
py doccopy.py add 2 which would copy the last 2 lines to the other docs, or:
py doccopy.py del 4 which would delete the last 4 lines from all docs.
So far, I have written a function that copies the number of lines I want from the original document,
def copy_last_lines(number_of_lines):
line_offset = [0]
offset = 0
for line in file_to_copy_from:
line_offset.append(offset)
offset += len(line)
file_to_copy_from.seek(line_offset[number_of_lines])
changedlines = file_to_copy_from.read()
a function that pastes said lines to a document
def add_to_file():
doc = open(files_to_write[file_number], "a")
doc.write("\n")
doc.write(changedlines.strip())
doc.close()
and a main function:
def main(action, number_of_lines):
if action == "add":
for files in files_to_write:
add_to_file()
elif action == "del":
for files in files_to_write:
del_from_file()
else:
print("Not a valid action.")
The main function isn't done yet, of course and I have yet to figure out how to realize the del_from_file function.
I also have problems with looping through all the documents.
My idea was to make a list including all the paths to the documents i want to write in and then loop through this list and to make a single variable for the "original" document, but I don't know if that's even possible the way I want to do it.
If possible, maybe someone has an idea for how to realize all this with a single list, have the "original" document be the first entry and loop through the list starting with "1" when writing to the other docs.
I realize that the code I've done so far is a total clusterfuck and I ask a lot of questions, so I'd be grateful for every bit of help. I'm totally new to programming, I just did a Python crash course in the last 3 days and my first own project is shaping out to be way more complicated than I thought it would be.
This should do what you ask, I think.
# ./doccopy.py add src N dst...
# Appends the last N lines of src to all of the dst files.
# ./doccopy.py del N dst...
# Removes the last N lines from all of the dst files.
import sys
def process_add(args):
# Fetch the last N lines of src.
src = argv[0]
count = int(args[1])
lines = open(src).readlines()[-count:]
# Copy to dst list.
for dst in args[2:}
open(dst,'a').write(''.join(lines))
def process_del(args):
# Delete the last N lines of each dst file.
count = int(args[0])
for dst in args[1:]:
lines = open(dst).readlines()[:-count]
open(dst,'w').write(''.join(lines))
def main():
if sys.argv[1] == 'add':
process_add( sys.argv[2:] )
elif sys.argv[1] == 'del':
process delete( sys.argv[2:] )
else:
print( "What?" )
if __name__ == "__main__":
main()

Please help me better understand this one "except"conditional line

I'm about a couple weeks into learning Python.
With the guidance of user:' Lost' here on Stackoverflow I was able to figure out how to build a simple decoder program. He suggested a code and I changed a few things but what was important for me was that I understood what was happening. I understand 97% of this code except for the except: i += 1 line in the decode(). As of now the code works, but I want to understand that line.
So basically this code unscrambles an encrypted word based on a specific criteria. You can enter this sample encrypted word to try it out. "0C1gA2uiT3hj3S" the answer should be "CATS"
I tried replacing the except: i += 1 with a Value Error because I have never seen a Try/Except conditional that just had an operational and no Error clause. But replacing it with Value Error created a never ending loop.
My question is what is the purpose of writing the except: i += 1 as it is.
'Lost' if you're there could you answer this question. Sorry, about the old thread
def unscramble(elist):
answer = []
i = 0
while i <= len(elist):
try:
if int(elist[i]) > -1:
i = i + int(elist[i]) + 1
answer.append(elist[i])
except:
i += 1
return "".join(answer)
def boom():
eword = input("paste in your encrypted message here >> ")
elist = list(eword)
answer = unscramble(elist)
print (answer)
clear()
boom()
The purpose is to advance i by one, skipping the current character in case the cast to int fails, i.e. if elist[i] is not a digit.
There are a couple of errors, than can occur inside the try-Block:
i is out of index, because the while loop runs one index to far.
elist[i] is not a number, which leads to an ValueError
i = i + int(elist[i]) + 1 gets to big, and the next index access leads also to an IndexError
In either way, the except-clause will ignore the next character. And the loop goes on.
An correct implementation wouldn't need any exceptions:
def unscramble(elist):
answer = []
i = 0
while i < len(elist):
i += int(elist[i]) + 1
answer.append(elist[i])
i += 1
return "".join(answer)

wx.TextCtrl GetLineLength wx.CallAfter not working

I am outputting the stderr to a wx.TextCtrl, after 10 lines I want to delete the first line so there is only ever a maximum of 10 lines in my wx.TextCtrl window.
I have a python script which is using multiple threads and classes. I just can't for the life of me get the below bit of code to work, can someone give me a few hints please?
a = 1
while True:
line = self.process1.stderr.readline().decode('utf-8')
wx.CallAfter(self.frame.running_log1.AppendText, line)
if a >= 10:
s = wx.CallAfter(self.frame.running_log1.GetLineLength, 0) +1
wx.CallAfter(self.frame.running_log1.Remove, 0, s)
print s
a +=1
When run s = None, so fails. I am using wx.CallAfter as I am using threads.
The reason wx.CallAfter returns None is because there isn't anything to return at that point. It can't return the length, because all it has done is made a note that at some point soon it needs to call the function. It hasn't actually called the function, and won't wait until the function has been called.
In this situation I would write a method that would append a line and remove the first line as necessary. This might look something like:
def appendAndTrim(self, line):
self.frame.running_log1.AppendText(line)
self.line_count += 1
if self.line_count > 10:
first_line_length = self.frame.running_log1.GetLineLength(0) + 1
self.frame.running_log1.Remove(0, first_line_length)
I would then pass this single method to wx.CallAfter, rather than making three separate calls to wx.CallAfter:
self.line_count = 0
while True:
line = self.process1.stderr.readline().decode('utf-8')
wx.CallAfter(self.appendAndTrim, line)

while loop in python issue

I started learning python few weeks ago (no prior programming knowledge) and got stuck with following issue I do not understand. Here is the code:
def run():
count = 1
while count<11:
return count
count=count+1
print run()
What confuses me is why does printing this function result in: 1?
Shouldn't it print: 10?
I do not want to make a list of values from 1 to 10 (just to make myself clear), so I do not want to append the values. I just want to increase the value of my count until it reaches 10.
What am I doing wrong?
Thank you.
The first thing that you do in the while loop is return the current value of count, which happens to be 1. The loop never actually runs past the first iteration. Python is indentation sensitive (and all languages that I know of are order-sensitive).
Move your return after the while loop.
def run():
count = 1
while count<11:
count=count+1
return count
Change to:
def run():
count = 1
while count<11:
count=count+1
return count
print run()
so you're returning the value after your loop.
Return ends the function early, prohibiting it from going on to the adding part.

Increment number in string

I am trying to get the following output until a certain condition is met.
test_1.jpg
test_2.jpg
..
test_50.jpg
The solution (if you could remotely call it that) that I have is
fileCount = 0
while (os.path.exists(dstPath)):
fileCount += 1
parts = os.path.splitext(dstPath)
dstPath = "%s_%d%s" % (parts[0], fileCount, parts[1])
however...this produces the following output.
test_1.jpg
test_1_2.jpg
test_1_2_3.jpg
.....etc
The Question: How do I get change the number in its current place (without appending numbers to the end)?
Ps. I'm using this for a file renaming tool.
UPDATE: Using various ideas below, i've discovered a loop that works
dstPathfmt = "%s_%d%s"
parts = os.path.splitext(dstPath)
fileCount = 0
while (os.path.exists(dstPath)):
fileCount += 1
dstPath = parts[0]+"_%d"%fileCount+parts[1]
It's probably easiest to keep dstPath something like "test_%d.jpg", and just pass it a varying count:
dstPath = "test_%d.jpg"
i = 1
while os.path.exists(dstPath % i):
i += 1
dstPath = dstPath % i # Final name
Print out the value of parts[0] each time you go round the loop ... I think you may be surprised,
It seems as though your condition os.path.exists(dstPath) is matching the same renamed file multiple times. So for example, it renames test.jpg to test_1.jpg; then renames test_1.jpg to test_1_2.jpg, etc.
for j in range(1,10):
print("test_{0}.jpg".format(j))
enter image description here
Update for Python v3.6+ - using formatted string literals:
for n in range(1,51):
print(f'test_{n}')

Categories

Resources