Hi all,
I have written a simple program which sorts a list of numbers and/or letters.
BUT!
number 233 for example, will come before 3, due to the leading 2.
A similar thing happens with words.
I have used a simple
number1 > number2
line to see which of a pair is bigger.
My question is: how may I add place value to my program?
thanks
Place value + value of letters
8 posts
- Posts: 42
- Joined: Wed Nov 16, 2011 3:04 pm
Post the code, let's have a look.
/uk/lancashire/heapey/dave
As you say 'similar thing happen with words' you are at the essence of the issue: your variables are most likely strings/text, so even though what you think of as numbers are actually string/text representation of the number - and because strings/text is sorted alphabetically (not numerically), "223" comes before "3".
Now, as you say 'program which sorts a list of numbers and/or letters' you cannot really get both:
- if you have only numbers (in numeric variables), you can sort them in numeric order
- if you have only letters, you can sort then in alphabetic order
- if you have mixed numbers and letters, you can sort them in alphabetic order (or you have to create your own comparison function that returns something else)
Hope that is clears it at least a bit!
Hmm... just out of curiosity tried this:
...so it seems you can compare numbers and strings, but how the Python compares them is beyond me (a beginner in Python myself).
- Code: Select all
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print 2 < 3
True
>>> print 223 < 3
False
>>> print "223" < "3"
True
>>> print "a2" < "a3"
True
>>> i = 223
>>> j = 3
>>> print i < j
False
>>> i = "223"
>>> j = "3"
>>> print i < j
True
>>>
Now, as you say 'program which sorts a list of numbers and/or letters' you cannot really get both:
- if you have only numbers (in numeric variables), you can sort them in numeric order
- if you have only letters, you can sort then in alphabetic order
- if you have mixed numbers and letters, you can sort them in alphabetic order (or you have to create your own comparison function that returns something else)
Hope that is clears it at least a bit!
Hmm... just out of curiosity tried this:
- Code: Select all
>>> print "a" < 65
False
>>> print "2" < 3
False
...so it seems you can compare numbers and strings, but how the Python compares them is beyond me (a beginner in Python myself).
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
- Posts: 852
- Joined: Thu Nov 01, 2012 12:12 pm
- Location: Dublin, Ireland
@ -rst-, it looks like it is comparing the ASCII (or maybe Unicode) encoding of the character. "2" is 50, and "a" is 97.
The problem is that things can get complex and ambiguous. How should these strings be ordered?
this2string1000
this19string900
1,456,234.3
1.456.234,3
1456234.3
14562343
It is ambiguous enough that any general solution would be insufficient more often than it was useful.
The pragmatic solution is to always use the same number of digits with leading zeros.
The problem is that things can get complex and ambiguous. How should these strings be ordered?
this2string1000
this19string900
1,456,234.3
1.456.234,3
1456234.3
14562343
It is ambiguous enough that any general solution would be insufficient more often than it was useful.
The pragmatic solution is to always use the same number of digits with leading zeros.
Ok so having read your post I abandoned the idea of supporting non-number inputs.
To fix my code I changed the raw_input() to input() (code below) which seems to have changed the variable type in my list.
here is my (messy) code:
now changing the raw_input() to input() means I cant have my nice input loop
1st: is there a way I can change the data type from raw_input to the type input() gives?
2nd: feel free to scream at me about how poor my code is: i want tips on how to improve it
thanks guys
PS: I know bubble sort is not the most efficient, but that is not the point of this
To fix my code I changed the raw_input() to input() (code below) which seems to have changed the variable type in my list.
here is my (messy) code:
- Code: Select all
list_in=[]
iterations = 1
inputs=0
print "how many numbers do you want to input?\n"
to_be_input=input()
print "input integers plz; and 00 to end input\n"
while inputs<to_be_input:
input_last = input()
input_last
list_in.append(input_last)
inputs=inputs+1
print "you just input\n" ,list_in, "\n beginning sorting"
#next bit iterate until there is no more change between iterations
while 1<2:
Y=1
changes=0
while Y<len(list_in): #this loop is the single do/dont flip part of the code
X=Y-1
if list_in[X] > list_in[Y]:
tempX=list_in[X]
tempY=list_in[Y]
list_in[X]=tempY
list_in[Y]=tempX
changes=1
Y=Y+1
print iterations,list_in
iterations=iterations+1
if changes==0:
break
print list_in
now changing the raw_input() to input() means I cant have my nice input loop
1st: is there a way I can change the data type from raw_input to the type input() gives?
2nd: feel free to scream at me about how poor my code is: i want tips on how to improve it
thanks guys
PS: I know bubble sort is not the most efficient, but that is not the point of this
- Posts: 42
- Joined: Wed Nov 16, 2011 3:04 pm
Bubble sort is one of the best algorithms to start with (simple enough to understand and simulate with pen and paper)!
What do you think is 'not so nice' with this input loop?
I assume the 'and 00 to end' is left from your original... There is one extra line within the loop: the lonely 'input_last'. Other that that it looks ok - maybe the variable names could be a bit more descriptive and at least follow the same pattern: to_be_input, last_input, input_list, n_inputs (or num_inputs) ...these are a bit of a question of personal taste as well...
In the bubble sort you should be able to do the swap with only one extra variable - or maybe even without any - this is a good exercise
The while loop as it is now, the test '1<2' could(/should) be written as 'True' (just because Python offers the boolean variable type, that is missing from many languages). Also the changes variable could be a boolean... And to polish it off, use a real (boolean) variable to replace the 'while True' + 'break'.
Guess that covers the Question 2
Answer to question 1: you could do
...which is better than input() as it would fail for anything not integer ...obviously a good programmer would make sure the code can gracefully handle this - after you get all the rest working, see handling exceptions
Something to think...
What do you think is 'not so nice' with this input loop?
I assume the 'and 00 to end' is left from your original... There is one extra line within the loop: the lonely 'input_last'. Other that that it looks ok - maybe the variable names could be a bit more descriptive and at least follow the same pattern: to_be_input, last_input, input_list, n_inputs (or num_inputs) ...these are a bit of a question of personal taste as well...
In the bubble sort you should be able to do the swap with only one extra variable - or maybe even without any - this is a good exercise
Guess that covers the Question 2
Answer to question 1: you could do
- Code: Select all
last_input = int(raw_input())
...which is better than input() as it would fail for anything not integer ...obviously a good programmer would make sure the code can gracefully handle this - after you get all the rest working, see handling exceptions
Something to think...
http://raspberrycompote.blogspot.com/ - Low-level graphics and 'Coding Gold Dust'
- Posts: 852
- Joined: Thu Nov 01, 2012 12:12 pm
- Location: Dublin, Ireland
Thanks a lot!
yes the input 00 was an experiment to see if I could end the loop like that (before, I had it break on an empty space)
I see what you mean about the switch too: but I was going for ease-of-thinking rather than efficiency.
now to tinker on quick sort.... ( a bit more challenging methinks)
yes the input 00 was an experiment to see if I could end the loop like that (before, I had it break on an empty space)
I see what you mean about the switch too: but I was going for ease-of-thinking rather than efficiency.
now to tinker on quick sort.... ( a bit more challenging methinks)
- Posts: 42
- Joined: Wed Nov 16, 2011 3:04 pm
"input()" is a security hole. The user can type Python code in and it will get interpreted
if the user types "x" then y is set to 42. Try it.
For that reason input() in Python 3 is redefined to be the same as raw_input() in Python 2, and Python 2 users are encouraged to use raw_input() only.
raw_input() always returns a string and it is the program's responsibility to convert it. Unfortunately the only clean way to do that is to use exceptions.
We try to convert it to an integer first, because that's the most stringent. If that fails we try to convert it to a float, and if that fails we leave it as a string.
Now we need to be able to compare strings with numbers, so we define a function to do that. It takes two parameters: a and b, and it returns -1 if a<b, +1 if a>b and 0 if they are the same:
that just orders all strings lower than all numbers, but you can obviously enhance it if you have a better ordering in your application.
And you use the comparison function in the sort function:
By the way, you could just use
It does actually work, but the way it sorts strings and numbers is not defined and may change. So to be correct you have to tell it your comparison function. You can do that in Python 2:
but in Python 3 they've taken out the cmp parameter and the equivalent method requires even more newbie unfriendly language features.
- Code: Select all
x = 42
y = input()
print y
if the user types "x" then y is set to 42. Try it.
For that reason input() in Python 3 is redefined to be the same as raw_input() in Python 2, and Python 2 users are encouraged to use raw_input() only.
raw_input() always returns a string and it is the program's responsibility to convert it. Unfortunately the only clean way to do that is to use exceptions.
- Code: Select all
x = raw_input()
try:
input_last = int(x)
except ValueError:
try:
input_last = float(x)
except ValueError:
input_last = x
We try to convert it to an integer first, because that's the most stringent. If that fails we try to convert it to a float, and if that fails we leave it as a string.
Now we need to be able to compare strings with numbers, so we define a function to do that. It takes two parameters: a and b, and it returns -1 if a<b, +1 if a>b and 0 if they are the same:
- Code: Select all
def mytest (a, b):
if type(a) == str and type(b) != str:
return -1
elif type(a) != str and type(b) == str:
return +1
elif a < b:
return -1
elif a > b:
return +1
else:
return 0
that just orders all strings lower than all numbers, but you can obviously enhance it if you have a better ordering in your application.
And you use the comparison function in the sort function:
- Code: Select all
while True:
Y=1
changes=0
while Y<len(list_in): #this loop is the single do/dont flip part of the code
X=Y-1
if mytest(list_in[X], list_in[Y]) > 0:
tempX=list_in[X]
tempY=list_in[Y]
list_in[X]=tempY
list_in[Y]=tempX
changes=1
Y=Y+1
print iterations,list_in
iterations=iterations+1
if changes==0:
break
print list_in
By the way, you could just use
- Code: Select all
list_out = sorted(list_in)
It does actually work, but the way it sorts strings and numbers is not defined and may change. So to be correct you have to tell it your comparison function. You can do that in Python 2:
- Code: Select all
list_out = sorted(list_in, cmp=mytest)
but in Python 3 they've taken out the cmp parameter and the equivalent method requires even more newbie unfriendly language features.