[Tutor] Python problem

Mark Lawrence breamoreboy at gmail.com
Sat Feb 27 09:15:36 EST 2021


On 27/02/2021 13:32, Dennis Lee Bieber wrote:
> On Sat, 27 Feb 2021 11:23:19 +0400, Vakhtang Kvaratskhelia
> <va_kvaratskhelia at cu.edu.ge> declaimed the following:
> 
> 
>> low=0
>> high=10000
>> epsilon=100
>> portion_saved=0
>> while abs(250,000 - portion_saved * 566,774) >= epsilon:
>>     if portion_saved * 566774 < 250,000 :
>>         low=portion_saved
>>     else:
>>         high=portion_saved
>>     portion_saved=(high+low) / 2
>> print(portion_saved)
>>
>> The result is the same as the answer in the book that had the problem.
>>
>> but if i run the code:
>>
>> low=0
>> high=10000
>> epsilon=100
>> portion_saved=0
>> while abs(250,000 - portion_saved * 566,774) >= epsilon:
>>     if portion_saved * 566,774 < 250,000 :
>>         low=portion_saved
>>     else:
>>         high=portion_saved
>>     portion_saved=(high+low) // 2
>> print(portion_saved)
>>
>> Where i use "//" instead of "/" i get infinite loop because the "//" gets
>> stuck on one particular guess and doesn't continue the search as the "/"
>> division would.
>>
> 
> 	In both versions, you NEVER TEST for high/low converging on a value.
> Your WHILE loop is testing on the monetary (?) computation, and I don't
> know what units epsilon is supposed to be -- scaled integer for "1.00", or
> an actual difference of 100(currency units).
> 
> 	Reread your "hint"...
> 
>> "Because we are searching for a value that is in principle a float, we are
>> going to limit ourselves to two decimals of accuracy (i.e., we may want to
>> save at 7.04% or 0.0704 in decimal – but we are not going to worry about
>> the difference between 7.041% and 7.039%). This means we can search for an
>> integer between 0 and 10000 (using integer division), and then convert it
>> to a decimal percentage (using float division) to use when we are
> 
> 	The convergence is on the scaled %age, NOT on the monetary value you
> compute. The binary search is for %, not money result.
> 
> 	You have to determine how close high and low can be to each other to
> count as "same value". Note that 7.039..7.041 spans a range of 0.002. So:
> abs(high - low) < 0.002 would indicate you are done with the loop. Now
> scale that to your integer version (which is going to be a problem -- using
> the suggested scale means the above would be 703.9..704.1, but you don't
> have the .9/.1 -- your smallest epsilon is 1 [704 - 703] corresponding to
> 0.01%, not the 0.002% of the example)
> 
> 	Note: the number of steps taken will be consistent, and based solely
> upon how many significant digits you are carrying: 0..100% with epsilon 1%
> will always take 7 steps. 0..100% with epsilon 0.1% will take 10 steps.
> Binary search, 2^7 spans 0..127; 2^10 spans 0..1024. This is why I state
> that using scaled integers and integer division is futile -- the search
> ends when the difference between high and low is less than your selected
> epsilon value, so "infinite number of floating values between 0.0 .. 100.0"
> just doesn't matter -- if epsilon is 1.0% (100 as scaled integer) the loop
> will take 7 steps; if 0.1% (10 as scaled integer) it will take 10 steps.
> 
> 	The only justification I can see for using scaled integers is that one
> is running on a microcontroller that does not have floating point
> operations at all.
> 

I do not see the purpose of all this analysis when the code given does 
not even run:-

cat mytest.py
low = 0
high = 10000
epsilon = 100
portion_saved = 0
while abs(250, 000 - portion_saved * 566, 774) >= epsilon:
     if portion_saved * 566774 < 250, 000:
         low = portion_saved
     else:
         high = portion_saved
     portion_saved = (high+low) / 2
print(portion_saved)
mark at mark-HP-15-Notebook-PC:~/mypython$ python3 ./mytest.py
   File "./mytest.py", line 6
     if portion_saved * 566774 < 250, 000:
                                    ^
SyntaxError: invalid syntax

The call to abs gets away with it as there are three parameters listed, 
which is wrong anyway as abs only takes one argument.  In fact check the 
difference between 566, 774 in the call to abs and 566774 in the line below.

Correct all the problems and the output I get is 0.4410743713378906.  Is 
that correct? I've no idea and I'm not bothered enough to check.

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence



More information about the Tutor mailing list