Why count doesn't behave normal in python for loop - python

I have a text file I'm reading from and just threw a counter on there to make sure I grabbed everything but when I implemented a simple counter it acted weird. It works now but I had to do the following:
f = open("street.txt", "r")
l = ""
count = -1
for line in f:
if(line[0].isdigit()):
l = line.replace('\n', '')
else:
count=count+1
l = l + " " + line.replace('\n', '')
c = str(count) + ')'
print(c + l + '\n')
Essentially I was attempting to just run through this file, add every other line to the previous line then number them just as a check with a count variable, that I covered everything. For some reason when the count was running it started at 2 when I had count initially set to 0. It wouldn't print out "1)" until I changed count to -1 initially. That print statement is an L, not a 1. I have no idea why it was doing that. I didn't get an error, it ran fine just with the wrong numbers for about 4-5 runs. And that's an L in the print statement...which should be fairly obvious from the if statement but just in case.

Just initialize count with 0 and increment statement should be in the last.
l = l + " " + line.replace('\n', '')
c = str(count) + ')'
print(c + l + '\n')
count+=1

Related

Can you explain me the RLE algorithm code in python

I I've finally found how to make a RLE algorithm by watching a tutorial but This tutorial didn' t explain something in that code I didn't get why we write j = i instead of j = 0 (Knowing that I = 0) it's the same no ?
I didn't get why i = j + 1 either. Why i = j + 1 At the end of the function ? Why not simply i += 1 but if we want to repeat a loop in a loop then we do j + 1 ?
Did the first while loop is supposed to repeat the second while loop until the string is finished ?
And finally why encoded_message is repeated two times ? instead of one. We return encoded_message so that's it ? We can simply do print(encode(text)) instead of
"print('The encoded message is the output ',encoded_message)" (when we put encode(text) into encoded_message)
I know i'm asking a lot of questions but I just can't memorize the code without understanding it, it would be totally useless and unproductive
def encode(message):
encoded_message = ""
i = 0
while(i<len(message)):
count = 1
ch = message[i]
j = i # ???
while(j<len(message)-1): # GET IT -----------------------------------------------------------
if message[j] == message[j+1]: # if the previous and next characters are the same
count = count + 1 # we increase count variable
j += 1 # we increase j position
# GET IT ----------------------------------------------------------------------------
else:
break
encoded_message = encoded_message + str(count) + ch # "" + count converted to string + character (ch)
i = j + 1 # ???
return encoded_message
text = input('enter your charcter chain...')
encoded_message = encode(text)
print('The encoded message is the output ',encoded_message)
When I replaced j = i by j = 0 nothing is displayed in the terminal
see : no result
There is an outer loop and an inner loop. The outer loop with the variable i starts iterating over the message. The inner loop uses the variable j and starts at the current position of i.
That is: when i=0 then j=0. But when i=5 (for example) then j=5 also.
The inner loops task is to check whether 2 or more identical characters follow one another. If they do i is increased accordingly at the end of the inner loop. So that each letter of the message is only looked at once.
That is why j should not be set to a constant value. Setting it to j=0 would cause the inner loop to start at the beginning of the message at every iteration.
I added two simple print() statements to your code to clarify:
def encode(message):
encoded_message = ""
i = 0
while(i<len(message)):
print(f'outer loop: i={i}')
count = 1
ch = message[i]
j = i
while(j<len(message)-1):
print(f'\tinner loop: j={j}')
if message[j] == message[j+1]: # if the previous and next characters are the same
count = count + 1 # we increase count variable
j += 1 # we increase j position
else:
break
encoded_message = encoded_message + str(count) + ch # "" + count converted to string + character (ch)
i = j + 1
return encoded_message
text = 'Hello World'
encoded_message = encode(text)
print('The encoded message is the output ', encoded_message)
(Please note: I do not know the RLE algorithm but just looked at your code.)

Sum of Digits in a specific way in Python

I'm looking for a code that runs, i.e:
int(input) = 2565
Printed Output should be like:
2 + 5 + 6 + 5 = 18 = 1 + 8 = 9
I wrote the code that gives final answer "9". But I couldn't managed to write it with every digit separated "+" sign. Assuming that I need to use while loop but how can I write the code so it will be like the output above?
You can use something like this:
def sum_of_digits(s):
if s < 10:
return s
return sum_of_digits(sum(int(c) for c in str(s)))
> sum_of_digits(2565)
9
It recursively checks if the numerical value is less than 10. If it does, it returns this value. If not, it adds the digits, then recursively calls itself on the result.
Edit
To print out the steps as it goes along, you could do something like this:
def sum_of_digits(s):
if s < 10:
print(s)
return s
print(' + '.join(c for c in str(s)) + ' = ')
return sum_of_digits(sum(int(c) for c in str(s)))
First, initiate an empty string output_str.
With a while loop which contniues when our integer is > 9:
[s for s in str(x)] would create a list of the digits (as strings) of our integer. It's called a list comprehension, is very useful, and my advice is to read a bit about it.
With " + ".join() we create a string with " + " between the
digits. Add this string at the end of output_str.
Add " = " to the end of output_str.
Calculate the sum of the digits (we cannot use sum(lst_of_digits) because it's a list of strings. sum([int(s) for s in lst_of_digits]) converts the string list into an inter list, which can be summed using sum()). Store the sum into x.
Add the new x + " = " to output_string.
At the end of the string, we have a redundant " = " (because the last (5) was not needed), let's just remove the last 3 chars (=) from it.
x = 2565
output_str = ""
while x > 9:
lst_of_digits = [s for s in str(x)]
output_str += " + ".join(lst_of_digits)
output_str += " = "
x = sum([int(s) for s in lst_of_digits])
output_str += f"{x} = "
output_str = output_str[:-3]
outputs:
output_str = '2 + 5 + 6 + 5 = 18 = 1 + 8 = 9'
You can play around with the end keyword argument of the print function which is the last character/string that print will put after all of its arguments are, well, printed, by default is "\n" but it can be change to your desire.
And the .join method from string which put the given string between the given list/iterable of strings to get the desire result:
>>> " + ".join("123")
'1 + 2 + 3'
>>>
Mixing it all together:
def sum_digit(n):
s = sum(map(int,str(n)))
print(" + ".join(str(n)),"=",s, end="")
if s<10:
print()
return s
else:
print(" = ",end="")
return sum_digit(s)
Here we first get the sum of the digit on s, and print it as desire, with end="" print will not go to the next line which is necessary for the recursive step, then we check if done, and in that case print a new empty line if not we print an additional = to tie it for the next recursive step
>>> sum_digit(2565)
2 + 5 + 6 + 5 = 18 = 1 + 8 = 9
9
>>>
This can be easily be modify to just return the accumulated string by adding an extra argument or to be iterative but I leave those as exercise for the reader :)
I am a noob but this should do what you want.
Cheers,
Guglielmo
import math
import sys
def sumdigits(number):
digits = []
for i in range( int(math.log10(number)) + 1):
digits.append(int(number%10))
number = number/10
digits.reverse()
string = ''
thesum = 0
for i,x in enumerate(digits):
string += str(x)
thesum += x
if i != len(digits)-1: string += ' + '
else: string += ' = '
if thesum > 10:
return string,thesum,int(math.log10(number))+1
else:
return string,thesum,0
def main():
number = float(sys.argv[1])
finalstring = ''
string,thesum,order = sumdigits(number)
finalstring += string
finalstring += str(thesum)
while order > 0:
finalstring += ' = '
string,thesum,order = sumdigits(thesum)
finalstring += string
finalstring += str(thesum)
print 'myinput = ',int(number)
print 'Output = ',finalstring
if __name__ == "__main__":
main()

Wrong order of elements when appending to .csv

Here is a sample of my current code
for i in pin:
i.click()
time.sleep(4)
f = driver.find_elements_by_xpath('//td[#class="bold"]')
d = driver.find_elements_by_xpath('//td[#class="date"]')
with open("tennisopening.csv","a") as r:
r.write(match + "," + date + "," + score + "\n")
for i in f:
b= i.text
for i in d:
c= i.text
with open("tennisopening.csv","a") as r:
r.write(b + "," + c)
This results in a csv table with cells in the following order:
(b,c,match,date,score,\n)
But, I wish to have it in the following order:
(match,date,score,b,c,\n)
How can I fix this?
Thank you
for i in pin:
i.click()
time.sleep(4)
f = driver.find_elements_by_xpath('//td[#class="bold"]')
d = driver.find_elements_by_xpath('//td[#class="date"]')
with open("tennisopening.csv","a") as r:
for i in f:
b= i.text
for i in d:
c= i.text
with open("tennisopening.csv","a") as r:
r.write(b + "," + c)
r.write(match + "," + date + "," + score + "\n")
This will do
Remember when u write using
with open(filename,mode) as f:
f.write(data)
## data is written only in memory and not yet committed to file.
## data now committed to file
so for the data to be written you must come out of with open() scope
same goes for above data
First come out of this with's scope
with open("tennisopening.csv","a") as r:
r.write(b + "," + c)
and then write into memory
r.write(match + "," + date + "," + score + "\n")
Then come out of parent with scope
;)
Change your inner loop code with this:
with open("tennisopening.csv","a") as r:
for i in f:
b= i.text
for i in d:
c= i.text
r.write("{},{},{},{},{}\n".format(match,date,score,b,c)
This should write "match,date,score,b,c\n" in every line as you asked.
In your code, (match, date, score) will be written only once for every outer loop code.
And you have two instances open for the same file, the instance which writes "b,c" closes first, so it gets written first in the actual file.

How to print numbers in steps using function python

Am trying to write a function to print numbers in steps.Here is my code
def steps(num):
v = num
for i in range(1, v+1):
print(" "*i + str(i)*3)
print(steps(3))
The result appears as
111
222
333
None
I am trying to get rid of the "none" word any help? Note please, i don't want to get rid of the print statement in "print(steps(3)), any other method or solution will be welcomed.
You need to output the spaces yourself like so:
for i in range(1, v + 1):
print(" " * i + str(i) * 3)
def steps(number):
mystr = ""
for i in range(1, number + 1):
mystr += 3*str(i) + '\n' + i*'\t'
return mystr

Counting a string within a file in python

I have 10 files with 100 random numbers named randomnumbers(1-10).py. I want to create a program which says "congratulations" when a string of 123 is found and count the number of times 123 shows up as well. I have the "congratulations" part and I have written code for the counting part but I always get zero as a result. What's wrong?
for j in range(0,10):
n = './randomnumbers' + str(j) + '.py'
s='congradulations'
z='123'
def replacemachine(n, z, s):
file = open(n, 'r')
text=file.read()
file.close()
file = open(n, 'w')
file.write(text.replace(z, s))
file.close()
print "complete"
replacemachine(n, z, s)
count = 0
if 'z' in n:
count = count + 1
else:
pass
print count
if 'z' in n is testing to see if the literal string 'z' is in the filename n. Since you only open the file within replacemachine, you can't access the file contents from outside.
Best solution would be to just count the occurrences from within replacemachine:
def replacemachine(n, z, s):
file = open(n, 'r')
text=file.read()
file.close()
if '123' in text:
print 'number of 123:', text.count('123')
file = open(n, 'w')
file.write(text.replace(z, s))
file.close()
print "complete"
Then you don't need that code after replacemachine(n, z, s).
consider:
some_file_as_string = """\
184312345294839485949182
57485348595848512493958123
5948395849258574827384123
8594857241239584958312"""
num_found = some_file_as_string.count('123')
if num_found > 0:
print('num found: {}'.format(num_found))
else:
print('no matches found')
Doing an '123' in some_file_as_string is a little wasteful, because it still needs to look through the entire string. You might as well count anyway and do something when the count returns more than 0.
You also have this
if 'z' in n:
count = count + 1
else:
pass
print count
Which is asking if the string 'z' is present, you should be checking for z the variable instead (without the quote)

Categories