RE: on writing a while loop for rolling two dice
For some people the "while true" method seems reasonable but it has a problem if the internal body does not have some guarantee of an exit. And that exit can be subtle. Many have mentioned ways an end condition can fail due to rounding errors not being exactly equal to what you are looking for, or an asymptotic process that approaches zero with a cutoff that is thus never reached. But I have seen some cases where you want a process or thread to run indefinitely until it is killed by another process or you reboot. You could of course use something like flag="green" and have your while keep testing that value but that is just wasted motion. Of course, properly used, it does help explain to the reader what your intention is, if done properly. It also can confuse if you put in "while 5 < 6" or other weird ways to say do this indefinitely. I think part of this conversation is about programming styles and what we should teach new students versus those who are trying to find more creative ways to do things or more efficiently or more generality. Sometimes a more direct method may be reasonable. On another forum, I saw someone write somewhat lengthy and redundant code on how to deal with partitioning data into three clusters randomly. My algorithm was general and handled any number of N clusters and since N often does not cleanly divide the number of items, has to place the remaining items into one of the N clusters or distribute them one at a time into some to make them almost even in size. His solution was to repeat large sections of code, three times, with some modification, for the cases where the remainder (modulo N) was 0, 1 or 2. The latter method was longer but in an odd way, much easier to understand. It boiled down to, if you have one extra put it here. If you have two, put one here and one there. My method had all kinds of bells and whistles that this specific case did not need. Let me end with asking if anyone has ever seen a mild variant of this: ... # code while false apologize() ... # more code -Original Message- From: Python-list On Behalf Of Hope Rouselle Sent: Thursday, September 2, 2021 10:42 AM To: [email protected] Subject: Re: on writing a while loop for rolling two dice David Raymond writes: >> def how_many_times(): >> x, y = 0, 1 >> c = 0 >> while x != y: >> c = c + 1 >> x, y = roll() >> return c, (x, y) > > Since I haven't seen it used in answers yet, here's another option > using our new walrus operator > > def how_many_times(): > roll_count = 1 > while (rolls := roll())[0] != rolls[1]: > roll_count += 1 > return (roll_count, rolls) That's nice, although it doesn't seem more readable to a novice seeing a while for the first time, seeing a loop for the first time, than that while-True version. In fact, I think the while-True is the clearest so far. But it's always nice to spot a walrus in the wild! (If you're somewhere safe, that is.) -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Problem with python
On 2021-09-04, Hope Rouselle wrote: > Igor Korot writes: > >> Hi, >> Will this syntax work in python 2? > > If you say > > print(something) > > it works in both. But it doesn't always work the _same_ in both. If you're expecting some particular output, then one or the other might not won't "work". > So, stick to this syntax. Only if you import print_function from __future__ in 2.x -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On Sat, 4 Sep 2021 12:27:55 -0500, "Michael F. Stemper"
declaimed the following:
>
>Kernighan and Ritchie agree(d) with you. Per _The C Programming
>Language__:
> Experience shows that do-while is much less used that while
> and for.
>
And just for confusion, consider languages with "repeat / until"...
"do / while" repeats so long as the condition evaluates to "true";
"repeat / until" /exits/ when the condition evaluates to "true".
Then... there is Ada...
While one is most likely to encounter constructs:
for ix in start..end loop
...
end loop;
and
while condition loop
...
end loop;
the core construct is just a bare
loop
...
end loop;
which, with the "exit when condition" statement allows low-level emulation
of any loop... (same as Python "if condition: break"
loop-- "while" loop
exit when not condition;
...
end loop;
loop-- "repeat / until"
...
exit when condition;
end loop;
loop-- split
...
exit when condition;
...
end loop;
{I'm not going to do the "for" loop, but one can easily manage
initialization/increment/test statements}.
To really get your mind blown, look at loops in REXX...
do while condition
...
end
do until condition
/* note that the termination parameter is listed at top, */
/* but takes effect at the bottom, so always one pass */
...
end
do forever
...
if condition then
leave
...
end
do idx = start to end /* optional: by increment */
...
end
do idx = 1 by increment for repetitions
...
end
AND worse! You can combine them...
do idx = start for repetitions while condition1 until condition2
...
end
{I need to check if both while and until can be in the same statement}
--
Wulfraed Dennis Lee Bieber AF6VN
[email protected]://wlfraed.microdiversity.freeddns.org/
--
https://mail.python.org/mailman/listinfo/python-list
Re: on floating-point numbers
On Sat, 04 Sep 2021 10:40:35 -0300, Hope Rouselle
declaimed the following:
>course, I don't even have floats to worry about.) If I'm given 1.17,
>say, I am not confident that I could turn this number into 117 by
>multiplying it by 100. And that was the question. Can I always
>multiply such IEEE 754 dollar amounts by 100?
>
HOW are you "given" that 1.17? If that is coming from some
user-readable source (keyboard entry, text-based file [CSV/TSV, even SYLK])
you do NOT have a number -- you have a string, which needs to be converted
by some algorithm.
For money, the best solution, again, is to use the Decimal module and
feed the /string/ to the initialization call. If you want to do it
yourself, to get a scaled integer, you will have to code a
parser/converter.
* strip extraneous punctuation ($, etc -- but not comma, decimal
point, or + and -)
* strip any grouping separators (commas, but beware, some
countries
group using a period -- "1.234,56" vs "1,234.56"). "1,234.56" => "1234.56"
* ensure there is a decimal point (again, you may have to convert
a
comma to decimal point), if not append a "." to the input
* append enough 0s to the end to ensure you have whatever scale
factor you are using behind the decimal point (as mentioned M$ Excel money
type uses four places) "1234.56" => "1234.5600"
* remove the decimal marker. "1234.5600" => "12345600"
* convert to native integer. int("12345600") => 12345600 [as
integer]
{may fail if +/- are not in the required position for Python}
If the number is coming from some binary file format, it is already too
late. And you might need to study any DBMS being used. Some transfer values
as text strings, and reconvert to DBMS numeric types on receipt. Make sure
the DBMS is using a decimal number type and not a floating type for the
field (which leaves out SQLite3 which will store anything in any field,
but uses some slightly obscure logic to determine what conversion is done)
--
Wulfraed Dennis Lee Bieber AF6VN
[email protected]://wlfraed.microdiversity.freeddns.org/
--
https://mail.python.org/mailman/listinfo/python-list
Re: on floating-point numbers
On 2021-09-05, Peter J. Holzer wrote: > On 2021-09-05 03:38:55 +1200, Greg Ewing wrote: >> If 7.23 were exactly representable, you would have got >> 723/1000. >> >> Contrast this with something that *is* exactly representable: >> >> >>> 7.875.as_integer_ratio() >> (63, 8) >> >> and observe that 7875/1000 == 63/8: >> >> >>> from fractions import Fraction >> >>> Fraction(7875,1000) >> Fraction(63, 8) >> >> In general, to find out whether a decimal number is exactly >> representable in binary, represent it as a ratio of integers where >> the denominator is a power of 10, reduce that to lowest terms, > > ... and check if the denominator is a power of two. If it isn't > (e.g. 1000 == 2**3 * 5**3) then the number is not exactly > representable as a binary floating point number. > > More generally, if the prime factorization of the denominator only > contains prime factors which are also prime factors of your base, > then the number can be exactle represented (unless either the > denominator or the enumerator get too big). And once you understand that, ignore it and write code under the assumumption that nothing can be exactly represented in floating point. If you like, you can assume that 0 can be exactly represented without getting into too much trouble as long as it's a literal constant value and not the result of any run-time FP operations. If you want to live dangerously, you can assume that integers with magnitude less than a million can be exactly represented. That assumption is true for all the FP representations I've ever used, but once you start depending on it, you're one stumble from the edge of the cliff. -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re-design the position of the RPROMPT string.
I forked and made some improvements to the ariadne package [1]. I noticed that the current RPROMPT line is composed by percol.view.PROMPT [2] and percol.view.__class__.RPROMPT [3], as shown below: X10DAi-00 (M-h/M-n)> M-m:string Path:C-d Local:C-l Unique:M-r Exit0:M-t Fold:F1,F2,F3 But this leaves very little room for the search string used to filter the history. So, I want to split the RPROMPT line into two lines as follows: M-m:string Path:C-d Local:C-l Unique:M-r Exit0:M-t Fold:F1,F2,F3 X10DAi-00 (M-h/M-n)> But I've tried a lot and still don't know how to do it. Any hints will be highly appreciated. Regareds, HY [1] https://github.com/hongyi-zhao/ariadne [2] https://github.com/hongyi-zhao/ariadne/blob/ec864434b8a947b801f019e84c827c3a96dcf7e4/rc.py#L56 [3] https://github.com/hongyi-zhao/ariadne/blob/ec864434b8a947b801f019e84c827c3a96dcf7e4/rc.py#L73 -- https://mail.python.org/mailman/listinfo/python-list
Re: on floating-point numbers
"Peter J. Holzer" writes: > On 2021-09-05 03:38:55 +1200, Greg Ewing wrote: >> If 7.23 were exactly representable, you would have got >> 723/1000. >> >> Contrast this with something that *is* exactly representable: >> >> >>> 7.875.as_integer_ratio() >> (63, 8) >> >> and observe that 7875/1000 == 63/8: >> >> >>> from fractions import Fraction >> >>> Fraction(7875,1000) >> Fraction(63, 8) >> >> In general, to find out whether a decimal number is exactly >> representable in binary, represent it as a ratio of integers >> where the denominator is a power of 10, reduce that to lowest >> terms, > > ... and check if the denominator is a power of two. If it isn't (e.g. > 1000 == 2**3 * 5**3) then the number is not exactly representable as a > binary floating point number. > > More generally, if the prime factorization of the denominator only > contains prime factors which are also prime factors of your base, then > the number can be exactle represented (unless either the denominator or > the enumerator get too big). So, for base 10 (2*5), all numbers which > have only powers of 2 and 5 in the denominator (e.g 1/10 == 1/(2*5), > 1/8192 == 1/2**13, 1/1024000 == 1/(2**13 * 5**3)) can represented > exactly, but those with other prime factors (e.g. 1/3, 1/7, > 1/24576 == 1/(2**13 * 3), 1/1024001 == 1/(11 * 127 * 733)) cannot. > Similarly, for base 12 (2*2*3) numbers with 2 and 3 in the denominator > can be represented and for base 60 (2*2*3*5), numbers with 2, 3 and 5. Very grateful to these paragraphs. They destroy all the mystery. -- https://mail.python.org/mailman/listinfo/python-list
Re: CPython / Decimal and bit length of value.
Il 03/09/2021 22:09, Nacnud Nac ha scritto: Hi, Is there a quick way to get the number of bits required to store the value in a Decimal class? What obvious thing am I missing? I'm working with really large integers, say, in the order of 5_000_000 of ASCII base 10 digits. It seems the function mpd_sizeinbase would be a nice thing to be able to call. It'd be nice to just be able to tell the "size of data", or something like that, that was stored in the *data? I note there is len "field" in the structure mpd_t Sorry for the dumb question Thanks,Duncan to semplfy the example I'll use the value 100: value="100" exponent in base 10 is len(value) - 1 # (1 * 10^6) now need change from base 10 to base 2: newexp = 6 / log(2) # 19 (more or less) you will need newexp + 1 bits to represent the number: 2^20 = 1.048.576 hope helps -- https://mail.python.org/mailman/listinfo/python-list
Re: on floating-point numbers
Chris Angelico writes: > On Sun, Sep 5, 2021 at 1:04 PM Hope Rouselle wrote: >> The same question in other words --- what's a trivial way for the REPL >> to show me such cycles occur? >> >> >> 7.23.as_integer_ratio() >> >>> (2035064081618043, 281474976710656) >> >> Here's what I did on this case. The REPL is telling me that >> >> 7.23 = 2035064081618043/281474976710656 >> >> If that were true, then 7.23 * 281474976710656 would have to equal >> 2035064081618043. So I typed: >> >> >>> 7.23 * 281474976710656 >> 2035064081618043.0 >> >> That agrees with the falsehood. I'm getting no evidence of the problem. >> >> When take control of my life out of the hands of misleading computers, I >> calculate the sum: >> >>844424930131968 >> +5629499534213120 >> 197032483697459200 >> == >> 203506408161804288 >> =/= 203506408161804300 >> >> How I can save the energy spent on manual verification? > > What you've stumbled upon here is actually a neat elegance of > floating-point, and an often-forgotten fundamental of it: rounding > occurs exactly the same regardless of the scale. The number 7.23 is > represented with a certain mantissa, and multiplying it by some power > of two doesn't change the mantissa, only the exponent. So the rounding > happens exactly the same, and it comes out looking equal! That's insightful. Thanks! > The easiest way, in Python, to probe this sort of thing is to use > either fractions.Fraction or decimal.Decimal. I prefer Fraction, since > a float is fundamentally a rational number, and you can easily see > what's happening. You can construct a Fraction from a string, and > it'll do what you would expect; or you can construct one from a float, > and it'll show you what that float truly represents. > > It's often cleanest to print fractions out rather than just dumping > them to the console, since the str() of a fraction looks like a > fraction, but the repr() looks like a constructor call. > Fraction(0.25) > Fraction(1, 4) Fraction(0.1) > Fraction(3602879701896397, 36028797018963968) > > If it looks like the number you put in, it was perfectly > representable. If it looks like something of roughly that many digits, > it's probably not the number you started with. That's pretty, pretty nice. It was really what I was looking for. -- You're the best ``little lord of local nonsense'' I've ever met! :-D (Lol. The guy is kinda stressed out! Plonk, plonk, plonk. EOD.) -- https://mail.python.org/mailman/listinfo/python-list
RE: on writing a while loop for rolling two dice
I actually like it if a language lets you spell out your intention, although adding many keywords is not a plus. So, yes something like: loop ... end loop; Is appealing as it makes clear the decision on when to exit the loop must be within the loop (or till something kills ...) In languages like C/C++ there are people who make up macros like: #define INDEFINITELY_LOOP while (true) Or something like that and then allow the preprocessor to replace INDEFINITELY_LOOP with valid C code. So, how to do something like that in python, is a challenge left to the user 😉 Bottom line I find is it is a great idea to write comments as even if you are the one reviewing the code much later, you may struggle to figure out what you did and why. -Original Message- From: Python-list On Behalf Of Dennis Lee Bieber Sent: Sunday, September 5, 2021 12:50 PM To: [email protected] Subject: Re: on writing a while loop for rolling two dice On Sat, 4 Sep 2021 12:27:55 -0500, "Michael F. Stemper" declaimed the following: > >Kernighan and Ritchie agree(d) with you. Per _The C Programming >Language__: > Experience shows that do-while is much less used that while > and for. > And just for confusion, consider languages with "repeat / until"... "do / while" repeats so long as the condition evaluates to "true"; "repeat / until" /exits/ when the condition evaluates to "true". Then... there is Ada... While one is most likely to encounter constructs: for ix in start..end loop ... end loop; and while condition loop ... end loop; the core construct is just a bare loop ... end loop; which, with the "exit when condition" statement allows low-level emulation of any loop... (same as Python "if condition: break" loop-- "while" loop exit when not condition; ... end loop; loop-- "repeat / until" ... exit when condition; end loop; loop-- split ... exit when condition; ... end loop; {I'm not going to do the "for" loop, but one can easily manage initialization/increment/test statements}. To really get your mind blown, look at loops in REXX... do while condition ... end do until condition /* note that the termination parameter is listed at top, */ /* but takes effect at the bottom, so always one pass */ ... end do forever ... if condition then leave ... end do idx = start to end /* optional: by increment */ ... end do idx = 1 by increment for repetitions ... end AND worse! You can combine them... do idx = start for repetitions while condition1 until condition2 ... end {I need to check if both while and until can be in the same statement} -- Wulfraed Dennis Lee Bieber AF6VN [email protected]://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
RE: on writing a while loop for rolling two dice
Let me add something, Stefan. Some people just want to get a job done. For this person, he had a very specific need for a one-time project where the rest of it was understood but one small step was confusing. Frankly, he could have done it faster by opening a text editor on something like a CSV file and flipped some (actual) three-sided coins while manually doing a cut and past of lines into three new files and near the end, make sure the last few only went into files with a missing row or two. I have too often had people ask me for programming help and when I suggested they learn how to do it or let me make a more careful piece of code that checks for errors or will easily work under various changed conditions, guess what I usually encounter? Many just want it DONE. They often sheepishly come back some time later with some variant of the same need that mysteriously does not work with code they asked to be designed to just work in one case! Often they hack away at the code in odd ways first and then come to me to have it fixed. But there are costs to generality and creating functions with dozens of optional arguments and that handle a wide variety of inputs and thus constantly are checking what types they are working with and perhaps converting to others or need to create objects with lots of dunders, can also make it error prone. Looking at our forever loop discussion, how often are the contents of the loop written with multiple terminating parts within the loop body that get complex? I mean lots of break or continue statements all over the place with multi-part if statements. Some can be rewritten as a more standard loop with a condition like "while (a < 5 && found_it == FALSE || ( ... )) ..." and often in the body you need if statements that let you skip the rest if found_it is true. It can be a mess either way. At times you need to consider rewriting it from scratch. This especially happens as requirements keep changing. Ages ago we had code that processed MTA headers and every time we had a meeting of standards bodies, we kept adding ever more headers and keywords that often required some existing code to also look at other headers that now might be present as they might change what you did in existing code locations. I eventually suggested a rewrite and it turned out to be more compact now that we evaluated some things first, rather than within many existing parts. Has anyone mentioned the really stupid looking forever loop in languages with the other style of for loop? for ( ; ;) All that generally was, was an initialization command before a while and so on but here all three parts were null, so why use it? And in the python version, has anyone made a generator that returned NULL or the like so you can say uselessly: for ( _ in forever() ) ... -Original Message- From: Python-list On Behalf Of Stefan Ram Sent: Monday, September 6, 2021 12:34 PM To: [email protected] Subject: Re: on writing a while loop for rolling two dice "Avi Gross" writes: >For some people the "while true" method seems reasonable but it has a >problem if the internal body does not have some guarantee of an exit. >And A programming error where the condition used does not express the intent of the programmer can happen with any kind of while loop. >help explain to the reader what your intention is, if done properly. It >also can confuse if you put in "while 5 < 6" or other weird ways to say >do this indefinitely. If any reader cannot understand "while True:", it's not a problem with the source code. When someone writes "while True:", it is clearly his intention that the following indented code is repeated until it's exited by some means, which means is not the while condition. >His solution was to repeat large sections of code, three times, with >some modification, for the cases where the remainder (modulo N) was 0, 1 or 2. This is typical of - beginners who just do not know the means of the language to reduce redundancy yet, - less experience programmers, who know the language but still are not able to apply features to reduce redundancy always, - premature publication of unfinished code where the redundancy has not yet been reduced, or - programmers who do not have the personal means to climb to the level of abstraction needed to remove the redundancy in a specific case. And, I think you wrote that too, sometimes less smart code is more readable or maintainable. Maybe three very similar blocks are repeated literally because future modifications are expected that will make them less similar. -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: on writing a while loop for rolling two dice
On 2021-09-06 at 20:11:41 -0400, Avi Gross via Python-list wrote: > And in the python version, has anyone made a generator that returned > NULL or the like so you can say uselessly: > > for ( _ in forever() ) ... while "forever": ... -- https://mail.python.org/mailman/listinfo/python-list
RE: on writing a while loop for rolling two dice
I hate to quibble but as almost anything in Python can evaluate to being
truthy, a command like
while "never"
evaluates to true as the string is not empty.
I meant a generator like
>>> def boring():
while True: yield()
>>> for _ in boring():
print("repeating ...")
The above gives me a nice infinite loop, with the second one looking like a
normal loop but actually doing nothing much.
-Original Message-
From: Python-list On
Behalf Of [email protected]
Sent: Monday, September 6, 2021 8:28 PM
To: [email protected]
Subject: Re: on writing a while loop for rolling two dice
On 2021-09-06 at 20:11:41 -0400,
Avi Gross via Python-list wrote:
> And in the python version, has anyone made a generator that returned
> NULL or the like so you can say uselessly:
>
> for ( _ in forever() ) ...
while "forever":
...
--
https://mail.python.org/mailman/listinfo/python-list
--
https://mail.python.org/mailman/listinfo/python-list
Non sequitur: on writing a while loop for rolling two dice
On Mon, 6 Sep 2021 20:11:41 -0400, Avi Gross via Python-list declaimed the following: >changing. Ages ago we had code that processed MTA headers and every time we >had a meeting of standards bodies, we kept adding ever more headers and Why did my mind immediately flash on "The Man Who Never Returned"? (Especially as you describe just the opposite -- many returns ) -- Wulfraed Dennis Lee Bieber AF6VN [email protected]://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
Non sequitur: on writing a while loop for rolling two dice
RESEND with clarification! On Mon, 6 Sep 2021 20:11:41 -0400, Avi Gross via Python-list declaimed the following: >changing. Ages ago we had code that processed MTA headers and every time we >had a meeting of standards bodies, we kept adding ever more headers and Why did my mind immediately flash on "The Man Who Never Returned"? (AKA: "M.T.A.", Kingston Trio song) (Especially as you describe just the opposite -- many returns ) -- Wulfraed Dennis Lee Bieber AF6VN [email protected]://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list
RE: on writing a while loop for rolling two dice
It has been nearly three decades since I have had to write in C, Stefan, but what I suggested jokingly is quite mild compared to what the winners of the obfuscated C Contest do: https://www.ioccc.org/ Time for me to drop out of this thread. Personally I fully agree uses of "while' as described are perfectly understandable. Features that sophisticated programmers love tend to confuse novices. I recall my exposure to PERL where weird things seemed to just happen with no rhyme or reason or connections. Turned out just about everything puts things into or takes them out of hidden variables so much of the time, a string of commands just does what might be expected. Another variant on the elusive concept of a pipeline. But all the nice gimmicks and tricks make novices a bit puzzled. On the other hand, you can still write most programs the old fashioned way and sort of start normal then head off into hyperspace at warp speed. Python too has a way to write fairly unsophisticated programs as well as idioms and methods that rapidly become hard to comprehend. -Original Message- From: Python-list On Behalf Of Stefan Ram Sent: Monday, September 6, 2021 7:49 PM To: [email protected] Subject: Re: on writing a while loop for rolling two dice "Avi Gross" writes: > In languages like C/C++ there are people who make up macros like: >#define INDEFINITELY_LOOP while (true) >Or something like that and then allow the preprocessor to replace >INDEFINITELY_LOOP with valid C code. Those usually are beginners. >So, how to do something like that in python, is a challenge left to the >user Such a use of macros is frowned upon by most C programmers, because it renders the code unreadable. "while(1)" in C or "while True:" in Python is perfectly clear. Don't fix it if it ain't broke! -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
