Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #110876 > unrolled thread
| Started by | Elizabeth Weiss <cake240@gmail.com> |
|---|---|
| First post | 2016-06-30 20:08 -0700 |
| Last post | 2016-07-01 10:57 +0200 |
| Articles | 20 on this page of 23 — 12 participants |
Back to article view | Back to comp.lang.python
Creating a calculator Elizabeth Weiss <cake240@gmail.com> - 2016-06-30 20:08 -0700
Re: Creating a calculator Michael Torrie <torriem@gmail.com> - 2016-06-30 21:38 -0600
Re: Creating a calculator DFS <nospam@dfs.com> - 2016-06-30 23:57 -0400
Re: Creating a calculator DFS <nospam@dfs.com> - 2016-07-01 00:54 -0400
Re: Creating a calculator Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-07-01 09:42 +0300
Re: Creating a calculator Christopher Reimer <christopher_reimer@icloud.com> - 2016-07-01 05:25 -0700
Re: Creating a calculator Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-07-01 15:46 +0300
Re: Creating a calculator Christopher Reimer <christopher_reimer@icloud.com> - 2016-07-01 06:19 -0700
Re: Creating a calculator Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-07-01 16:35 +0300
Re: Creating a calculator Steven D'Aprano <steve@pearwood.info> - 2016-07-01 23:52 +1000
Re: Creating a calculator alister <alister.ware@ntlworld.com> - 2016-07-01 14:21 +0000
Re: Creating a calculator Christopher Reimer <christopher_reimer@icloud.com> - 2016-07-01 07:15 -0700
Re: Creating a calculator Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-07-01 20:44 +0300
Re: Creating a calculator Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2016-07-04 12:32 +0200
Re: Creating a calculator DFS <nospam@dfs.com> - 2016-07-01 20:16 -0400
Re: Creating a calculator pdorange@pas-de-pub-merci.mac.com (Pierre-Alain Dorange) - 2016-07-01 11:34 +0200
Re: Creating a calculator Chris Warrick <kwpolska@gmail.com> - 2016-07-01 13:39 +0200
Re: Creating a calculator pdorange@pas-de-pub-merci.mac.com (Pierre-Alain Dorange) - 2016-07-01 15:03 +0200
Re: Creating a calculator DFS <nospam@dfs.com> - 2016-07-01 20:16 -0400
Re: Creating a calculator pdorange@pas-de-pub-merci.mac.com (Pierre-Alain Dorange) - 2016-07-04 11:50 +0200
Re: Creating a calculator BartC <bc@freeuk.com> - 2016-07-06 01:53 +0100
Re: Creating a calculator Quivis <quivis@domain.invalid> - 2016-07-07 22:00 +0000
Re: Creating a calculator Chris Warrick <kwpolska@gmail.com> - 2016-07-01 10:57 +0200
Page 1 of 2 [1] 2 Next page →
| From | Elizabeth Weiss <cake240@gmail.com> |
|---|---|
| Date | 2016-06-30 20:08 -0700 |
| Subject | Creating a calculator |
| Message-ID | <a0ed0591-dcbb-4ad2-b69a-58feef50153a@googlegroups.com> |
while True:
print("Options:")
print("Enter 'add' to add two numbers")
print("Enter 'subtract' to subtract two numbers")
print("Enter 'multiply' to multiply two numbers")
print("Enter 'divide' to divide two numbers")
print("Enter 'quit' to end the program")
user_input=input(":")
if user_input=="quit":
break
elif user_input=="add":
num1=float(input("Enter a number"))
num2=float(input("Enter another number"))
result=str(num1+num2)
print("The answer is"+ result)
elif user_input=="subtract":
num1=float(input("Enter a number"))
num2=float(input("Enter another number"))
result=str(num1-num2)
print("The answer is"+result)
Two questions:
1. Why do I need to put ' ' around the words add, subtract, multiply, quit, etc. when it is already in quotes in print()? When the calculator asks me which option I would like to choose I do not write 'add'- I only write add.
2. The program I am using to help me learn python mentions that the output line could be put outside the if statements to omit repetition of code. What does this mean and how would I write the code differently according to this?
Thank you!
[toc] | [next] | [standalone]
| From | Michael Torrie <torriem@gmail.com> |
|---|---|
| Date | 2016-06-30 21:38 -0600 |
| Message-ID | <mailman.151.1467344302.2358.python-list@python.org> |
| In reply to | #110876 |
On 06/30/2016 09:08 PM, Elizabeth Weiss wrote:
> while True:
> print("Options:")
> print("Enter 'add' to add two numbers")
> print("Enter 'subtract' to subtract two numbers")
> print("Enter 'multiply' to multiply two numbers")
> print("Enter 'divide' to divide two numbers")
> print("Enter 'quit' to end the program")
> user_input=input(":")
> if user_input=="quit":
> break
> elif user_input=="add":
> num1=float(input("Enter a number"))
> num2=float(input("Enter another number"))
> result=str(num1+num2)
> print("The answer is"+ result)
> elif user_input=="subtract":
> num1=float(input("Enter a number"))
> num2=float(input("Enter another number"))
> result=str(num1-num2)
> print("The answer is"+result)
>
> Two questions:
> 1. Why do I need to put ' ' around the words add, subtract, multiply, quit, etc. when it is already in quotes in print()? When the calculator asks me which option I would like to choose I do not write 'add'- I only write add.
I think those extra quotes are just to make the output stand out when
it's printed to the screen so that the user knows that the word in
quotes is the special word they will need to type in. It's much like
how things are quoted in literature.
Since the string is already inside of double quotes, the inner single
quotes simply get printed. And if you wanted to print real double
quotes to the screen, you can surround the string with single quotes.
Either works, depending on which quote character you want to actually
print to the screen.
Here's examples using the interactive python prompt:
>>> print ('He said, "How are you?"')
He said, "How are you?"
>>> print ("In British books one might say, 'How are you?'")
In British books one might say, 'How are you?'
Hope this helps.
>
> 2. The program I am using to help me learn python mentions that the output line could be put outside the if statements to omit repetition of code. What does this mean and how would I write the code differently according to this?
It means that since each of the elif blocks does something that needs to
be printed out, and if it's being printed out the same way by each, then
you can just stick it at the end of the if processing block so that it
always runs regardless of which elif block did the computation. Though
in your code example this isn't strictly true, since if the input was
not "add" or "subtract" then there is no result to print. At least if
the code you posted was complete.
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2016-06-30 23:57 -0400 |
| Message-ID | <nl4pnj$isr$2@dont-email.me> |
| In reply to | #110876 |
On 6/30/2016 11:08 PM, Elizabeth Weiss wrote:
> while True: print("Options:") print("Enter 'add' to add two
> numbers") print("Enter 'subtract' to subtract two numbers")
> print("Enter 'multiply' to multiply two numbers") print("Enter
> 'divide' to divide two numbers") print("Enter 'quit' to end the
> program") user_input=input(":") if user_input=="quit": break elif
> user_input=="add": num1=float(input("Enter a number"))
> num2=float(input("Enter another number")) result=str(num1+num2)
> print("The answer is"+ result) elif user_input=="subtract":
> num1=float(input("Enter a number")) num2=float(input("Enter another
> number")) result=str(num1-num2) print("The answer is"+result)
>
> Two questions: 1. Why do I need to put ' ' around the words add,
> subtract, multiply, quit, etc. when it is already in quotes in
> print()? When the calculator asks me which option I would like to
> choose I do not write 'add'- I only write add.
Use raw_input instead of input, and you won't need to write the
apostrophes. They're shown in your example just for emphasis.
> 2. The program I am using to help me learn python mentions that the
> output line could be put outside the if statements to omit repetition
> of code. What does this mean and how would I write the code
> differently according to this?
>
> Thank you!
Consider this 13-line version which accomplishes the same as your
original 20 lines (actually more - it also does the multiply and
divide). This is python 2.7.11 on Windows.
while True:
print('Enter add, subtract, multiply or divide')
print('(or enter quit to end the program)')
ui=raw_input(': ')
if ui=='quit': break
num1=float(raw_input('Enter a number: '))
num2=float(raw_input('Enter the number to '+ui+': '))
if ui=='add' : result=str(num1+num2)
if ui=='subtract' : result=str(num1-num2)
if ui=='multiply' : result=str(num1*num2)
if ui=='divide' : result=str(num1/num2)
print('The answer is: ' + result)
print
I put the blank lines in for readability. You can remove them with no
impact.
Notice the 2nd number input prompts you with the operation you said to
perform. That's just a 'nice to have' to help the user.
Notice I don't use elif - that's a personal choice I made for this tiny
program - I like the way it looks and reads. It also means all 4 if
statements will be evaluated each time the code runs, so the program is
technically a tiny bit slower and less-efficient. It's usually
considered bad form - never do it if the code will execute many times.
I also used apostrophes instead of quote marks. That's also a personal
choice. You can usually mix and match them in python.
Notice there's just one 'print answer' statement at the end - that's
what they're talking about "put outside the if statements to omit
repetition".
The last print is to add a blank line on screen before the next prompt.
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2016-07-01 00:54 -0400 |
| Message-ID | <nl4t1n$qgp$2@dont-email.me> |
| In reply to | #110876 |
On 6/30/2016 11:08 PM, Elizabeth Weiss wrote:
> while True:
> print("Options:")
> print("Enter 'add' to add two numbers")
> print("Enter 'subtract' to subtract two numbers")
> print("Enter 'multiply' to multiply two numbers")
> print("Enter 'divide' to divide two numbers")
> print("Enter 'quit' to end the program")
> user_input=input(":")
> if user_input=="quit":
> break
> elif user_input=="add":
> num1=float(input("Enter a number"))
> num2=float(input("Enter another number"))
> result=str(num1+num2)
> print("The answer is"+ result)
> elif user_input=="subtract":
> num1=float(input("Enter a number"))
> num2=float(input("Enter another number"))
> result=str(num1-num2)
> print("The answer is"+result)
>
> Two questions:
> 1. Why do I need to put ' ' around the words add, subtract, multiply, quit, etc. when it is already in quotes in print()? When the calculator asks me which option I would like to choose I do not write 'add'- I only write add.
>
> 2. The program I am using to help me learn python mentions that the output line could be put outside the if statements to omit repetition of code. What does this mean and how would I write the code differently according to this?
>
> Thank you!
Here's a related program that doesn't require you to tell it what type
of operation to perform. Just enter 'num1 operator num2' and hit Enter,
and it will parse the entry and do the math.
-----------------------------------------------
ui=raw_input('Enter calculation to perform: ')
n1=float(ui.split(' ')[0])
op=ui.split(' ')[1]
n2=float(ui.split(' ')[2])
if op=='+':c=n1+n2
if op=='-':c=n1-n2
if op=='*':c=n1*n2
if op=='/':c=n1/n2
print(ui+' = '+str(c))
-----------------------------------------------
Note that it requires you to enter spaces in the calculation:
3 * 4
33 / 11
17 + 18
etc
The split() command, on lines 2,3,4, parses the data you entered and
puts it into variables. The numbers in brackets [0] [1] [2] are the
index positions of the data ([0] is the 1st item, [1] is the 2nd item,
etc. It's called 0-base indexing.).
calc = 3 * 4
calc.split(' ')
index[0] = 3
index[1] = *
index[2] = 4
as opposed to:
calc = 3*4
calc.split('*')
index[0] = 3
index[1] = 4
index[2] = error list index out of range
See what's happening there?
Notice I used short variable names:
ui = user input
n1 = 1st number
op = math operator
n2 = 2nd number
c = the calculation
I also used 2 statements on one line, with few spaces:
if op=='*':c=n1*n2
is the same as:
if op == '*':
c = n1 * n2
That's all personal choice. It's a tradeoff between readability and
maintainability (say if someone else inherits your program), and brevity
for you, the developer. Python 'purists' won't like it, but I like the
tight code. Do what makes you comfortable.
[toc] | [prev] | [next] | [standalone]
| From | Jussi Piitulainen <jussi.piitulainen@helsinki.fi> |
|---|---|
| Date | 2016-07-01 09:42 +0300 |
| Message-ID | <lf5oa6hhn9x.fsf@ling.helsinki.fi> |
| In reply to | #110881 |
DFS writes:
> Here's a related program that doesn't require you to tell it what type
> of operation to perform. Just enter 'num1 operator num2' and hit
> Enter, and it will parse the entry and do the math.
>
> -----------------------------------------------
> ui=raw_input('Enter calculation to perform: ')
> n1=float(ui.split(' ')[0])
> op=ui.split(' ')[1]
> n2=float(ui.split(' ')[2])
> if op=='+':c=n1+n2
> if op=='-':c=n1-n2
> if op=='*':c=n1*n2
> if op=='/':c=n1/n2
> print(ui+' = '+str(c))
> -----------------------------------------------
I use multiple assignment a lot, like this:
n1, op, n2 = ui.split()
It's not only compact, it also crashes if there are more elements than
expected, and I want it to crash when that happens. Or rather, I prefer
a crash to silence when input is bad.
For the calculator, it may be better to split on any whitespace and
discard empty strings, which is what ui.split() does. Splitting on a
single space seems unnecessarily strict in a calculator (whereas
splitting on a single tab is what I very much do in my work - the data
formats are such).
I think multiple assignment is good even for a beginner. Perhaps do it a
second time straight away:
n1, op, n2 = ui.split()
n1, n2 = float(n1), float(n2)
But it's only with the split where it really pays.
n1, op, n2 = ui.split()
n1 = float(n1)
n2 = float(n2)
The latter might be even preferable. Hm.
n1, n2 = map(float, (n1, n2))
:)
[toc] | [prev] | [next] | [standalone]
| From | Christopher Reimer <christopher_reimer@icloud.com> |
|---|---|
| Date | 2016-07-01 05:25 -0700 |
| Message-ID | <mailman.156.1467375975.2358.python-list@python.org> |
| In reply to | #110886 |
> On Jun 30, 2016, at 11:42 PM, Jussi Piitulainen <jussi.piitulainen@helsinki.fi> wrote:
>
> DFS writes:
>
>> Here's a related program that doesn't require you to tell it what type
>> of operation to perform. Just enter 'num1 operator num2' and hit
>> Enter, and it will parse the entry and do the math.
>>
>> -----------------------------------------------
>> ui=raw_input('Enter calculation to perform: ')
>> n1=float(ui.split(' ')[0])
>> op=ui.split(' ')[1]
>> n2=float(ui.split(' ')[2])
>> if op=='+':c=n1+n2
>> if op=='-':c=n1-n2
>> if op=='*':c=n1*n2
>> if op=='/':c=n1/n2
>> print(ui+' = '+str(c))
>> -----------------------------------------------
>
> I use multiple assignment a lot, like this:
>
> n1, op, n2 = ui.split()
>
> It's not only compact, it also crashes if there are more elements than
> expected, and I want it to crash when that happens. Or rather, I prefer
> a crash to silence when input is bad.
>
> For the calculator, it may be better to split on any whitespace and
> discard empty strings, which is what ui.split() does. Splitting on a
> single space seems unnecessarily strict in a calculator (whereas
> splitting on a single tab is what I very much do in my work - the data
> formats are such).
>
> I think multiple assignment is good even for a beginner. Perhaps do it a
> second time straight away:
>
> n1, op, n2 = ui.split()
> n1, n2 = float(n1), float(n2)
>
> But it's only with the split where it really pays.
>
> n1, op, n2 = ui.split()
> n1 = float(n1)
> n2 = float(n2)
>
> The latter might be even preferable. Hm.
>
> n1, n2 = map(float, (n1, n2))
>
> :)
For my BASIC interpreter, each line of BASIC is broken this way into tokens.
line_number, keyword, *expression = line.split(' ', 2)
For a line like 10 PRINT "HELLO, WORLD!", this works as expected.
For a line like 20 END, which doesn't have a third element for expression, an empty list is assigned.
By using * to unpack the split line, my program no longer crashes and no try/except block is needed to work around the crash. A later line of code will test the expression, ignore if empty or run regex if full.
Chris R.
[toc] | [prev] | [next] | [standalone]
| From | Jussi Piitulainen <jussi.piitulainen@helsinki.fi> |
|---|---|
| Date | 2016-07-01 15:46 +0300 |
| Message-ID | <lf5poqxmsqc.fsf@ling.helsinki.fi> |
| In reply to | #110893 |
Christopher Reimer writes:
> For my BASIC interpreter, each line of BASIC is broken this way into
> tokens.
>
> line_number, keyword, *expression = line.split(' ', 2)
>
> For a line like 10 PRINT "HELLO, WORLD!", this works as expected.
>
> For a line like 20 END, which doesn't have a third element for
> expression, an empty list is assigned.
>
> By using * to unpack the split line, my program no longer crashes and
> no try/except block is needed to work around the crash. A later line
> of code will test the expression, ignore if empty or run regex if
> full.
Yes.
Consider line.split(None, 2) or line.split(maxsplit=2). You may still
need to strip the third component, but at least it will *be* the third
component even if the user happens to type extra spaces like this:
10 PRINT "Hello, world."
And you won't get a spurious third component if the user types this:
20 END
(There's trailing spaces.)
[toc] | [prev] | [next] | [standalone]
| From | Christopher Reimer <christopher_reimer@icloud.com> |
|---|---|
| Date | 2016-07-01 06:19 -0700 |
| Message-ID | <mailman.157.1467379145.2358.python-list@python.org> |
| In reply to | #110894 |
> On Jul 1, 2016, at 5:46 AM, Jussi Piitulainen <jussi.piitulainen@helsinki.fi> wrote:
>
> Christopher Reimer writes:
>
>> For my BASIC interpreter, each line of BASIC is broken this way into
>> tokens.
>>
>> line_number, keyword, *expression = line.split(' ', 2)
>>
>> For a line like 10 PRINT "HELLO, WORLD!", this works as expected.
>>
>> For a line like 20 END, which doesn't have a third element for
>> expression, an empty list is assigned.
>>
>> By using * to unpack the split line, my program no longer crashes and
>> no try/except block is needed to work around the crash. A later line
>> of code will test the expression, ignore if empty or run regex if
>> full.
>
> Yes.
>
> Consider line.split(None, 2) or line.split(maxsplit=2). You may still
> need to strip the third component, but at least it will *be* the third
> component even if the user happens to type extra spaces like this:
>
> 10 PRINT "Hello, world."
>
> And you won't get a spurious third component if the user types this:
>
> 20 END
>
> (There's trailing spaces.)
This is a BASIC interpreter. Any extra spaces for line_number or keyword will raise an incomprehensible syntax error, as the line number must convert to an integer and the keyword much match the KEYWORDS list. As for trailing spaces for expression, regex will keep them whole if enclosed in double quotes or convert them to a list element. Depending on the keyword grammar, extra spaces are likely to be ignored.
A C interpreter would be more difficult as the same line of code could be written several different ways and be valid.
FILE *source
FILE * source
FILE* source
FILE*source
The first line is how I normally see this statement written. The last line I found in a 1991 book with a strange dialect of C that I've never seen before and doesn't always compile correctly without modification. Writing a C interpreter is not on my to do list.
Chris R.
[toc] | [prev] | [next] | [standalone]
| From | Jussi Piitulainen <jussi.piitulainen@helsinki.fi> |
|---|---|
| Date | 2016-07-01 16:35 +0300 |
| Message-ID | <lf5lh1lmqfm.fsf@ling.helsinki.fi> |
| In reply to | #110896 |
Christopher Reimer writes:
>> On Jul 1, 2016, at 5:46 AM, Jussi Piitulainen wrote:
>>
>> Christopher Reimer writes:
>>
>>> For my BASIC interpreter, each line of BASIC is broken this way into
>>> tokens.
>>>
>>> line_number, keyword, *expression = line.split(' ', 2)
>>>
>>> For a line like 10 PRINT "HELLO, WORLD!", this works as expected.
>>>
>>> For a line like 20 END, which doesn't have a third element for
>>> expression, an empty list is assigned.
>>>
>>> By using * to unpack the split line, my program no longer crashes and
>>> no try/except block is needed to work around the crash. A later line
>>> of code will test the expression, ignore if empty or run regex if
>>> full.
>>
>> Yes.
>>
>> Consider line.split(None, 2) or line.split(maxsplit=2). You may still
>> need to strip the third component, but at least it will *be* the third
>> component even if the user happens to type extra spaces like this:
>>
>> 10 PRINT "Hello, world."
>>
>> And you won't get a spurious third component if the user types this:
>>
>> 20 END
>>
>> (There's trailing spaces.)
>
> This is a BASIC interpreter. Any extra spaces for line_number or
> keyword will raise an incomprehensible syntax error, as the line
> number must convert to an integer and the keyword much match the
> KEYWORDS list. As for trailing spaces for expression, regex will keep
> them whole if enclosed in double quotes or convert them to a list
> element. Depending on the keyword grammar, extra spaces are likely to
> be ignored.
You get to decide!
(But if you split on whitespace as I suggested, there won't be any extra
spaces in the line number or keyword. While if you split on every single
space, the first and second component of the split may not even contain
the intended line number and keyword. Try it. Then do what you like.)
> A C interpreter would be more difficult as the same line of code could
> be written several different ways and be valid.
>
> FILE *source
> FILE * source
> FILE* source
> FILE*source
>
> The first line is how I normally see this statement written. The last
> line I found in a 1991 book with a strange dialect of C that I've
> never seen before and doesn't always compile correctly without
> modification. Writing a C interpreter is not on my to do list.
C syntax is not line-oriented anyway. It's semicolon-oriented.
Good luck with your BASIC interpreter. (No sarcasm or anything like
that. I think it's a nice project.)
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2016-07-01 23:52 +1000 |
| Message-ID | <577675ae$0$1604$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #110893 |
On Fri, 1 Jul 2016 10:25 pm, Christopher Reimer wrote:
> For my BASIC interpreter, each line of BASIC is broken this way into
> tokens.
[...]
> By using * to unpack the split line, my program no longer crashes and no
> try/except block is needed to work around the crash. A later line of code
> will test the expression, ignore if empty or run regex if full.
I wish you wouldn't describe this as "crash".
The Python interpreter should never crash. That would be a segmentation
fault, and that is considered to be a very serious bug.
But *raising an exception* is another story. Raising exceptions is not a
crash, it is the interpreter working as expected. This statement:
line_number, keyword, expr = "20 END".split(' ', 2)
is SUPPOSED to raise an exception, if it didn't, the interpreter would be
broken. To call that a "crash" is horribly misleading.
--
Steven
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.
[toc] | [prev] | [next] | [standalone]
| From | alister <alister.ware@ntlworld.com> |
|---|---|
| Date | 2016-07-01 14:21 +0000 |
| Message-ID | <X%udz.951173$5w3.253344@fx40.am4> |
| In reply to | #110898 |
On Fri, 01 Jul 2016 23:52:45 +1000, Steven D'Aprano wrote:
> On Fri, 1 Jul 2016 10:25 pm, Christopher Reimer wrote:
>
>> For my BASIC interpreter, each line of BASIC is broken this way into
>> tokens.
> [...]
>> By using * to unpack the split line, my program no longer crashes and
>> no try/except block is needed to work around the crash. A later line of
>> code will test the expression, ignore if empty or run regex if full.
>
> I wish you wouldn't describe this as "crash".
>
> The Python interpreter should never crash. That would be a segmentation
> fault, and that is considered to be a very serious bug.
>
> But *raising an exception* is another story. Raising exceptions is not a
> crash, it is the interpreter working as expected. This statement:
>
> line_number, keyword, expr = "20 END".split(' ', 2)
>
> is SUPPOSED to raise an exception, if it didn't, the interpreter would
> be broken. To call that a "crash" is horribly misleading.
i think this one is a matter of symantics
you are correct that the Python interpreter has not crashed but the op
could also be considered correct is saying that HIS program has crashed.
As a child I had many programs "crash" in this way on my Commodore 64
without killing the basic interpreter (at-least not until I started to
include machine code ;-) )
--
Technology is dominated by those who manage what they do not understand.
[toc] | [prev] | [next] | [standalone]
| From | Christopher Reimer <christopher_reimer@icloud.com> |
|---|---|
| Date | 2016-07-01 07:15 -0700 |
| Message-ID | <mailman.1.1467386156.2295.python-list@python.org> |
| In reply to | #110898 |
> On Jul 1, 2016, at 6:52 AM, Steven D'Aprano <steve@pearwood.info> wrote:
>
>> On Fri, 1 Jul 2016 10:25 pm, Christopher Reimer wrote:
>>
>> For my BASIC interpreter, each line of BASIC is broken this way into
>> tokens.
> [...]
>> By using * to unpack the split line, my program no longer crashes and no
>> try/except block is needed to work around the crash. A later line of code
>> will test the expression, ignore if empty or run regex if full.
>
> I wish you wouldn't describe this as "crash".
>
> The Python interpreter should never crash. That would be a segmentation
> fault, and that is considered to be a very serious bug.
>
> But *raising an exception* is another story. Raising exceptions is not a
> crash, it is the interpreter working as expected. This statement:
>
> line_number, keyword, expr = "20 END".split(' ', 2)
>
> is SUPPOSED to raise an exception, if it didn't, the interpreter would be
> broken. To call that a "crash" is horribly misleading.
Where did I write that the Python interpreter had "crashed"?
I wrote that *my program* crashed and I found an elegant solution to prevent the crashing from happening in the first place that doesn't require a try/except block.
Chris R.
[toc] | [prev] | [next] | [standalone]
| From | Jussi Piitulainen <jussi.piitulainen@helsinki.fi> |
|---|---|
| Date | 2016-07-01 20:44 +0300 |
| Message-ID | <lf5h9c98d8l.fsf@ling.helsinki.fi> |
| In reply to | #110898 |
Steven D'Aprano writes:
> On Fri, 1 Jul 2016 10:25 pm, Christopher Reimer wrote:
>
>> For my BASIC interpreter, each line of BASIC is broken this way into
>> tokens.
> [...]
>> By using * to unpack the split line, my program no longer crashes and no
>> try/except block is needed to work around the crash. A later line of code
>> will test the expression, ignore if empty or run regex if full.
>
> I wish you wouldn't describe this as "crash".
>
> The Python interpreter should never crash. That would be a segmentation
> fault, and that is considered to be a very serious bug.
>
> But *raising an exception* is another story. Raising exceptions is not a
> crash, it is the interpreter working as expected. This statement:
>
> line_number, keyword, expr = "20 END".split(' ', 2)
>
> is SUPPOSED to raise an exception, if it didn't, the interpreter would
> be broken. To call that a "crash" is horribly misleading.
I think Christopher merely echoed my use of the word, so let me take the
blame.
But it's quite different to say "my program crashed" (didn't handle an
exception - fix program, or fix the input) and "the Python interpreter
crashed" (uh oh).
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2016-07-04 12:32 +0200 |
| Message-ID | <mailman.64.1467628458.2295.python-list@python.org> |
| In reply to | #110898 |
Op 01-07-16 om 15:52 schreef Steven D'Aprano:
> On Fri, 1 Jul 2016 10:25 pm, Christopher Reimer wrote:
>
>> For my BASIC interpreter, each line of BASIC is broken this way into
>> tokens.
> [...]
>> By using * to unpack the split line, my program no longer crashes and no
>> try/except block is needed to work around the crash. A later line of code
>> will test the expression, ignore if empty or run regex if full.
> I wish you wouldn't describe this as "crash".
I wish you wouldn't mix semantic levels.
>
> The Python interpreter should never crash. That would be a segmentation
> fault, and that is considered to be a very serious bug.
But in that case your computer didn't crash. That would be a your computer
freezing, or rebooting.
>
> But *raising an exception* is another story. Raising exceptions is not a
> crash, it is the interpreter working as expected. This statement:
A segment violation is not a crash either, your computer/os will just
carry on.
>
> line_number, keyword, expr = "20 END".split(' ', 2)
>
> is SUPPOSED to raise an exception, if it didn't, the interpreter would be
> broken. To call that a "crash" is horribly misleading.
Supposed by whom? The line may be supposed to raise an exception by
the languager designer, that doesn't mean the programmer meant to
write an instruction that would raise an exception. So the programmer
can correctly assert the line was not supposed to raise an exception.
--
Antoon.
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2016-07-01 20:16 -0400 |
| Message-ID | <nl7159$qrn$4@dont-email.me> |
| In reply to | #110886 |
On 7/1/2016 2:42 AM, Jussi Piitulainen wrote: > I use multiple assignment a lot, like this: > > n1, op, n2 = ui.split() Nice. Accomplishes a lot in one line. I often use multiple assignments, too, but of the simpler format: l1,l2,l3=[],[],[] i,j,k=0,0,0 > I think multiple assignment is good even for a beginner. Perhaps do it a > second time straight away: > > n1, op, n2 = ui.split() > n1, n2 = float(n1), float(n2) This would be my preference. It saves a line of code, and it's readable. > But it's only with the split where it really pays. > > n1, op, n2 = ui.split() > n1 = float(n1) > n2 = float(n2) > > The latter might be even preferable. Hm. > > n1, n2 = map(float, (n1, n2)) > > :) Getting fancy!
[toc] | [prev] | [next] | [standalone]
| From | pdorange@pas-de-pub-merci.mac.com (Pierre-Alain Dorange) |
|---|---|
| Date | 2016-07-01 11:34 +0200 |
| Message-ID | <1mpph6r.u6n05219srlzsN%pdorange@pas-de-pub-merci.mac.com> |
| In reply to | #110881 |
DFS <nospam@dfs.com> wrote:
> Here's a related program that doesn't require you to tell it what type
> of operation to perform. Just enter 'num1 operator num2' and hit Enter,
> and it will parse the entry and do the math.
>
> -----------------------------------------------
> ui=raw_input('Enter calculation to perform: ')
> n1=float(ui.split(' ')[0])
> op=ui.split(' ')[1]
> n2=float(ui.split(' ')[2])
> if op=='+':c=n1+n2
> if op=='-':c=n1-n2
> if op=='*':c=n1*n2
> if op=='/':c=n1/n2
> print(ui+' = '+str(c))
> -----------------------------------------------
More reduced :
----------------------------------
u=raw_input('Enter calculation:")
print eval(u)
----------------------------------
works and compute :
1+2+3+4-1+4*2
2+3.0/2-0.5
Perform better and shorter, but less educationnal of course...
--
Pierre-Alain Dorange Moof <http://clarus.chez-alice.fr/>
Ce message est sous licence Creative Commons "by-nc-sa-2.0"
<http://creativecommons.org/licenses/by-nc-sa/2.0/fr/>
[toc] | [prev] | [next] | [standalone]
| From | Chris Warrick <kwpolska@gmail.com> |
|---|---|
| Date | 2016-07-01 13:39 +0200 |
| Message-ID | <mailman.155.1467373181.2358.python-list@python.org> |
| In reply to | #110890 |
On 1 July 2016 at 11:34, Pierre-Alain Dorange
<pdorange@pas-de-pub-merci.mac.com> wrote:
> DFS <nospam@dfs.com> wrote:
>
>> Here's a related program that doesn't require you to tell it what type
>> of operation to perform. Just enter 'num1 operator num2' and hit Enter,
>> and it will parse the entry and do the math.
>>
>> -----------------------------------------------
>> ui=raw_input('Enter calculation to perform: ')
>> n1=float(ui.split(' ')[0])
>> op=ui.split(' ')[1]
>> n2=float(ui.split(' ')[2])
>> if op=='+':c=n1+n2
>> if op=='-':c=n1-n2
>> if op=='*':c=n1*n2
>> if op=='/':c=n1/n2
>> print(ui+' = '+str(c))
>> -----------------------------------------------
>
> More reduced :
> ----------------------------------
> u=raw_input('Enter calculation:")
> print eval(u)
> ----------------------------------
> works and compute :
> 1+2+3+4-1+4*2
> 2+3.0/2-0.5
>
> Perform better and shorter, but less educationnal of course...
No, this is awful. It’s a great way to compromise your system’s
security. Never use eval() for any reason, especially with user input
— if you were to type in __import__('os').system('…') with some
particularly dangerous command (rm, format, …), you would kill your
system.
--
Chris Warrick <https://chriswarrick.com/>
PGP: 5EAAEA16
[toc] | [prev] | [next] | [standalone]
| From | pdorange@pas-de-pub-merci.mac.com (Pierre-Alain Dorange) |
|---|---|
| Date | 2016-07-01 15:03 +0200 |
| Message-ID | <1mppott.nlnf47ya08hzN%pdorange@pas-de-pub-merci.mac.com> |
| In reply to | #110892 |
Chris Warrick <kwpolska@gmail.com> wrote:
> > More reduced :
> > ----------------------------------
> > u=raw_input('Enter calculation:")
> > print eval(u)
> > ----------------------------------
> > works and compute :
> > 1+2+3+4-1+4*2
> > 2+3.0/2-0.5
> >
> > Perform better and shorter, but less educationnal of course...
>
> No, this is awful. It's a great way to compromise your system's
> security. Never use eval() for any reason, especially with user input
> — if you were to type in __import__('os').system('…') with some
> particularly dangerous command (rm, format, …), you would kill your
> system.
Yes you're right, eval can be really dangerous.
You could make it (a little) safer using env ; but a hacker could always
break things with eval.
-------------------------------------
env={}
env["__builtins__"] = None
u=raw_input('Enter calculation:")
print eval(u,env)
-------------------------------------
--
Pierre-Alain Dorange Moof <http://clarus.chez-alice.fr/>
Ce message est sous licence Creative Commons "by-nc-sa-2.0"
<http://creativecommons.org/licenses/by-nc-sa/2.0/fr/>
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2016-07-01 20:16 -0400 |
| Message-ID | <nl714r$qrn$3@dont-email.me> |
| In reply to | #110890 |
On 7/1/2016 5:34 AM, Pierre-Alain Dorange wrote:
> More reduced :
> ----------------------------------
> u=raw_input('Enter calculation:")
> print eval(u)
> ----------------------------------
> works and compute :
> 1+2+3+4-1+4*2
> 2+3.0/2-0.5
>
> Perform better and shorter, but less educationnal of course...
2 lines? Love it!
But apparently eval==evil.
http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html
I bet you get hammered about it here on clp.
[toc] | [prev] | [next] | [standalone]
| From | pdorange@pas-de-pub-merci.mac.com (Pierre-Alain Dorange) |
|---|---|
| Date | 2016-07-04 11:50 +0200 |
| Message-ID | <1mpuual.1m44kff1kknqueN%pdorange@pas-de-pub-merci.mac.com> |
| In reply to | #110922 |
DFS <nospam@dfs.com> wrote: > > 2 lines? Love it! > > But apparently eval==evil. > > http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html > > I bet you get hammered about it here on clp. It was a software to be deploy, it was just for educational purpose. -- Pierre-Alain Dorange Moof <http://clarus.chez-alice.fr/> Ce message est sous licence Creative Commons "by-nc-sa-2.0" <http://creativecommons.org/licenses/by-nc-sa/2.0/fr/>
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.python
csiph-web