Re: [Tutor] Python Help with Program

2015-02-16 Thread Alan Gauld

On 16/02/15 01:26, Tina Figz wrote:

I'm having a problem with my program and I'm not sure how to correct it
(I'm in an intro programming class).

My program is supposed two numbers and count the number of carry
operations.

This is what I have:

n1 = int(raw_input('Number #1: '))
n2 = int(raw_input('Number #2: '))
add = n1 + n2

> print ' '
> print n1, '+', n2, '=', add

Down to here everything is ok and you get the sum of the two numbers



sn1 = str(n1)
sn2 = str(n2)
num1 = 1
num2 = 1
num1 == num2


This line doesn't do anything.


last_n1 = sn1[-num1]
last_n2 = sn2[-num2]
int_lastn1 = int(last_n1)
int_lastn2 = int(last_n2)
eq = int_lastn1 + int_lastn2
carry = 0


Before entering the loop you have (for your example)
sn1 = '239', sn2 = '123' num1 = 1, num2 = 1
last_n1 = '9',last_n2 = '3', int_lastn1 = 9, int_lastn2 = 3
eq = 12
carry = 0


while eq >= 10 and carry < len(sn1) and carry < len(sn2):
 num1 += 1
 num2 += 1
 carry += 1


Your loop only changes num1, num2 and carry.
But only carry is tested in the loop condition.
So in effect you just keep adding 1 to carry
until it is > then len(sn1 or len(sn2), ie 3.

You are not changing anything else, so you are effectively
just counting the number of characters in your shortest
number.


When I input 239 & 123 as my two numbers it equals 362, which is correct.
But it says I have 3 carries, when the answer should be 1 carry operation.


You need to completely redesign your algorithm.
Try writing it out using pen and paper to figure
out how you would do it manually.

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Python Help with Program

2015-02-16 Thread Mark Lawrence

On 16/02/2015 08:24, Alan Gauld wrote:

On 16/02/15 01:26, Tina Figz wrote:

I'm having a problem with my program and I'm not sure how to correct it
(I'm in an intro programming class).

My program is supposed two numbers and count the number of carry
operations.

This is what I have:

n1 = int(raw_input('Number #1: '))
n2 = int(raw_input('Number #2: '))
add = n1 + n2

 > print ' '
 > print n1, '+', n2, '=', add

Down to here everything is ok and you get the sum of the two numbers



sn1 = str(n1)
sn2 = str(n2)
num1 = 1
num2 = 1
num1 == num2


This line doesn't do anything.


last_n1 = sn1[-num1]
last_n2 = sn2[-num2]
int_lastn1 = int(last_n1)
int_lastn2 = int(last_n2)
eq = int_lastn1 + int_lastn2
carry = 0


Before entering the loop you have (for your example)
sn1 = '239', sn2 = '123' num1 = 1, num2 = 1
last_n1 = '9',last_n2 = '3', int_lastn1 = 9, int_lastn2 = 3
eq = 12
carry = 0


while eq >= 10 and carry < len(sn1) and carry < len(sn2):
 num1 += 1
 num2 += 1
 carry += 1


Your loop only changes num1, num2 and carry.
But only carry is tested in the loop condition.
So in effect you just keep adding 1 to carry
until it is > then len(sn1 or len(sn2), ie 3.

You are not changing anything else, so you are effectively
just counting the number of characters in your shortest
number.


When I input 239 & 123 as my two numbers it equals 362, which is correct.
But it says I have 3 carries, when the answer should be 1 carry
operation.


You need to completely redesign your algorithm.
Try writing it out using pen and paper to figure
out how you would do it manually.



I'd start this exercise at line 1 and work right the way through the 
code, e.g. why bother doing all the work to get sn1 and sn2?


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

Mark Lawrence

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Python Help with Program

2015-02-16 Thread Steven D'Aprano
Hi Tina, or Taylor, welcome!

Sorry but your email "From" header says your name is Tina and your 
signature says Taylor so I'm not sure which name you prefer.


On Sun, Feb 15, 2015 at 07:26:35PM -0600, Tina Figz wrote:
> I'm having a problem with my program and I'm not sure how to correct it
> (I'm in an intro programming class).
> 
> My program is supposed two numbers and count the number of carry
> operations.

Let's start by working it out using pencil and paper. Write down two 
numbers, lined up on the right:

472837
 29152


for example. Let's go through and check for carries:

Number of carries so far: 0
7 and 2 = 9, no carry.
3 and 5 = 8, no carry.
8 and 1 = 9, no carry
2 and 9 = 11, carry the 1. Add one to the number of carries.
7 and 2, plus the 1 we carried, = 10, carry the 1. So add one to number 
of carries.
4, plus the 1 we carried, = 5, no carry.

So the number of carries is two.

The process is to take the digits of each number, starting from the 
right-hand end, in pairs. If you run out of digits for one number before 
the other, use 0. Add the two digits together, plus any carry digit from 
before, and if the result is larger than 9, there's a carry.

We start with the number of carries equal to 0, and add 1 to that *only* 
if adding the pair of digits is larger than 9.

Let's see what you have:

[snip part of the code]
> eq = int_lastn1 + int_lastn2
> carry = 0
> while eq >= 10 and carry < len(sn1) and carry < len(sn2):
> num1 += 1
> num2 += 1
> carry += 1

You start on the right track: you check whether the last two digits add 
to more than 9. But, you never check the next two digits, or the two 
after that. You calculate "eq" (which is not a good name, by the way) 
once, outside the loop, but never calculate it again with any additional 
digits.

Instead, you add 1 to carry *every single time*, regardless of the 
digits (apart from the first).

Fun fact: (well, not that fun) you have to repeat the calculation each 
time through the loop, otherwise you're just using the same result over 
and over again. Example:

py> my_string = "12345"
py> position = -1
py> total = int(my_string[position]) + 1000
py> while position > -len(my_string):
... print(total)
... position = position - 1
...
1005
1005
1005
1005


The total never changes, because we never re-calculate it. Instead:

py> my_string = "12345"
py> position = -1
py> while position > -len(my_string):
... total = int(my_string[position]) + 1000
... print(total)
... position = position - 1
...
1005
1004
1003
1002


Does that help you see why your code counts the wrong number of carries, 
and help you fix it?



-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Help with program

2015-02-16 Thread Courtney Skinner
Hello,

I am trying to build a program that approximates the value of cosine - this is 
my program so far. It is not returning the right values. Could you tell me what 
I am doing wrong?


def main():

import math

print("This program approximates the cosine of x by summing")
print("the terms of this series:  x^0 / 0!, -x^2 / 2!,")
print("x^4 / 4!, -x^6 / 6!...")

n = eval(input("How many terms should be used? ")) 
x = eval(input("What value should be used for x? "))

s = 1
d = 1
e = 1

value = 0

for i in range(n - 1):
value = value + s + (x**e / math.factorial(d))

s = s * 1
e = e + 2
d + d + 2



print("Approximation for cos(x) calculated by this program: ")
print(value)
print()

difference = math.cos(x) - value

print("Difference between this value and math.cos(x): ")
print(difference)

main()

Thank you!

C.Skinner

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help with program

2015-02-16 Thread Mark Lawrence

On 16/02/2015 16:27, Courtney Skinner wrote:

Hello,

I am trying to build a program that approximates the value of cosine - this is 
my program so far. It is not returning the right values. Could you tell me what 
I am doing wrong?


def main():

 import math


Not that it matters but imports are usually done at the top of the module.



 print("This program approximates the cosine of x by summing")
 print("the terms of this series:  x^0 / 0!, -x^2 / 2!,")
 print("x^4 / 4!, -x^6 / 6!...")

 n = eval(input("How many terms should be used? "))
 x = eval(input("What value should be used for x? "))


*DON'T* use eval, it's potentially dangerous.

n = int(input("How many terms should be used? "))
x = float(input("What value should be used for x? "))



 s = 1
 d = 1
 e = 1

 value = 0

 for i in range(n - 1):


Are you aware that this will count from zero to n - 2?


 value = value + s + (x**e / math.factorial(d))

 s = s * 1
 e = e + 2
 d + d + 2


Whoops :)


 print("Approximation for cos(x) calculated by this program: ")
 print(value)
 print()

 difference = math.cos(x) - value

 print("Difference between this value and math.cos(x): ")
 print(difference)

main()


We'd usually write:-

if __name__ == "__main__":
main()



Thank you!

C.Skinner


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

Mark Lawrence

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help with program

2015-02-16 Thread Alan Gauld

On 16/02/15 16:27, Courtney Skinner wrote:

Hello,

I am trying to build a program that approximates the value of cosine




def main():

 import math


Its usual to do the imports outside the function at the tyop of the 
file. Python doesn't actually care much but its 'standard practice'.



 print("This program approximates the cosine of x by summing")
 print("the terms of this series:  x^0 / 0!, -x^2 / 2!,")
 print("x^4 / 4!, -x^6 / 6!...")

 n = eval(input("How many terms should be used? "))
 x = eval(input("What value should be used for x? "))


Don't use eval(). Use int() for the first one and float()
for the second. eval() is a security hazard and potentially
dangerous.


 s = 1
 d = 1
 e = 1
 value = 0

 for i in range(n - 1):
 value = value + s + (x**e / math.factorial(d))


Your description says you subtract every second value (eg -x**2/2!)
You are adding them all. Also you are adding 1(s) every time, surely
you just want to add it the first time. In other words you
want value to start at 1 and the loop to iterate from 2-(n-1)?
You also want a sign multiplier which toggles between +/-1
Also you can get Python to do most the work for you by specifying
a third step-size argument to range:

...
for e in range(2, (n*2)+1, 2): #step by 2
   value += (x**e)/math.factorial(e) * sign
   ...

You no longer need any of the other increments or variables.


 s = s * 1
 e = e + 2
 d + d + 2



 print("Approximation for cos(x) calculated by this program: ")
 print(value)
 print()


You probably want all of these outside the loop.
You might like to add a print(value) though while you are debugging.



 difference = math.cos(x) - value

 print("Difference between this value and math.cos(x): ")
 print(difference)



HTH
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Help with program

2015-02-16 Thread Peter Otten
Courtney Skinner wrote:

> Hello,
> 
> I am trying to build a program that approximates the value of cosine -
> this is my program so far. It is not returning the right values. Could you
> tell me what I am doing wrong?
> 
> 
> def main():
> 
> import math
> 
> print("This program approximates the cosine of x by summing")
> print("the terms of this series:  x^0 / 0!, -x^2 / 2!,")
> print("x^4 / 4!, -x^6 / 6!...")
> 
> n = eval(input("How many terms should be used? "))
> x = eval(input("What value should be used for x? "))

Consider the more restrictive int() and float() instead of eval().
 
> s = 1

A nice suggestive name like "sign" instead of "s" might help you with your 
debugging efforts. Of course the same goes for your other names.

> d = 1
> e = 1
> 
> value = 0
> 
> for i in range(n - 1):
> value = value + s + (x**e / math.factorial(d))

With the name suggested above the error

 value = value + sign + (x**e / math.factorial(d))

should almost be obvious. sign plus? wait what...

Add
 print("current exponent", e)

to see another problem.

> 
> s = s * 1

That shows signs of a missing sign ;)

> e = e + 2
> d + d + 2
> 
> 
> 
> print("Approximation for cos(x) calculated by this program: ")
> print(value)
> print()
> 
> difference = math.cos(x) - value
> 
> print("Difference between this value and math.cos(x): ")
> print(difference)
> 
> main()
> 
> Thank you!
> 
> C.Skinner


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] What are *appropriate* uses for exec() and eval() ?

2015-02-16 Thread boB Stepp
I have heard periodically about the potential evils of using exec()
and eval(), including today,  on this list. I gather that the first
requirement for safely using these functions is that the passed
argument MUST be from a trusted source. So what would be examples
where the use of these functions IS appropriate?

-- 
boB
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Popen was deprecated since Python 2.6, now what?

2015-02-16 Thread Ken G.

Wow, just found out this morning that the following
terms of:

import os
pr = os.popen("lpr", "w")
pr.write(month), pr.write(" "),
pr.write("\t\tLine ")

was deprecated. In place there of, there is
a subprocess to use.

I have not been able to figure out on how to use a
subprocess in place of my former popen. I have been
reading the new materials on the subprocess  all day
and it is still not quite understandable.

Is there an easy tutorial of how to replace popen
with the subprocess?

I am using Python 2.7.6 on an Ubuntu 14.04.1 system.

In advance, thanking you all for your assistance.

Ken

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Popen was deprecated since Python 2.6, now what?

2015-02-16 Thread Danny Yoo
On Mon, Feb 16, 2015 at 1:26 PM, Ken G.  wrote:
> Wow, just found out this morning that the following
> terms of:
>
> import os
> pr = os.popen("lpr", "w")
> pr.write(month), pr.write(" "),
> pr.write("\t\tLine ")
>
> was deprecated. In place there of, there is
> a subprocess to use.

Hi Ken,


Yes: subprocess.Popen(), along with Popen.communicate(), are what you
want to look at.

For your example above, the change is relatively direct:

##
import subprocess
pr = subprocess.Popen(['lpr', 'w'])
pr.communicate(month + ' ' + '\t\tLine ')
##

The main difference between this and what you had earlier is that you
send all the input at once using Popen.communicate().

There's a quick-and-dirty section in the documentation for converting
from the os.popen call to the subprocess equivalents.  See:

https://docs.python.org/2/library/subprocess.html#replacing-os-popen-os-popen2-os-popen3
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] What are *appropriate* uses for exec() and eval() ?

2015-02-16 Thread Danny Yoo
On Mon, Feb 16, 2015 at 11:52 AM, boB Stepp  wrote:
> I have heard periodically about the potential evils of using exec()
> and eval(), including today,  on this list. I gather that the first
> requirement for safely using these functions is that the passed
> argument MUST be from a trusted source. So what would be examples
> where the use of these functions IS appropriate?


Given that there are language environments that do perfectly ok
without those functions, the flippant answer would be: those functions
aren't necessary.

But to be more serious: they'd probably be most useful when you're
defining your own interactive programming environment.  For example,
consider a debugger or an IDE (such as IDLE.  Or if you come from the
Java world, imagine Eclipse).  In a debugger, you're running another
program, and allowing the user to do something programmatic in the
context of that program.  Setting breakpoints, or looking at the value
of certain expressions.  In this scenario, we want to be able to
access the same runtime data structures that drive the running
program... within the program itself!  It's this introspection that
drives the need for an eval or exec.

Enormously powerful.  Enormously dangerous in the wrong hands.

That being said, almost all programs are neither debuggers nor IDEs at
their heart.  (Despite the joke that every program strives to become
Emacs at a certain point.)
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Popen was deprecated since Python 2.6, now what?

2015-02-16 Thread Alan Gauld

On 16/02/15 21:26, Ken G. wrote:

I have not been able to figure out on how to use a
subprocess in place of my former popen. I have been
reading the new materials on the subprocess  all day
and it is still not quite understandable.



Here is what the docs say:

###
17.5.5.5. Replacing os.popen(), os.popen2(), os.popen3()

(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
  stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdin, child_stdout) = (p.stdin, p.stdout)




(child_stdin,
 child_stdout,
 child_stderr) = os.popen3(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
  stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(child_stdin,
 child_stdout,
 child_stderr) = (p.stdin, p.stdout, p.stderr)




(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
  stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)





Return code handling translates as follows:

pipe = os.popen(cmd, 'w')
...
rc = pipe.close()
if rc is not None and rc >> 8:
print("There were some errors")
==>
process = Popen(cmd, 'w', stdin=PIPE)
...
process.stdin.close()
if process.wait() != 0:
print("There were some errors")



17.5.5.6. Replacing functions from the popen2 module

Note
If the cmd argument to popen2 functions is a string, the command is 
executed through /bin/sh. If it is a list, the command is directly executed.




(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
==>
p = Popen("somestring", shell=True, bufsize=bufsize,
  stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)



(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, 
mode)

==>
p = Popen(["mycmd", "myarg"], bufsize=bufsize,
  stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)


popen2.Popen3 and popen2.Popen4 basically work as subprocess.Popen, 
except that:

Popen raises an exception if the execution fails.
the capturestderr argument is replaced with the stderr argument.
stdin=PIPE and stdout=PIPE must be specified.
popen2 closes all file descriptors by default,
but you have to specify close_fds=True with Popen
to guarantee this behavior on all platforms or past Python versions.
#

Which bits of that don't you understand?
That way we have something concrete to work with.

For example, Your popen program:

import os
pr = os.popen("lpr", "w")
pr.write(month), pr.write(" "),
pr.write("\t\tLine ")

Translates according to the above as

import subprocess as sub
pr = sub.Popen(["lpr"], stdin = sub.PIPE)
pr.stdin.write(month)
pr.stdin.write(" ")
pr.stdin.close()
if pr.wait() != 0: print 'Errors!'

Now, how can we help further clarify things?

--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Popen was deprecated since Python 2.6, now what?

2015-02-16 Thread Ken G.


On 02/16/2015 05:11 PM, Danny Yoo wrote:

On Mon, Feb 16, 2015 at 1:26 PM, Ken G.  wrote:

Wow, just found out this morning that the following
terms of:

import os
pr = os.popen("lpr", "w")
pr.write(month), pr.write(" "),
pr.write("\t\tLine ")

was deprecated. In place there of, there is
a subprocess to use.

Hi Ken,


Yes: subprocess.Popen(), along with Popen.communicate(), are what you
want to look at.

For your example above, the change is relatively direct:

##
import subprocess
pr = subprocess.Popen(['lpr', 'w'])
pr.communicate(month + ' ' + '\t\tLine ')
##

The main difference between this and what you had earlier is that you
send all the input at once using Popen.communicate().

There's a quick-and-dirty section in the documentation for converting
from the os.popen call to the subprocess equivalents.  See:

https://docs.python.org/2/library/subprocess.html#replacing-os-popen-os-popen2-os-popen3
.
Thank you for helping me get on the road here. I printed out your 
response and I'll be playing with it.


Ken

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Popen was deprecated since Python 2.6, now what?

2015-02-16 Thread Ken G.


On 02/16/2015 06:26 PM, Alan Gauld wrote:

On 16/02/15 21:26, Ken G. wrote:

I have not been able to figure out on how to use a
subprocess in place of my former popen. I have been
reading the new materials on the subprocess  all day
and it is still not quite understandable.



Here is what the docs say:

###
17.5.5.5. Replacing os.popen(), os.popen2(), os.popen3()

(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
  stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdin, child_stdout) = (p.stdin, p.stdout)




(child_stdin,
 child_stdout,
 child_stderr) = os.popen3(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
  stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(child_stdin,
 child_stdout,
 child_stderr) = (p.stdin, p.stdout, p.stderr)




(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
  stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)





Return code handling translates as follows:

pipe = os.popen(cmd, 'w')
...
rc = pipe.close()
if rc is not None and rc >> 8:
print("There were some errors")
==>
process = Popen(cmd, 'w', stdin=PIPE)
...
process.stdin.close()
if process.wait() != 0:
print("There were some errors")



17.5.5.6. Replacing functions from the popen2 module

Note
If the cmd argument to popen2 functions is a string, the command is 
executed through /bin/sh. If it is a list, the command is directly 
executed.




(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
==>
p = Popen("somestring", shell=True, bufsize=bufsize,
  stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)



(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], 
bufsize, mode)

==>
p = Popen(["mycmd", "myarg"], bufsize=bufsize,
  stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)


popen2.Popen3 and popen2.Popen4 basically work as subprocess.Popen, 
except that:

Popen raises an exception if the execution fails.
the capturestderr argument is replaced with the stderr argument.
stdin=PIPE and stdout=PIPE must be specified.
popen2 closes all file descriptors by default,
but you have to specify close_fds=True with Popen
to guarantee this behavior on all platforms or past Python versions.
#

Which bits of that don't you understand?
That way we have something concrete to work with.

For example, Your popen program:

import os
pr = os.popen("lpr", "w")
pr.write(month), pr.write(" "),
pr.write("\t\tLine ")

Translates according to the above as

import subprocess as sub
pr = sub.Popen(["lpr"], stdin = sub.PIPE)
pr.stdin.write(month)
pr.stdin.write(" ")
pr.stdin.close()
if pr.wait() != 0: print 'Errors!'

Now, how can we help further clarify things?

Thank for the translation of the hard-to-read docs. Reading the docs 
threw me for a loop. I printed out your response and will be studying to 
try best understand it.


Ken

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Popen was deprecated since Python 2.6, now what?

2015-02-16 Thread Danny Yoo
> Thank for the translation of the hard-to-read docs. Reading the docs threw
> me for a loop. I printed out your response and will be studying to try best
> understand it.


No problem; feel free to ask questions on anything that doesn't make
sense, and we'll try to help as best as we can.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] What are *appropriate* uses for exec() and eval() ?

2015-02-16 Thread Steven D'Aprano
On Mon, Feb 16, 2015 at 01:52:16PM -0600, boB Stepp wrote:
> I have heard periodically about the potential evils of using exec()
> and eval(), including today,  on this list. I gather that the first
> requirement for safely using these functions is that the passed
> argument MUST be from a trusted source. So what would be examples
> where the use of these functions IS appropriate?

The flippant reply would be "there aren't any".

But that is not true.

In the broader context of programming in general, not just Python, the 
use of eval/exec is incredibly powerful because it allows you to write 
dynamic code that uses information available at runtime to solve 
problems which cannot even be expressed at compile time.

Think about it like this:

A programming language is like a toolbox filled with tools for solving 
problems. You combine those tools like Lego blocks, combining them in 
different ways to make new tools. One of those Lego blocks is a robot, 
called eval or exec, which you can instruct to make new tools, instead 
of making them yourself.

There are various downsides: the extra complexity of telling the robot 
which Lego blocks to use, instead of just directly using the blocks 
yourself, means that using the robot is slower, more complex, harder to 
read, error messages are less useful, and if your instructions contain 
data coming from strangers, they may be able to subvert your intention, 
sneak instructions into your code, and take control of the robot. But it 
means you can put off the decision for which Lego block to use until 
runtime when more information is available.

exec is literally a Python interpreter embedded inside Python, so if you 
have a particularly hard problem to solve, one of the ways you can solve 
it is to write a program to *write a program to solve it*, then use exec 
to run that second program.

All this discussion has been very abstract. Here are some concrete 
examples of good use of eval/exec.

In the standard library, we have the timeit module which takes a code 
snippet from the user, executes it as Python code, and measures how long 
it takes. There's no way to take *code* from the user except as a 
string, if you type it directly Python will interpret it immediately. To 
delay execution, you have to put the code inside a string, and then 
later interpret the string as Python code. In other words, exec.

Likewise, we have the doctest module. Inside your function docstrings, 
you can write samples of interactive output:

def spam(n):
"""Return n lots of spam.

>>> spam(3)
'spam spam spam'

"""
...


The doctest module scans the docstring, extracts anything which looks 
like interactive output (starting with >>> prompt), execs that text as 
Python code, and checks that the output matches what you gave it. Your 
sample code is *executable documentation*, so long as you remember to 
run dotest over it, you can always be sure that the sample code is 
correct.

In the collections module, there is a factory function called namedtuple 
for creating record-like tuples with named fields. How it works is you 
provide the name of the fields, they get plugged into a class definition 
template, and the template executed as Python code, which creates a new 
class. That class is returned for you to use:

py> from collections import namedtuple
py> Record = namedtuple("Record", "x y z")
py> point = Record(23, 42, 19)
py> print(point)
Record(x=23, y=42, z=19)
py> point.x
23


Here is the original version which eventually became part of the 
collections module:

http://code.activestate.com/recipes/500261-named-tuples/

Here is a fork of that recipe. It uses an inner class for the new 
namedtuple class. The only thing which needs exec is the __new__ method.

http://code.activestate.com/recipes/578918-yet-another-namedtuple/

This demonstrates a powerful truth about Python: *most of the time* you 
don't need to use exec or eval because the standard language features 
are powerful enough to solve the problem for you. Using a dynamically 
created inner class is *almost* enough to solve this problem, only the 
__new__ method defeats it. If our requirements where just a little less 
demanding, we could avoid exec completely.

In some languages, if you want to define functions are runtime, the only 
way to do it is to write a function template, fill in the blanks at 
runtime, then exec it:


template = """
def add(x):
return x + %s
"""
namespace = {}
exec(template % 10, namespace)
addTen = namespace['add']
print(addTen(23))


With Python, going to all that trouble is unnecessary:


def factory(n):
"""Return a new function which adds n to its argument."""
def add(x):
return x + n
return add

addTen = factory(10)
print(addTen(23))


The result is easier to read, faster, and more secure.


-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.or

Re: [Tutor] Help with program

2015-02-16 Thread Dave Angel

On 02/16/2015 11:27 AM, Courtney Skinner wrote:

Hello,

I am trying to build a program that approximates the value of cosine - this is 
my program so far. It is not returning the right values. Could you tell me what 
I am doing wrong?




You've got several answers that point out several problems in your code. 
 But I think you're missing a key concept.


If you're faced with a problem that's beyond your present abilities, or 
that's got you stumped, always consider factoring the problem into 
simpler ones.


To me the first thing you should factor out is a factorial function. 
Write one, that takes a positive int and returns the factorial, and test 
it against the one in the math library.


Once it's correct, then use it in the cosine problem.  Now you've got a 
simpler loop to write.  And you know part of the code works.


Next, see if you can avoid most of those three variables you're using. 
For example, What do you get when you calculate

   (-1) ** (i)

Can you use that to simplify things?


--
DaveA
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] What are *appropriate* uses for exec() and eval() ?

2015-02-16 Thread Devin Jeanpierre
On Mon, Feb 16, 2015 at 6:15 PM, Steven D'Aprano  wrote:
> Here is a fork of that recipe. It uses an inner class for the new
> namedtuple class. The only thing which needs exec is the __new__ method.
>
> http://code.activestate.com/recipes/578918-yet-another-namedtuple/
>
> This demonstrates a powerful truth about Python: *most of the time* you
> don't need to use exec or eval because the standard language features
> are powerful enough to solve the problem for you. Using a dynamically
> created inner class is *almost* enough to solve this problem, only the
> __new__ method defeats it. If our requirements where just a little less
> demanding, we could avoid exec completely.

No, exec is not necessary at all. If they had to the author could have
reimplemented the argument assignment logic by hand. They chose not to
because it is "too hard". (And it is.)  Fortunately, they don't have
to go that far:

signature = inspect.Signature([
inspect.Parameter(field_name, inspect.Parameter.POSITIONAL_OR_KEYWORD)
for field_name in field_names])

def __new__(cls, *args, **kwargs):
   return tuple.__new__(cls, signature.bind(*args, **kwargs).arguments.values())

-- Devin
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] What are *appropriate* uses for exec() and eval() ?

2015-02-16 Thread Cameron Simpson

On 16Feb2015 19:10, Devin Jeanpierre  wrote:

On Mon, Feb 16, 2015 at 6:15 PM, Steven D'Aprano  wrote:

Here is a fork of that recipe. It uses an inner class for the new
namedtuple class. The only thing which needs exec is the __new__ method.

http://code.activestate.com/recipes/578918-yet-another-namedtuple/

This demonstrates a powerful truth about Python: *most of the time* you
don't need to use exec or eval because the standard language features
are powerful enough to solve the problem for you. Using a dynamically
created inner class is *almost* enough to solve this problem, only the
__new__ method defeats it. If our requirements where just a little less
demanding, we could avoid exec completely.


No, exec is not necessary at all. If they had to the author could have
reimplemented the argument assignment logic by hand. [... example...]


I see your counter counter example and raise you another counter.

One might use exec() to use code that is valid in one python version but not 
another, when you need your program to run in both i.e. to get code that is 
syntacticly invalid in one version, but to use it (conditionally) in another 
version.


I only have one use case for this presently: I have a use of exec() in my 
cs.py3 python2/3 compatability module:


 def raise3(exc_type, exc_value, exc_traceback):
   if sys.hexversion >= 0x0300:
 raise exc_type(exc_value).with_traceback(exc_traceback)
   else:
 # subterfuge to let this pass a python3 parser; ugly
 exec('raise exc_type, exc_value, exc_traceback')

I'm using exec() here because a Python 3 interpreter will reject the 3 argument 
form of raise. Elsewhere in my code I just call cs.py3.raise3() with the 
requisite arguments. Note that the string passed to exec() is hardwired, not 
obtained from elsewhere in any form.


Like all sane people, I consider using exec() a code smell: if you're using it 
you should consider heavily alternatives to it.


Cheers,
Cameron Simpson 

I think... Therefore I ride.  I ride... Therefore I am.
   - Mark Pope 
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] What are *appropriate* uses for exec() and eval() ?

2015-02-16 Thread Devin Jeanpierre
On Mon, Feb 16, 2015 at 7:20 PM, Cameron Simpson  wrote:
> One might use exec() to use code that is valid in one python version but not
> another, when you need your program to run in both i.e. to get code that is
> syntacticly invalid in one version, but to use it (conditionally) in another
> version.
>
> I only have one use case for this presently: I have a use of exec() in my
> cs.py3 python2/3 compatability module:
>
>  def raise3(exc_type, exc_value, exc_traceback):
>if sys.hexversion >= 0x0300:
>  raise exc_type(exc_value).with_traceback(exc_traceback)
>else:
>  # subterfuge to let this pass a python3 parser; ugly
>  exec('raise exc_type, exc_value, exc_traceback')
>
> I'm using exec() here because a Python 3 interpreter will reject the 3
> argument form of raise. Elsewhere in my code I just call cs.py3.raise3()
> with the requisite arguments. Note that the string passed to exec() is
> hardwired, not obtained from elsewhere in any form.

I'd try conditional imports, first:

if sys.hexversion >= ...:
from .compat_py3 import raise3
else:
from .compat_py2 import raise3

But maybe this breaks with the setuptools pre-compilation shenanigans?

At any rate, I didn't mean to make a general statement. Obviously,
sometimes exec/eval is necessary. If for no other reason than because
sometimes the requirement is to use exec (e.g. if you are implementing
something equivalent to python -i, etc.).

-- Devin
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor