## while loop (string manipulation)

This is the place for queries that don't fit in any of the other categories.

### while loop (string manipulation)

Question:
Assume that this function receives a string that only has digits and that it has at least a '0'.
The function should treat each digit as a separate number and should calculate the minimum, maximum and average of the digits, considering all the digits from position 0 until but not including the first digit with value '0'. The result should be a string containing the three values: that is, minimum, maximum and average of those numbers separated by one hyphen ('-'). The average should be calculated with fractional part.

For example minMaxAvg('325408214') should return '2-5-3.5' because 2 is the minimum among 3,2,5,4 ; 5 is the maximum among 3,2,5,4 and 3.5 is the average of 3,2,5,4.

Code: Select all
`def minMaxAvg (inputs): i=0new_string=0while inputs[i] != '0':   new_string += inputs[i]   i += 1mi = int(min(new_string))ma = int(max(new_string))total = 0for i in range(len(new_string)):   total += int(new_string[i])average = int(total)/int(len(new_string))answer = int(mi) + "-" + int(ma) + "-" + int(average)return answer`

ltcy

Posts: 12
Joined: Sat Feb 16, 2013 1:32 am

### Re: while loop (string manipulation)

• The body of your function should be indented with respect to the def line.
• You're initializing new_string to an integer value (zero); you want to be initializing it to an empty string.
• When creating the answer at the very end, you want to be using str() instead of int() -- mi, ma and average are already integers and you want to turn them into strings before concatenation.
Apart from that, the code looks like it should work.

There are a few more things you might want to keep in mind, however:
• When getting the part of the input that is before '0', could use the split string method rather than using a while loop.
• When you're computing the min and max values, you're actually computing the min/max of the character ordinals, not the integer values represented by those characters. Since the order of characters representing digits matches the order of numerical values represented by those characters, this still produces the correct result in your case; but you should be aware of what is happening.
• this
Code: Select all
`total = 0for i in range(len(new_string)):   total += int(new_string[i])`

could be just
Code: Select all
`total = 0for c in new_string:   total += int(c)`

or, even better
Code: Select all
`total = sum(map(int, new_string))`
• Rather than constantly converting characters to integers, you might want to do it just once and keep the result in a list; then use that list for all the subsequent calculations.
• Rather than concatenating the end result by repeatedly using the + operator, you could use the join string method.
setrofim

Posts: 288
Joined: Mon Mar 04, 2013 7:52 pm

### Re: while loop (string manipulation)

setrofim wrote:[*]Rather than concatenating the end result by repeatedly using the + operator, you could use the join string method.[/list]

Just as an addition to setrofim's excellent and thorough response, using str.join() is recommended over string concatenation as being better style because the Python language does not guarantee that string concatenation will be reasonably fast. In CPython, the version you're probably using, it'll probably work just fine, but in Jython and possibly others, it can be dreadfully slow. It is considered better Python if the code you write works well on any implementation of Python.

That said, the point is minor, and is more style than performance if you're only running your code on CPython interpreters (this is the standard distribution).
Join the #python-forum IRC channel on irc.freenode.net for off-topic chat!

Please prefer not to PM members. The point of the forum is so that anyone can benefit. We don't want to help you over PMs/emails/Skype chats that others can't benefit from

micseydel

Posts: 2027
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA

### Re: while loop (string manipulation)

Here is my new code:
Code: Select all
` def minMaxAvg (inputs):i = 0new_string = ""while inputs[i] != '0':   new_string += inputs[i]   i += 1mi = int(min(new_string))ma = int(max(new_string))total = 0for i in range(len(new_string)):   total += int(new_string[i])   average = float(int(total)/int(len(new_string)))answer = str(mi) + "-" + str(ma) + "-" + str(average)return answer`

I still can't get the answer, when I tried it with the fixed example,
1.) '325408214' the answer should be '2-5-3.5' but I got this '2-5-3.0'
2.) '0123456' answer: '0-0-0' what I got: "Error: min of empty sequence"

setrofim wrote:
• The body of your function should be indented with respect to the def line.
• You're initializing new_string to an integer value (zero); you want to be initializing it to an empty string.
• When creating the answer at the very end, you want to be using str() instead of int() -- mi, ma and average are already integers and you want to turn them into strings before concatenation.
Apart from that, the code looks like it should work.

There are a few more things you might want to keep in mind, however:
• When getting the part of the input that is before '0', could use the split string method rather than using a while loop.
• When you're computing the min and max values, you're actually computing the min/max of the character ordinals, not the integer values represented by those characters. Since the order of characters representing digits matches the order of numerical values represented by those characters, this still produces the correct result in your case; but you should be aware of what is happening.
• this
Code: Select all
`total = 0for i in range(len(new_string)):   total += int(new_string[i])`

could be just
Code: Select all
`total = 0for c in new_string:   total += int(c)`

or, even better
Code: Select all
`total = sum(map(int, new_string))`
• Rather than constantly converting characters to integers, you might want to do it just once and keep the result in a list; then use that list for all the subsequent calculations.
• Rather than concatenating the end result by repeatedly using the + operator, you could use the join string method.
Last edited by Yoriz on Tue Mar 19, 2013 1:07 pm, edited 1 time in total.
Reason: Added a '[' to the quote
ltcy

Posts: 12
Joined: Sat Feb 16, 2013 1:32 am

### Re: while loop (string manipulation)

ltcy wrote:1.) '325408214' the answer should be '2-5-3.5' but I got this '2-5-3.0'
2.) '0123456' answer: '0-0-0' what I got: "Error: min of empty sequence"

1. By default, when you divide an int by another int in Python, you get an int back. The part after the decimal point gets dropped.
Code: Select all
`   average = float(int(total)/int(len(new_string)))`

do this:
Code: Select all
`   average = float(total)/len(new_string))`

Here, you'd be dividing a float by an int, which would yield a float. Alternatively, you can add the following to the top of the file:
Code: Select all
`from __future__ import division`

This will make sure that division always results in a float (even when dividing two ints).
2. When '0' is the leading character, your while check fails right away, and new_string remains empty. The min() function expects there to be at least one element in the sequence that is passed to it, so when you pass in the empty string, it gives you that error. To avoid this, you need to check for the empty string case explicitly and return immediately the result you want, rather than continuing with the function:
Code: Select all
`if not new_string:    return "0-0-0"`

I'll let you work out where in your code that should go.
setrofim

Posts: 288
Joined: Mon Mar 04, 2013 7:52 pm

### Re: while loop (string manipulation)

setrofim wrote:1.By default, when you divide an int by another int in Python, you get an int back.

That's the default in Python up to 2.7. In Python 3+ you get a float back if appropriate.
Craig "Ichabod" O'Brien
Minimalist, buddhist, theist, and programmer
Current languages: Python, SAS, C++, Erlang
Previous serious languages: R, Java, VBA, Lisp, HyperTalk, BASIC
ichabod801

Posts: 309
Joined: Sat Feb 09, 2013 12:54 pm
Location: Outside Washington DC

### Re: while loop (string manipulation)

ichabod801 wrote:That's the default in Python up to 2.7. In Python 3+ you get a float back if appropriate.

Good point. Thanks for the correction.
setrofim

Posts: 288
Joined: Mon Mar 04, 2013 7:52 pm