Does Python float function automatically recognize numbers? - python

So here is a simple problem input:
The first line contains an integer, N, the number of students.
The 2N subsequent lines describe each student over lines.
The first line contains a student's name.
The second line contains their grade.
and code:
l = []
second_lowest_names = []
scores = set()
for _ in range(int(input())):
name = input()
score = float(input())
l.append([name, score])
scores.add(score)
second_lowest = sorted(scores)[1]
for name, score in l:
if score == second_lowest:
second_lowest_names.append(name)
for name in sorted(second_lowest_names):
print(name, end='\n')
I'm just a bit confused of how the float() function only takes the numbers but not the names as input
here's a sample input
5
Harry
37.21
Berry
37.21
Tina
37.2
Akriti
41
Harsh
39

In your loop, you call input() twice. Each time you get a single line of the input, so the two values corresponding to the student are both read in a single pass of the loop:
for _ in range(int(input())):
name = input() # get the name
score = float(input()) # get the score, and convert it to a number
Only the second input line, which represents the student's score, gets passed to float. If you passed the student's name (from the previous line) to float, you'd get an exception unless the student had a very unconventional name (like 'Nan' or 'Inf').

Do you know what float does? It's an abbreviation for floating point number, which is a way of representing numbers in computers that can have fractional portions after the decimal point. Whenever you call input(), python always receives what you typed as a string, which means a sequence of characters.
Strings have no direct numeric meaning in the computer in the way that floats do. The string "41" to the computer is not the meaningful number that you or I would immediately interpret it as. To the computer, it is just two characters in order, the first of which happens to be the "4" character and the second of which happens to be the "1" character - nothing more, nothing less. The quotes in python indicate strings. If you were to evaluate "41"+"1" you would get "411". You could even evaluate "41" + "hello" to get "41hello". These are all just strings.
Calling float("41") takes the string and tries to evaluate it into an floating point number which the computer interprets as an actual number and not simply a sequence of characters. The sum of two floating point values such as 41.0 + 1.0 evaluates to 42.0 as you would expect.
Since a student's name is not meant to represent a number, you should not try to call float() on it as it doesn't make any sense to do so. Float will most likely fail to produce a numeric interpretation unless the name was one of a few special strings like "nan" (not a number) or "inf" (infinity). If the name did happen to be one of these strings, you wouldn't want this translation anyways.
This is why float is called on the numeric entities and not on the names in the code.
Another similar thing besides float() is int(), which is an abbreviation of integer. Both floats and ints are actual numeric representations. The difference essentially is that integers are restricted to be whole numbers (positive, negative, or zero), whereas floating point values can have fractional numbers after the decimal point. They are different ways of expressing numbers within a computer, each suited to different situations.

Related

Creating a unique short ID from string value

I have some data that has unique IDs stored as a string in the form:
ddd.dddddaddd.dddddz
Where d is some digit and a/z is some alphabet character. The digits may be 0-9 and the characters are either E or W for the a and N or S for the z.
I'd like to turn this into a unique integer and what I've tried using the hashlib module returns:
>>> int(hashlib.sha256(str.encode(s)).hexdigest(), 16)
Output: a very long integer (on another system cannot copy it)
Is there a way to generate a unique integer ID from a string so that it does not exceed 12 digits? I know that I will never need a unique integer ID beyond 12 digits.
Just something simple:
>>> s = '123.45678W123.45678S'
>>> int(s.translate(str.maketrans('EWNS', '1234', '.')))
123456782123456784
Not the impossible 12 digits you're still asking for in the question, but under the 20 digits you allowed in the comments.
As you are dealing with coordinates, I would try my best to keep the information in the final 12-digit ID.
If your points are global, it might be necessary to keep the degrees but they may be widespread, so you can sacrifice some information when it comes to precision.
If your points are local (all within a range of less than 10 degrees) you might skip the first two digits of the degrees and focus on the decimals.
As it may be possible that two points are close to each other, it may be prudent to reserve one digit as a serial number.
Proposal for widespread points:
s = "123.45678N123.45678E"
ident = "".join([s[0:6],s[10:16]]).replace(".","")
q = 0
if s[9]=="N":
q+=1
if s[-1]=="E":
q+=2
ident+=str(q)+'0'
The example would translate to 123451234530.
After computing the initial ident numbers for each ID, you should loop through them and increment the last digit if an ident is already taken.
This way you could easily reconstruct the location from the ID by just separating the first 10 digits to two degrees of the format ddd.dd and use the [-2] digit as an indicator of the quadrant (0:SW, 1:SE, 2:NW, 3:NE).

How to compare specific items in a string python

E.g. in a given input the fourth digit must be one greater than the fifth digit
input = "5000-0000-0000"
if input[3] != input[5] + 1
return false
If you think about what input[3] and input[5] are, you will pretty quickly realize they are characters and not numbers that can be added or compared with mathematical operations (think about what would happen if you wrote input = "Andrew Francis").
You can see this by using print(type(input[3])).
Fortunately, if you have a string that contains only characters that make up a valid number, you can convert it to (for instance) an integer using the int() function. So, try print(type(int(input[3]))) and see what you get.

Is it possible to have a float number without a decimal point in Python?

I asked this because it is possible in R. Note that both 1.5 and 1 are in numeric type (double-precision), and only 1L is an integer. When coercing a string into numeric type, it doesn't show a decimal point if there's not one in the string.
class(1.5)
# "numeric"
class(1)
# "numeric"
class(1L)
# "integer"
x <- as.numeric("3")
x
# 3
class(x)
# "numeric"
Am I allowed to have similar operations in Python? Let's say I have a function called key_in_a_number:
def key_in_a_number():
num = input("Key in a number here: ")
try:
return float(num)
except ValueError:
return "Please key in only numbers."
Now if one keys in "40", it will return 40.0, but 40.0 and 40 are different in certain digits. Thus, 40 should be returned if "40" is keyed in, while 40.0 should be returned only when "40.0" is keyed in.
My work around is:
def key_in_a_number():
num = input("Key in a number here: ")
try:
return int(num)
except ValueError:
try:
return float(num)
except ValueError:
return "Please key in only numbers."
However, in this way, I cannot be sure that the results are always in the same type, which could be problematic in following data storage or processing. Is there any way to have a number in float type without a decimal point?
I think your core problem here is that you're misunderstanding what float is.
A float represents a C double, which almost always means an IEEE 754-1985 double (or an IEEE 754-2008 binary64, which is basically the same thing but slightly better defined). It always has 53 binary digits of precision. It doesn't matter whether you specify it as 40., 40.00000, float(40), float('40'), or float('40.00'); those are all identical in every way.
So, the main problem you're asking about doesn't make any sense:
Now if one keys in "40", it will return 40.0, but 40.0 and 40 are different in certain digits.
No, they aren't. float("40") and float("40.0") are both the exact same value, with no differences in any digits, and no difference in their precision, or anything else.
There's a different type in Python, in the decimal library, that represents an IEEE 754-2008 arbitrary-sized decimal. It has as many decimal digits of precision as you tell it to have.
So, Decimal('40') and Decimal('40.') have two digits; Decimal('40.000') has five digits—they may be equal, but they're not identical, because the last one is more precise.
Decimal, on the other hand, prints out however many digits of precision it actually has:
>>> print(Decimal('40'))
40
>>> print(Decimal('40.'))
40
>>> print(Decimal('40.0'))
40.0
While we're at it, if you do want float and int values, here's how to translate each line of R into Python:
class(1.5) # numeric
type(1.5) # float
class(1) # numeric
type(1) # int
type(1.) # float
class(1L) # integer
type(1) # int
x <- as.numeric("3") # numeric
x = float(3) # float
x = float("3") # float
Notice that, just like as.numeric("3") gives you a numeric rather than an integer, float("3")gives you afloatrather than anint`. I'm not sure why that Python behavior puzzles you given that it's identical to the equivalent R behavior.
Yes,
10 would be an integer in Python, whereas 10. which represents the same number would be a float.

Python: Finding the length of a float with zeros at the end

I have several float values that have necessary zeros at the ends.
One number that I have is 0.0013790.
When finding the length of this, I get 8 when I should be getting 9, since the zero at the end is dropped. I can not use .format(), since some numbers are shorter than others and there is no concrete length that I want them set to. If I had a float that was seven digits long after the decimal and set the format to 8, I would get an extra zero which should NOT belong there.
I can not afford to have my program adding zeros through format when they are not always necessary, since some numbers will be shorter than others. How do I find the actual length of these numbers when a zero is at the end?
I can not make an if statement that checks if the number .endswith 0, because it never does. The zero is always dropped! I am already checking the length of the string of the float and still the zero is dropped! Many numbers will not end with zero, so I can not simply add one to the length found. Please help!
Numbers to test:
When inputting _, you should get _. If you can get the below to work along with some other numbers, please give me the solution. I've been racking at my brain for hours!! Thanks.
WANTED RESULTS: 0.12345 -> 7, 0.123450 -> 8, 0.1234500 -> 9.
UPDATE:
Thank you for your solutions, but the numbers are not inputs. I have them set to the eval() function, since I have roughly 1000 variables that need to be accessed dynamically from a websocket. Values are retrieved just fine, but if I am not mistaken, eval() defaults to float. Switching it from float to string has not done me much good, since I am guessing that eval() is always a float. Any solutions??
You need to store your values as strings if you want to track length independent of the value of the float.
Floating point values have no length, and trailing 0s do not affect the value so they produce identical floats. This means after it gets defined, there is no way to determine whether 0.12345 was defined using 0.12345 or 0.12345000000.
0.12345 is 0.123450 # True
0.12345 is 0.1234500 # True
len(0.12345) # TypeError: object of type 'float' has no len()
Everything works fine for the string representation of those floats:
"0.12345" is "0.123450" # False
"0.12345" is "0.1234500" # False
len("0.12345") # 7
Thus you should store these values as strings, and convert them to float when necessary.
If you first convert the input to a number, and then to a string, you'll lose any insignificant digits.
If you are asking the user to enter the value:
>>> foo = input('Enter the number here: ')
Enter the number here: 0.0013790
>>> len(foo)
9
If you are using Python 2, make sure you use raw_input and not input
As long as you don't cast the value to a float, you should get correct values for len().
Then we have to store the float as a string value. Following lines may be answer to the question where it is a default behaviour.
mynum = input('Enter your number: ')
print('Hello', mynum)
print(len(mynum))

Why do I have to change integers to strings in order to iterate them in Python?

First of all, I have only recently started to learn Python on codeacademy.com and this is probably a very basic question, so thank you for the help and please forgive my lack of knowledge.
The function below takes positive integers as input and returns the sum of all that numbers' digits. What I don't understand, is why I have to change the type of the input into str first, and then back into integer, in order to add the numbers' digits to each other. Could someone help me out with an explanation please? The code works fine for the exercise, but I feel I am missing the big picture here.
def digit_sum(n):
num = 0
for i in str(n):
num += int(i)
return num
Integers are not sequences of digits. They are just (whole) numbers, so they can't be iterated over.
By turning the integer into a string, you created a sequence of digits (characters), and a string can be iterated over. It is no longer a number, it is now text.
See it as a representation; you could also have turned the same number into hexadecimal text, or octal text, or binary text. It would still be the same numerical value, just written down differently in text.
Iteration over a string works, and gives you single characters, which for a number means that each character is also a digit. The code takes that character and turns it back into a number with int(i).
You don't have to use that trick. You could also use maths:
def digit_sum(n):
total = 0
while n:
n, digit = divmod(n, 10)
num += digit
return num
This uses a while loop, and repeatedly divides the input number by ten (keeping the remainder) until 0 is reached. The remainders are summed, giving you the digit sum. So 1234 is turned into 123 and 4, then 12 and 3, etc.
Let's say the number 12345
So I would need 1,2,3,4,5 from the given number and then sum it up.
So how to get individuals number. One mathematical way was how #Martijn Pieters showed.
Another is to convert it into a string , and make it iterable.
This is one of the many ways to do it.
>>> sum(map(int, list(str(12345))))
15
The list() function break a string into individual letters. SO I needed a string. Once I have all numbers as individual letters, I can convert them into integers and add them up .

Categories