Python get data in this format - python

I have a small unit of code which is given below :
round = 4
chars = 68
for k in range(round):
if (k % 2) == 0:
Title = 'Start '+chr(chars)
else:
Title = 'Reached ' + chr(chars)
chars = chars - 1
print(Title)
Using this i am getting output like :
Start D
Reached C
Start B
Reached A
What i actually want is i want result like :
Start C
Reached B
Start B
Reached A
how can i get the title in this way please help me in related to this

chars = 67
counter = 1
while counter <= 4:
if (counter % 2) != 0:
title = 'Start '+chr(chars)
counter += 1
chars -= 1
else:
title = 'Reached ' + chr(chars)
counter += 1
print(title)
OUTPUT (as desired):
Start C
Reached B
Start B
Reached A
EXPLANATION:
I used a while loop to iterate over the loop, and incremented the counter variable by 1 after every iteration to make sure the loop will be iterated 4 times. For the first iteration, counter = 1, such that it is an odd number, and will print "Start " + chr(chars) . Chars is set to 67 by default, which represents the letter "C". I then subtracted 1 from chars to make it equal 66, or "B". On the next iteration, counter is equal to 2, so it will print "Reached B". No need to subtract from chars in this iteration, because we want chars to stay as "B" for the next iteration. I basically just repeated this logic in a loop and iterated over it 4 times, to achieve the desired output. Hope this helps!

round = 4
chars = 67
start = True
for k in range(round):
if(start):
print('start '+chr(chars))
start = False
chars = chars-1
else:
print('reached '+chr(chars))
start = True
this code gets your result
start C
reached B
start B
reached A

There are a few things that need to be fixed:
chr(68) represents the letter 'D', so you should initialize the variable chars = 67.
You also want the range to loop through values 1 to 4, so you want range(1,5) instead of range(4) which will loop through the values 0 to 3.
The print statement should be outside of your if/else statements so that it prints on each iteration of the loop.
round = 4
chars = 67
for k in range(1, round+1):
if (k % 2) == 0:
Title = 'Start '+chr(chars)
else:
Title = 'Reached ' + chr(chars)
chars = chars - 1
print(Title)
Output:
Reached C
Start B
Reached B
Start A

A few things to consider while coding. You want to avoid defining variables that have same name as a python function. For example round is a function in python and you have a variable round assigned to 4. I changed it to r instead.
Also chr(68) is D so started the program at 67 to get you the desired result. When it loops first time, the value of k will be 0. That results in the if (k % 2 == 0 to true. That's why you should start with 67.
Also, your print(Title) was not indented correctly. I moved it outside the if-else statement so it can print correctly.
The only change you had to do to your code was in two places. chars = 67 and subtract the value of chars before you assign the new value to Title with Reached.
r = 4 #changed the variable name to r. round is a function
chars = 67 #started with 67 to give you C instead of D
for k in range(r): #used r instead of round
if (k % 2) == 0:
Title = 'Start '+ chr(chars)
else:
chars = chars - 1 #moved this line before you reassign value to Title
Title = 'Reached ' + chr(chars)
print(Title) #modified the indentation to print after each iteration
Output:
Start C
Reached B
Start B
Reached A
Hope this helps you understand the changes and implementation of your code.

Related

How to compare two strings by character and print matching positions in python

I want to compare two strings by character and then print how many times they have the same character in the same position. If I were to input 'soon' and 'moon' as the two strings, it would print that they match in 3 positions.
I've run into another problem where if the 2nd string is shorter, it gives me an error "string index out of range".
I tried
a = input('Enter string')
b = input('Enter string')
i=0
count = 0
while i<len(a):
if b[i] == a[i]:
match = match + 1
i = i + 1
print(match, 'positions.')
You have some extraneous code in the form of the 2nd if statement and you don't have the match incrementor in the first if statement. You also don't need the found variable. This code should solve the problem
# get input from the user
A = input('Enter string')
B = input('Enter string')
# set the incrementors to 0
i=0
match = 0
# loop through every character in the string.
# Note, you may want to check to ensure that A and B are the same lengths.
while i<len(A):
# if the current characters of A and B are the same advance the match incrementor
if B[i] == A[I]:
# This is the important change. In your code this line
# is outside the if statement, so it advances for every
# character that is checked not every character that passes.
match = match + 1
# Move to the next character
i = i + 1
# Display the output to the user.
print(match, 'positions.')
num_matching = 0
a = "Hello"
b = "Yellow"
shortest_string = a if len(a) <= len(b) else b
longest_string = b if shortest_string == a else a
for idx, val in enumerate(shortest_string):
if val == b[idx]:
num_matching += 1
print(f"In {a} & {b} there are {num_matching} characters in the same position!")
Simplifying my answer in light of #gog's insight regarding zip versus zip_longest:
string1 = "soon"
string2 = "moon"
matching_positions = 0
for c1, c2 in zip(string1, string2):
if c1 == c2:
matching_positions += 1
print(matching_positions)
Output:
3

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.)

How do I go about ending this loop?

I am trying to count the longest length of string in alphabetical order
s = 'abcv'
longest = 1
current = 1
for i in range (len(s) - 1):
if s[i] <= s[i+1]:
current += 1
else:
if current > longest:
longest = current
current = 0
i += 1
print longest
For this specific string, 'Current' ends up at the correct length, 4, but never modifies longest.
EDIT: The following code now runs into an error
s = 'abcv'
current = 1
biggest = 0
for i in range(len(s) - 1):
while s[i] <= s[i+1]:
current += 1
i += 1
if current > biggest:
biggest = current
current = 0
print biggest
It seems my logic is correct , but I run into errors for certain strings. :(
Although code sources are available on the internet which print the longest string, I can't seem to find how to print the longest length.
break will jump behind the loop (to sam indentation as the for statement. continue will jump to start of loop and do the next iteration
Your logic in the else: statement does not work - you need to indent it one less.
if s[i] <= s[i+1]:
checks for "is actual char less or equal then next char" - if this is the case you need to increment your internal counter and set longest if it is longer
You might get into trouble with if s[i] <= s[i+1]: - you are doing it till len(s)-1. "jfjfjf" is len("jfjfjf") = 6 - you would iterate from 0 to 5 - but the if accesses s[5] and s[6] which is more then there are items.
A different approach without going over explicit indexes and split into two responsibilities (get list of alphabetical substring, order them longest first):
# split string into list of substrings that internally are alphabetically ordered (<=)
def getAlphabeticalSplits(s):
result = []
temp = ""
for c in s: # just use all characters in s
# if temp is empty or the last char in it is less/euqal to current char
if temp == "" or temp[-1] <= c:
temp += c # append it to the temp substring
else:
result.append(temp) # else add it to the list of substrings
temp = "" # and clear tem
# done with all chars, return list of substrings
return result
# return the splitted list as copy after sorting reverse by length
def SortAlphSplits(sp, rev = True):
return sorted(sp, key=lambda x: len(x), reverse=rev)
splitter = getAlphabeticalSplits("akdsfabcdemfjklmnopqrjdhsgt")
print(splitter)
sortedSplitter = SortAlphSplits(splitter)
print (sortedSplitter)
print(len(sortedSplitter[0]))
Output:
['ak', 's', 'abcdem', 'jklmnopqr', 'dhs']
['jklmnopqr', 'abcdem', 'dhs', 'ak', 's']
9
This one returns the array of splits + sorts them by length descending. In a critical environment this costs more memory then yours as you only cache some numbers whereas the other approach fills lists and copies it into a sorted one.
To solve your codes index problem change your logic slightly:
Start at the second character and test if the one before is less that this. That way you will ever check this char with the one before
s = 'abcvabcdefga'
current = 0
biggest = 0
for i in range(1,len(s)): # compares the index[1] with [0] , 2 with 1 etc
if s[i] >= s[i-1]: # this char is bigger/equal last char
current += 1
biggest = max(current,biggest)
else:
current = 1
print biggest
You have to edit out the else statement. Because consider the case where the current just exceeds longest, i.e, from current = 3 and longest =3 , current becomes 4 by incrementing itself. Now here , you still want it to go inside the if current > longest statement
s = 'abcv'
longest = 1
current = 1
for i in range (len(s) - 1):
if s[i] <= s[i+1]:
current += 1
#else:
if current > longest:
longest = current
current = 0
i += 1
longest = current
print longest
Use a while condition loop, then you can easy define, at what condition your loop is done.
If you want QualityCode for longterm:
While loop is better practice than a break, because you see the Looping condition at one place. The simple break is often worse to recognize inbetween the loopbody.
At the end of the loop, current is the length of the last substring in ascending order. Assigning it to longest is not right as the last substring in ascending is not necessarily the longest.
So longest=max(current,longest) instead of longest=current after the loop, should solve it for you.
Edit: ^ was for before the edit. You just need to add longest=max(current,longest) after the for loop, for the same reason (the last ascending substring is not considered). Something like this:
s = 'abcv'
longest = 1
current = 1
for i in range (len(s) - 1):
if s[i] <= s[i+1]:
current += 1
else:
if current > longest:
longest = current
current = 0
i += 1
longest=max(current,longest) #extra
print longest
The loop ends when there is no code after the tab space so technically your loop has already ended

How to count specific substrings using slice notation

I want to count the number of occurrences of the substring "bob" within the string s. I do this exercise for an edX Course.
s = 'azcbobobegghakl'
counter = 0
numofiterations = len(s)
position = 0
#loop that goes through the string char by char
for iteration in range(numofiterations):
if s[position] == "b": # search pos. for starting point
if s[position+1:position+2] == "ob": # check if complete
counter += 1
position +=1
print("Number of times bob occurs is: " + str(counter))
However it seems that the s[position+1:position+2] statement is not working properly. How do i adress the two chars behind a "b"?
The second slice index isn't included. It means that s[position+1:position+2] is a single character at position position + 1, and this substring cannot be equal to ob. See a related answer. You need [:position + 3]:
s = 'azcbobobegghakl'
counter = 0
numofiterations = len(s)
position = 0
#loop that goes through the string char by char
for iteration in range(numofiterations - 2):
if s[position] == "b": # search pos. for starting point
if s[position+1:position+3] == "ob": # check if complete
counter += 1
position +=1
print("Number of times bob occurs is: " + str(counter))
# 2
You could use .find with an index:
s = 'azcbobobegghakl'
needle = 'bob'
idx = -1; cnt = 0
while True:
idx = s.find(needle, idx+1)
if idx >= 0:
cnt += 1
else:
break
print("{} was found {} times.".format(needle, cnt))
# bob was found 2 times.
Eric's answer explains perfectly why your approach didn't work (slicing in Python is end-exclusive), but let me propose another option:
s = 'azcbobobegghakl'
substrings = [s[i:] for i in range(0, len(s))]
filtered_s = filter(substrings, lambda s: s.startswith("bob"))
result = len(filtered_s)
or simply
s = 'azcbobobegghakl'
result = sum(1 for ss in [s[i:] for i in range(0, len(s))] if ss.startswith("bob"))

Python Convert String Literal to Float

I am working through the book "Introduction to Computation and Programming Using Python" by Dr. Guttag. I am working on the finger exercises for Chapter 3. I am stuck. It is section 3.2, page 25. The exercise is: Let s be a string that contains a sequence of decimal numbers separated by commas, e.g., s = '1.23,2.4,3.123'. Write a program that prints the sume of the numbers in s.
The previous example was:
total = 0
for c in '123456789':
total += int(c)
print total.
I've tried and tried but keep getting various errors. Here's my latest attempt.
total = 0
s = '1.23,2.4,3.123'
print s
float(s)
for c in s:
total += c
print c
print total
print 'The total should be ', 1.23+2.4+3.123
I get ValueError: invalid literal for float(): 1.23,2.4,3.123.
Floating point values cannot have a comma. You are passing 1.23,2.4,3.123 as it is to float function, which is not valid. First split the string based on comma,
s = "1.23,2.4,3.123"
print s.split(",") # ['1.23', '2.4', '3.123']
Then convert each and and every element of that list to float and add them together to get the result. To feel the power of Python, this particular problem can be solved in the following ways.
You can find the total, like this
s = "1.23,2.4,3.123"
total = sum(map(float, s.split(",")))
If the number of elements is going to be too large, you can use a generator expression, like this
total = sum(float(item) for item in s.split(","))
All these versions will produce the same result as
total, s = 0, "1.23,2.4,3.123"
for current_number in s.split(","):
total += float(current_number)
Since you are starting with Python, you could try this simple approach:
Use the split(c) function, where c is a delimiter. With this you will have a list numbers (in the code below). Then you can iterate over each element of that list, casting each number to a float (because elements of numbers are strings) and sum them:
numbers = s.split(',')
sum = 0
for e in numbers:
sum += float(e)
print sum
Output:
6.753
From the book Introduction to Computation and Programming using Python at page 25.
"Let s be a string that contains a sequence of decimal numbers separated by commas, e.g., s
= '1.23,2.4,3.123'. Write a program that prints the sum of the numbers in s."
If we use only what has been taught so far, then this code is one approach:
tmp = ''
num = 0
print('Enter a string of decimal numbers separated by comma:')
s = input('Enter the string: ')
for ch in s:
if ch != ',':
tmp = tmp + ch
elif ch == ',':
num = num + float(tmp)
tmp = ''
# Also include last float number in sum and show result
print('The sum of all numbers is:', num + float(tmp))
total = 0
s = '1.23,2.4,3.123'
for c in s.split(','):
total = total + float(c)
print(total)
Works Like A Charm
Only used what i have learned yet
s = raw_input('Enter a string that contains a sequence of decimal ' +
'numbers separated by commas, e.g. 1.23,2.4,3.123: ')
s = "," + s+ ","
total =0
for i in range(0,len(s)):
if s[i] == ",":
for j in range(1,(len(s)-i)):
if s[i+j] == ","
total = total + float(s[(i+1):(i+j)])
break
print total
This is what I came up with:
s = raw_input('Enter a sequence of decimal numbers separated by commas: ')
aux = ''
total = 0
for c in s:
aux = aux + c
if c == ',':
total = total + float(aux[0:len(aux)-1])
aux = ''
total = total + float(aux) ##Uses last value stored in aux
print 'The sum of the numbers entered is ', total
I think they've revised this textbook since this question was asked (and some of the other's have answered.) I have the second edition of the text and the split example is not on page 25. There's nothing prior to this lesson that shows you how to use split.
I wound up finding a different way of doing it using regular expressions. Here's my code:
# Intro to Python
# Chapter 3.2
# Finger Exercises
# Write a program that totals a sequence of decimal numbers
import re
total = 0 # initialize the running total
for s in re.findall(r'\d+\.\d+','1.23, 2.2, 5.4, 11.32, 18.1,22.1,19.0'):
total = total + float(s)
print(total)
I've never considered myself dense when it comes to learning new things, but I'm having a hard time with (most of) the finger exercises in this book so far.
s = input('Enter a sequence of decimal numbers separated by commas: ')
x = ''
sum = 0.0
for c in s:
if c != ',':
x = x + c
else:
sum = sum + float(x)
x = ''
sum = sum + float(x)
print(sum)
This is using just the ideas already covered in the book at this point. Basically it goes through each character in the original string, s, using string addition to add each one to the next to build a new string, x, until it encounters a comma, at which point it changes what it has as x to a float and adds it to the sum variable, which started at zero. It then resets x back to an empty string and repeats until all the characters in s have been covered
Here's a solution without using split:
s='1.23,2.4,3.123,5.45343'
pos=[0]
total=0
for i in range(0,len(s)):
if s[i]==',':
pos.append(len(s[0:i]))
pos.append(len(s))
for j in range(len(pos)-1):
if j==0:
num=float(s[pos[j]:pos[j+1]])
total=total+num
else:
num=float(s[pos[j]+1:pos[j+1]])
total=total+num
print total
My way works:
s = '1.23, 211.3'
total = 0
for x in s:
for i in x:
if i != ',' and i != ' ' and i != '.':
total = total + int(i)
print total
My answer is here:
s = '1.23,2.4,3.123'
sum = 0
is_int_part = True
n = 0
for c in s:
if c == '.':
is_int_part = False
elif c == ',':
if is_int_part == True:
total += sum
else:
total += sum/10.0**n
sum = 0
is_int_part = True
n = 0
else:
sum *= 10
sum += int(c)
if is_int_part == False:
n += 1
if is_int_part == True:
total += sum
else:
total += sum/10.0**n
print total
I have managed to answer the question with the knowledge gained up until 3.2 the section for loop
s = '1.0, 1.1, 1.2'
print 'List of decimal number'
print s
total = 0.0
for c in s:
if c == ',':
total += float(s[0:(s.index(','))])
d = int(s.index(','))+1
s = s[(d+1) : len(s)]
s = float(s)
total += s
print '1.0 + 1.1 + 1.2 = ', total
This is the answer to the question i feel that the split function is not good for beginner like you and me.
Considering the fact that you might not yet be exposed to more complex functions, simply try these out.
total = 0
for c in "1.23","2.4",3.123":
total += float(c)
print total
My answer:
s = '2.1,2.0'
countI = 0
countF = 0
totalS = 0
for num in s:
if num == ',' or (countF + 1 == len(s)):
totalS += float(s[countI:countF])
if countF < len(s):
countI = countF + 1
countF += 1
print(totalS) # 4.1
This only works if the numbers are floats
Here is my answer. It is similar to the one by user5716300 above, but since I am also a beginner I explicitly created a separate variable s1 for the split string:
s = "1.23,2.4,3.123"
s1 = s.split(",") #this creates a list of strings
count = 0.0
for i in s1:
count = count + float(i)
print(count)
If we are just sticking with the content for that chapter, I came up with this: (though using that sum method mentioned by theFourthEye is also pretty slick):
s = '1.23,3.4,4.5'
result = s.split(',')
result = list(map(float, result))
n = 0
add = 0
for a in result:
add = add + result[n]
n = n + 1
print(add)
I just wanna to post my answer because I am reading this book now.
s = '1.23,2.4,3.123'
ans = 0.0
i = 0
j = 0
for c in s:
if c == ',':
ans += float(s[i:j])
i = j + 1
j += 1
ans += float(s[i:j])
print(str(ans))
Using knowledge from the book:
s = '4.58,2.399,3.1456,7.655,9.343'
total = 0
index = 0
for string in s:
index += 1
if string == ',':
temp = float(s[:index-1])
s = s[index:]
index = 0
total += temp
temp = 0
print(total)
Here I used string slicing, and by slicing the original string every time our 'string' variable is equal to ','. Also using an index variable to keep track of the number that is before the comma. After slicing the string, the number that gets input into tmp is cleared with the comma in front of it, the string becoming another string without that number.
Because of this, the index variable needs to be reset every time this happens.
Here's mine using the exact string in the question and only what has been taught so far.
total = 0
temp_num = ''
for char in '1.23,2.4,3.123':
if char == ',':
total += float(temp_num)
temp_num = ''
else:
temp_num += char
total += float(temp_num) #to catch the last number that has no comma after it
print(total)
I know this isn't covered in the book up to this point but I happened to learn the use of the eval() function on my own prior to getting to this question and used it to solve.
total = 0
s = "1.23,2.4,3.123"
x = eval(s)
y = sum(x)
print(y)
I think this is the easiest way to answer the question. It uses the split command, which is not introduced in the book at this moment but a very useful command.
s = input('Insert string of decimals, e,g, 1.4,5.55,12.651:')
sList = s.split(',') #create a list of these values
print(sList) #to check if list is correctly created
total = 0 #for creating the variable
for each in sList:
total = total + float(each)
print(total)
total =0
s = {1.23,2.4,3.123}
for c in s:
total = total+float(c)
print(total)

Categories