No iteration in nested while statement - python

How the loop should iterate. I'm a beginner trying to create a Python program to print a word backwards based on old knowledge from a few years ago. It does a few other things but they are just printed statements are don't pose a problem. Here is my code:
count = 0
while count < 100:
word_var = input("Enter ONE word with NO spaces:")
def split(word_var):
return list(word_var)
word_array = split(word_var)
m = 0
i = len(word_array)-1-m
print("The number of letters in your word is:", i)
while m < len(word_array):
if m < i:
word_array[m], word_array[i - m] = word_array[i - m], word_array[m]
m = m + 1
else:
break
m = m + 1
print(''.join(word_array))
count = count + 1
print("You've typed:",count,"word(s).")
Here is the problem section:
if m < i:
word_array[m], word_array[i - m] = word_array[i - m], word_array[m]
m = m + 1
else:
break
m = m + 1
My main problem is that it seems like the second while loop is not iterating when the word is more than five letters long. For example, if I input the word "should" into the program I get back out dhouls. It seems as if only one interchange of letters is being performed. I figure this is a problem with the if statement in that nested while loop, but I can't seem to find what is wrong with it. I carefully sketched out how I think the if statement works in the photo attached.

Your if condition is wrong. You want to compare the two indices that you will use in the list, but the second one is not i, but i-m. So change it to:
if m < i - m:
This corrects your issue. It should be noted that in Python you can reverse string just like this:
print(word_var[::-1])

There are two issues:
The counting of the letters isn't correct. You should just output the length of word_array.
You're iterating the while loop too many times. You should terminate it when m equals or exceeds len(word_array) // 2. Otherwise, you'll unreverse the letters and get the original word back.
i = len(word_array)-1
print("The number of letters in your word is:", len(word_array))
while m < len(word_array) // 2:
word_array[m], word_array[i - m] = word_array[i - m], word_array[m]
m = m + 1
This outputs:
Enter ONE word with NO spaces:should
The number of letters in your word is: 6
dluohs
You've typed: 1 word(s).

I like your project and appreciate your efforts.
This a another way to reverse a string using a list variable and the insert() method.
word_array = []
word_var = input('Your word : ')
word_array = []
for c in word_var:
word_array.insert(0, c)
word_reversed = ''.join(word_array)
print(word_var, '->', word_reversed)
output :
should -> dluohs

Related

Why is my function not prompting me to enter input?

I’m using Python IDE 3. My goal is this: If I have a string of text, ‘ABCDEFGHIJKL’, I want to sort it into groups, like three groups (‘ADGJ’,’BEHK’,’CFIL’). I require input for this, but the prompts aren’t showing up and I can’t type in input. Here’s my code:
#data
code_text = input('Text: ').lower()
code_skip = int(input('Shift length: '))
code_list = []
#function
def countSkip(text, shift, listt):
i = 0
group = 1
if group <= shift:
for e in text:
#make sure the set starts at the right place
if e.index()+1 < group:
pass
elif shift != 0:
if i = shift:
listt.append(e)
i = 0
i += 1
else:
listt.append(e)
group += 1
Calling the function
countSkip(code_text, code_shift, code_list)
There's a few things stopping your code from working that people have pointed out in the comments. Instead of trying to dissect your code and get that to work, I wrote a much more concise function that will get you the results you're after
def text_splitter(input_text, set_length):
num_sets = int(len(input_text)/set_length)
split_text = ["".join([input_text[(n * num_sets) + m] for n in range(set_length)]) for m in range(num_sets)]
return split_text
text_to_split = input('Text: ').lower()
len_set = int(input('Set Length: '))
text_list = text_splitter(text_to_split, len_set)
Sorry I was struggling to name the variables in an effective manner but the function above uses a list expression to get you the results you need. Keep in mind that if you use say a 7 letter string and ask for sets of length 2, the last letter won't be appended. However this shouldn't be too hard to check and correct. For example you could add this code to the function or around the initial input for the set length:
while len(input_text) % set_length != 0:
set_length = int(input("The text is length " + str(len(input_text)) + " please enter a different set length: "))

search through the word for the letter which comes alphabetically first, and returns that letter

I'm trying to write a code that basically requires me to find the letter that comes alphabetically first and print. Although the printing is required in another function. Need to use the while loop
this what I've gotten so far.
def alphabetically_first(word):
n = 0
p = 0
while n + 1 < len(word):
if word[n] < word[n+1]:
p = word[n]
elif word[n + 1] < word [n]:
p = word[n+1]
n += 1
print p
return

List Index Error on Python

Im writing a program to try to calculate how many times the most repeated word in a list occurs. I keep getting an error that says: index error. Even though when I print the list of my word_list, it shows there are 108 elements. Could someone point me in the right direction as to where my error is?
length = len(word_list)
num = 0
print(length)
while num <= length:
ele = word_list[num]
if ele in wordDict:
wordDict[ele] = wordDict[ele] +1
repeat = repeat + 1
if repeat > highestRepeat:
highestRepeat = repeat
else:
wordDict[ele] = 1
repeat = 1
num = num+1
List indexing goes from 0 to length-1.
In your while loop, you've told the num to go from 0 to length. That's why you have an index error.
Simply change num <= length to num < length. That should fix your code for you.
As an aside, there are much better ways to do this particular task. A simple two liner:
from collections import Counter
print(Counter(word_list).most_common(1))
Counter will calculate the frequencies of each element in your list for you, and most_common(1) will return the element with the highest frequency in your list.
Just to mention that there is a more compact solution to your problem:
word_list =['this' ,'is', 'a', 'test', 'is']
for word in set(word_list):
print word, ": ", word_list.count(word)

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)

I need to count like characters in the same position in python, but I have no idea how to get it right, as i am new to the program

Write a Python script that asks the user to enter two DNA
sequences with the same length. If the two sequences have
different lengths then output "Invalid input, the length must
be the same!" If inputs are valid, then compute how many dna bases at the
same position are equal in these two sequences and output the
answer "x positions of these two sequences have the same
character". x is the actual number, depending on the user's
input.
Below is what I have so far.
g=input('Enter DNA Sequence: ')
h=input('Enter Second DNA Sequence: ')
i=0
count=0
if len(g)!=len(h):
print('Invalid')
else:
while i<=len(g):
if g[i]==h[i]:
count+=1
i+=1
print(count)
Do this in your while loop instead (choose better variable names in your actual code):
for i, j in zip(g, h):
if i == j:
count += 1
OR replace the loop entirely with
count = sum(1 for i, j in zip(g, h) if i == j)
This will fix your index error. In general, you shouldn't be indexing lists in python, but looping over them. If you really want to index them, the i <= len(g) was the problem... it should be changed to i < len(g).
If you wanted to be really tricky, you could use the fact that True == 1 and False == 0:
count = sum(int(i == j) for i, j in zip(g, h))
The issue here is your loop condition. Your code gives you an IndexError; this means that you tried to access a character of a string, but there is no character at that index. What it means here is that i is greater than the len(g) - 1.
Consider this code:
while i<=len(g):
print(i)
i+=1
For g = "abc", it prints
0
1
2
3
Those are four numbers, not three! Since you start from 0, you must omit the last number, 3. You can adjust your condition as such:
while i < len(g):
# do things
But in Python, you should avoid using while loops when a for-loop will do. Here, you can use a for-loop to iterate through a sequence, and zip to combine two sequences into one.
for i, j in zip(g, h):
# i is the character of g, and j is the character of h
if i != j:
count += 1
You'll notice that you avoid the possibility of index errors and don't have to type so many [i]s.
i<=len(g) - replace this with i<len(g), because index counting starts from 0, not 1. This is the error you are facing. But in addition, your code is not very pretty...
First way to simplify it, keeping your structure:
for i in range(len(g)):
if g[i]==h[i]:
count+=1
Even better, you can actually make it a one-liner:
sum(g[i]==h[i] for i in range(len(g)))
Here the fact that True is evaluated to 1 in Python is used.
g = raw_input('Enter DNA Sequence: ')
h = raw_input('Enter Second DNA Sequence: ')
c = 0
count = 0
if len(g) != len(h):
print('Invalid')
else:
for i in g:
if g[c] != h[c]:
print "string does not match at : " + str(c)
count = count + 1
c = c + 1
print(count)
if(len(g)==len(h)):
print sum([1 for a,b in zip(g,h) if a==b])
Edit: Fixed the unclosed parens. Thanks for the comments, will definitely look at the generator solution and learn a bit - thanks!

Categories