Re: Best way to go about embedding python

2016-11-13 Thread Ben Finney
[email protected] writes:

> A friend of mine is developing a game engine, and I would like to
>  extend the engine by adding some scripting functionality.

I haven't done it myself. But the Python Wiki has some pages that will
help you, I think:

* https://wiki.python.org/moin/AppsWithPythonScripting>
* https://wiki.python.org/moin/IntegratingPythonWithOtherLanguages>

-- 
 \   “The internet's completely over.… Anyway, all these computers |
  `\and digital gadgets are no good. They just fill your head with |
_o__) numbers and that can't be good for you.” —Prince, 2010-07-05 |
Ben Finney

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Best way to go about embedding python

2016-11-13 Thread Chris Angelico
On Sun, Nov 13, 2016 at 6:10 PM,   wrote:
>
> (Sorry about the last post, my finger slipped before I was finished, and I 
> can't delete it for some reason.)

(That's because this is a mailing list and newsgroup gatewayed to each
other. Once sent, a message cannot be edited or deleted.)

> A friend of mine is developing a game engine, and I would like to extend the 
> engine by adding some scripting functionality.  However, there's a lot of 
> information out there, and I have a lot of questions before I get started.
>

The very first question to ask is: Are you intending to let untrusted
or less trusted people write the scripts? If so, *do not* use Python.
Embedding Python can be done to make your work easier, but it isn't
sandboxed.

> 1.  What's the best implementation to use?
> - The engine itself is written in pure C, and the compiler being used 
> is clang.  Eventually, we'd like it to target multiple platforms.
>

Sounds like the standard CPython interpreter will suit you just fine.

> 2.  How would I go about including python scripts to run with the engine.  
> Would the .py files from the standard libraries be necessary, or is anything 
> built in?
>

You'll probably want to link against libpython, which (AIUI) will
connect you to an installed Python, complete with the standard
library. Python without its stdlib is a disappointingly featureless
language :)

> 3.  How could I go about adding a repl to the engine application?  
> Preferably, I'd be able to connect to it with sublimerepl.
>

Hmm, that depends a bit on the way your app works. Most likely, a
classic REPL won't work, as the console won't be directly available.
You'll probably end up with an internal console of some sort. You
should be able to either build your own REPL on top of that, or tie in
with something from Idle's code.

> 4.  Would it be possible to attach any python debuggers to the application 
> and step through python code?
>

Again, this depends on how your app is architected, but it should be possible.

Embedding Python isn't too hard. The best place to start is here:

https://docs.python.org/3/extending/index.html

You'll find it's easy enough to get a simple "Hello, world" going, and
after that, it's a matter of figuring out what you need.

Have fun with it!

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: how to print variable few time?

2016-11-13 Thread andy
Sat, 12 Nov 2016 04:58:20 -0800 wrote guy asor:

> hello!
> 
> this is my code:
> 
> word=raw_input()
> print word*3
> 
> 
> with this code im getting - wordwordword.
> what changes i need to make to get - word word word - instead?
> 
> thanks

using python3.x:

word=input()
print((word+' ')*2, end='')
print(word)

 ..but D'Apranos ' '.join(..) is far more elegant.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: how to print variable few time?

2016-11-13 Thread andy
Sun, 13 Nov 2016 15:12:01 +0100 wrote andy:

> word=input()
> print((word+' ')*2, end='')
> print(word)
> 
>  ..but D'Apranos ' '.join(..) is far more elegant.

don't know whether I really would use this form, but it works in python3:

word = ' '.join([input()]*3)
print(word)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: how to print variable few time?

2016-11-13 Thread Jussi Piitulainen
andy writes:

> Sat, 12 Nov 2016 04:58:20 -0800 wrote guy asor:
>
>> hello!
>> 
>> this is my code:
>> 
>> word=raw_input()
>> print word*3
>> 
>> 
>> with this code im getting - wordwordword.
>> what changes i need to make to get - word word word - instead?
>> 
>> thanks
>
> using python3.x:
>
> word=input()
> print((word+' ')*2, end='')
> print(word)

print(*[word]*3)
-- 
https://mail.python.org/mailman/listinfo/python-list


if iter(iterator) is iterator

2016-11-13 Thread Antoon Pardon

Some time ago I read a text or saw a video on iterators and one thing
I remember from it, is that you should do something like the following
when working with iterators, to avoid some pitt falls.

def bar(iterator):
if iter(iterator) is iterator:
...

However I can't relocate it and can't remember the what and how anymore.
Does anyone know what this is about?

-- 
Antoon.
-- 
https://mail.python.org/mailman/listinfo/python-list


Halp in if

2016-11-13 Thread menta231
Hii there
I am preety New at python,  and i need your help. I want to make a script that 
if somthing happens, it stop, and if it doesnt, it couninues. I dont finding a 
smart way. Here is what i wrote. I want to do it without exits and sleeps. 


import time
print ("hello there ")
x = raw_input ("what is you name ? ")
print ("hello ") + x + (" lets play a game ")
y = raw_input ("chooe a number ")
iny = raw_input ("what is the power of this number ?")
z = int(y) * int(y)
if int(iny) == int(y) * int(y) :
 print ("I see you are smart ")
else: 
 print ("Such An Idiot! answer is ") + str(z)
 time.sleep(3)
 exit()
if int(iny) == int(y) * int(y) :
 print ("think touy are so smart")
lll=raw_input("do you want to cotinue?")
if lll== str("yes"):
 print ("good")
else:
 print ("bye bye")
 time.sleep(2)
 exit()
lmm=raw_input("what is the thirs power of the same number")
if lmm == str(int(y)* int(y)*int(y)):
 print ("you are a pro")
else :
 print ("I'm dissapointed... answear is ") + str(int(y) * int(y)*int(y))
 time.sleep (5)
 exit()
time.sleep(121)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: if iter(iterator) is iterator

2016-11-13 Thread Chris Angelico
On Mon, Nov 14, 2016 at 7:02 AM, Antoon Pardon
 wrote:
> Some time ago I read a text or saw a video on iterators and one thing
> I remember from it, is that you should do something like the following
> when working with iterators, to avoid some pitt falls.
>
> def bar(iterator):
> if iter(iterator) is iterator:
> ...
>
> However I can't relocate it and can't remember the what and how anymore.
> Does anyone know what this is about?

That's how you distinguish an iterator from other iterables. An
iterable is something you can call iter() on; an iterator is required
to specifically return _itself_.

What you do with that information, though, depends on the function. In
a lot of cases, you shouldn't care - if you need an iterator, just
"iterator = iter(iterator)" at the top and move on.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: if iter(iterator) is iterator

2016-11-13 Thread Gregory Ewing

Antoon Pardon wrote:


def bar(iterator):
if iter(iterator) is iterator:
...


That's a way of finding out whether you can safely iterate
over something more than once. If the object is already an
iterator, applying iter() to it will return the same
object, and iterating over it will consume it.

You would only care if you're intending to iterate over
it more than once, and you're not sure what kind of object
you have.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: Halp in if

2016-11-13 Thread Erik

Hi,

On 13/11/16 20:09, [email protected] wrote:

HI want to make a script that if somthing happens, it stop, and if it doesnt, 
it couninues. I dont finding a smart way.


Read the documentation for the "while", "break" and "continue" keywords.

Regards, E.

--
https://mail.python.org/mailman/listinfo/python-list


Re: if iter(iterator) is iterator

2016-11-13 Thread Chris Angelico
On Mon, Nov 14, 2016 at 8:57 AM, Gregory Ewing
 wrote:
> Antoon Pardon wrote:
>
>> def bar(iterator):
>> if iter(iterator) is iterator:
>> ...
>
>
> That's a way of finding out whether you can safely iterate
> over something more than once. If the object is already an
> iterator, applying iter() to it will return the same
> object, and iterating over it will consume it.

Not strictly true. There's no guarantee that something that yields new
iterators is actually reiterable. And even if it is, there's no
guarantee that it'll yield the same values.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Making stl files with python for 3d printing

2016-11-13 Thread Poul Riis
Below you can find my python code to make a vase for 3D-printing.
The vase looks nice on my screen so the vertices and the faces seem to be 
perfect.
However, when sending the .stl file produced to a 3D-printer the vase comes out 
as a filled solid - no room for water and flowers!
I have tried to slice the vase the the program "Cura". It seems that the slices 
are full disks, not rings as intended, at some values of z but far from all.
I don't expect anybody to read the full program (I'm a very poor programmer) 
but my hope is that someone can give a hint as to how I can improve the writing 
of the .stl file.

Poul Riis

#!/usr/bin/env python
#coding:utf-8
# Purpose: Export 3D objects, build of faces with 3 or 4 vertices, as ASCII or 
Binary STL file.
# License: MIT License

import struct
from tvtk.api import tvtk
from mayavi import mlab
from math import *
from sympy import *



ASCII_FACET = """facet normal 0 0 0
outer loop
vertex {face[0][0]:.4f} {face[0][1]:.4f} {face[0][2]:.4f}
vertex {face[1][0]:.4f} {face[1][1]:.4f} {face[1][2]:.4f}
vertex {face[2][0]:.4f} {face[2][1]:.4f} {face[2][2]:.4f}
endloop
endfacet
"""

BINARY_HEADER ="80sI"
BINARY_FACET = "12fH"

class ASCII_STL_Writer:
""" Export 3D objects build of 3 or 4 vertices as ASCII STL file.
"""
def __init__(self, stream):
self.fp = stream
self._write_header()

def _write_header(self):
self.fp.write("solid python\n")

def close(self):
self.fp.write("endsolid python\n")

def _write(self, face):
self.fp.write(ASCII_FACET.format(face=face))

def _split(self, face):
p1, p2, p3, p4 = face
return (p1, p2, p3), (p3, p4, p1)

def add_face(self, face):
""" Add one face with 3 or 4 vertices. """
if len(face) == 4:
face1, face2 = self._split(face)
self._write(face1)
self._write(face2)
elif len(face) == 3:
self._write(face)
else:
raise ValueError('only 3 or 4 vertices for each face')

def add_faces(self, faces):
""" Add many faces. """
for face in faces:
self.add_face(face)

class Binary_STL_Writer(ASCII_STL_Writer):
""" Export 3D objects build of 3 or 4 vertices as binary STL file.
"""
def __init__(self, stream):
self.counter = 0
super(Binary_STL_Writer, self).__init__(stream)

def close(self):
self._write_header()

def _write_header(self):
self.fp.seek(0)
self.fp.write(struct.pack(BINARY_HEADER, b'Python Binary STL Writer', 
self.counter))

def _write(self, face):
self.counter += 1
data = [
0., 0., 0.,
face[0][0], face[0][1], face[0][2],
face[1][0], face[1][1], face[1][2],
face[2][0], face[2][1], face[2][2],
0
]
self.fp.write(struct.pack(BINARY_FACET, *data))


def example(fn):
def get_cube():
p=[]
nxy=24
nz=21#Must be odd
unit=10
h=2*unit
dh=h/nz
zbottom=-2*dh
thickness=0.3*unit

z=Symbol('z')
f=1*(1+sin((z/h)**2*1*pi)/8)*exp(z/h/2)*unit#1*
#f=(1+z/h)*unit
flambdified = lambdify(z, f)
fdiff=f.diff(z)
fdifflambdified = lambdify(z, fdiff)

rinner0=10
rinner=rinner0
router0=rinner0+thickness
router=router0
deltar=1
deltaphi=2*pi/nxy
deltaphih=deltaphi/2
nxyz=nxy*nz
npts=0

#Inner:
for j in range(0,nz+1):
zact=j*dh
ract=flambdified(zact)
phiact=j%2*(-deltaphih)
for i in range(0,nxy):
p.append((ract*cos(phiact),ract*sin(phiact),zact))
phiact=phiact+deltaphi
npts=npts+1
npts1=npts


#Middle of upper rim:
phiact=0
ract=flambdified(zact)
a=fdifflambdified(zact)
b=sqrt(1+a*a)
k=thickness/b/2
for i in range(0,nxy):
cosphi=cos(phiact)
sinphi=sin(phiact)
dx=k*cosphi
dy=k*sinphi
dz=-k*a
p.append((ract*cosphi+dx,ract*sinphi+dy,zact+dz))
phiact=phiact+deltaphi
npts1=npts1+1

#Outer:
for j in range(-1,nz+2):
zact=(nz-j-1)*dh
ract=flambdified(zact)
a=fdifflambdified(zact)
b=sqrt(1+a*a)
k=thickness/b
phiact=(j-0)%2*(-deltaphih)
for i in range(0,nxy):
cosphi=cos(phiact)
sinphi=sin(phiact)
dx=k*cosphi
dy=k*sinphi
dz=-k*a
p.append((ract*cosphi+dx,ract*sinphi+dy,zact+dz))
phiact=phiact+deltaphi
npts1=npts1+1

   
#Center of bottom:
p.append((0,0,-thickness)

Re: if iter(iterator) is iterator

2016-11-13 Thread Steve D'Aprano
On Mon, 14 Nov 2016 07:02 am, Antoon Pardon wrote:

> 
> Some time ago I read a text or saw a video on iterators and one thing
> I remember from it, is that you should do something like the following
> when working with iterators, to avoid some pitt falls.
> 
> def bar(iterator):
> if iter(iterator) is iterator:
> ...
> 
> However I can't relocate it and can't remember the what and how anymore.
> Does anyone know what this is about?

Probably something like this:


def function(iterable):
if iter(iterable) is iterable:
print("iterable is already an iterator")
assert hasattr(iterable, '__next__')  # 'next' in Python 2
else:
print("iterable is not an iterator")
print("it may be a list, dict, string, etc.")


`iter(thing) is thing` is an easy way to check whether thing is an iterator.

I'm surprised that the inspect module doesn't appear to have isiterable and
isiterator functions. Here's my first attempt at both:


def isiterable(obj):
"""Return True if obj is an iterable, and False otherwise.

Iterable objects can be iterated over, and they provide either
an __iter__ method or a __getitem__ method.

Iteration over an object tries calling the object's __iter__ 
method (if any), then repeatedly calls __next__ on the result
until a StopIteration exception is raised (the Iterator
Protocol). Otherwise, it tries calling __getitem__ with 
arguments 0, 1, 2, 3 ... until an IndexError exception is
raised (the Sequence Protocol).

"""
T = type(obj)
return hasattr(T, '__iter__') or hasattr(T, '__getitem__')


def isiterator(obj):
"""Return True if obj is an iterator, and False otherwise.

Iterators can be iterated over, and they provide the following
methods:

- __iter__ which returns itself
- __next__

Iteration over an iterator repeatedly calls __next__ until a
StopIteration exception is raised.
"""
T = type(obj)
if hasattr(T, '__iter__') and hasattr(T, '__next__'):
return iter(obj) is obj
return False






-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Best way to go about embedding python

2016-11-13 Thread Steve D'Aprano
On Mon, 14 Nov 2016 12:23 am, Chris Angelico wrote:

> Python without its stdlib is a disappointingly featureless
> language :)


I don't think that's true. You can do a lot in Python without any imports in
your code:

- basic string processing
- BigNum (int) and float arithmetic
- lists and tuples
- dicts
- lazy processing of iterators
- custom functions and classes
- functional style zip, map and filter

and more.

Some parts of the standard library are required for built-in functions, e.g.
the io module is needed to open files. But I think you could probably
reduce the standard library by, oh, 90% and still have a decent language
for game scripting.


-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: if iter(iterator) is iterator

2016-11-13 Thread Chris Angelico
On Mon, Nov 14, 2016 at 11:40 AM, Steve D'Aprano
 wrote:
> def isiterable(obj):
> """Return True if obj is an iterable, and False otherwise.
>
> Iterable objects can be iterated over, and they provide either
> an __iter__ method or a __getitem__ method.
>
> Iteration over an object tries calling the object's __iter__
> method (if any), then repeatedly calls __next__ on the result
> until a StopIteration exception is raised (the Iterator
> Protocol). Otherwise, it tries calling __getitem__ with
> arguments 0, 1, 2, 3 ... until an IndexError exception is
> raised (the Sequence Protocol).
>
> """
> T = type(obj)
> return hasattr(T, '__iter__') or hasattr(T, '__getitem__')

Any particular reason to write it that way, rather than:

def isiterable(obj):
try:
iter(obj)
return True
except TypeError:
return False

?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Best way to go about embedding python

2016-11-13 Thread Chris Angelico
On Mon, Nov 14, 2016 at 11:40 AM, Steve D'Aprano
 wrote:
> On Mon, 14 Nov 2016 12:23 am, Chris Angelico wrote:
>
>> Python without its stdlib is a disappointingly featureless
>> language :)
>
>
> I don't think that's true. You can do a lot in Python without any imports in
> your code:
>
> - basic string processing
> - BigNum (int) and float arithmetic
> - lists and tuples
> - dicts
> - lazy processing of iterators
> - custom functions and classes
> - functional style zip, map and filter
>
> and more.
>
> Some parts of the standard library are required for built-in functions, e.g.
> the io module is needed to open files. But I think you could probably
> reduce the standard library by, oh, 90% and still have a decent language
> for game scripting.

Perhaps what would be more accurate is that Python without its stdlib
is as featureless as (say) Lua, but still without being safe to embed.
Yes, it's technically usable, but you really don't have a lot. And
remember, some of the stdlib is what we call builtins; if you embed
Python and engage "restricted mode", it's by emptying out the
builtins. You're pretty much down to three things:

1) Stuff that you could pass to ast.literal_eval
2) Control flow statements
3) Hacks that get you around the limitations, thus proving that
Python-without-stdlib is really really hard to actually test anything
with.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Best way to go about embedding python

2016-11-13 Thread Michael Torrie
On 11/13/2016 12:10 AM, [email protected] wrote:
> 2.  How would I go about including python scripts to run with the
> engine.  Would the .py files from the standard libraries be
> necessary, or is anything built in?

It's usually just a matter of asking the python instance to load and run
the script for you.  You'll need to be familiar with the libpython C
API.  This document is a good starting point:
https://docs.python.org/3/extending/extending.html

One of the interesting things about libpython and the API is that
there's really little difference between extending Python with C and
embedding Python in C.  The principles are the same.

The hardest part about integrating Python is that you have to consider
what kinds of primitives from your C program you want to expose to
Python and how you intend to expose them.  You'll have to use the C api
to wrap your native structures and functions so that they can be
interacted with from Python.  And such bindings may need to be two-way.
For example in Python code you may want to instantiate some new instance
of game object, and you'll need to make sure that the wrapper code will
create the appropriate in-game object. This aspect is probably going to
be the most time-consuming and hardest.

I'm glad to hear of someone wanting to embed Python.  Seems like so many
projects are using Javascript (yuck).  The Epiphany browser, for example
used to use Python for creating extensions but years ago they tossed it
out in favor of javascript which was a step backwards I thought.  Of
course Lua is probably the most popular embedded scripting language,
particularly with gaming engines.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Best way to go about embedding python

2016-11-13 Thread Nathan Ernst
In regards to performance of Lua vs Python, I don't have enough (near zero
experience) with Lua to comment there.

But in regards to embedding in a game, the only experience I have w/ Python
being embedded is while working on modding Civilization IV. What I saw
there just made me nauseous.

The reasoning for moving to Lua in Civilization V was performance & memory
usage - but they completely screwed up exposing the C++ internals to Python
in Civ IV. They copied object instances & containers to the Python
embedded, then marshalled them back to the C++ code when the Python code
was finished. It was horribly inefficient.

I don't have much experience hosting Python inside of a C/C++ app, but I've
10 years of experience consuming C++ APIs from Python, mostly wrapped using
Boost Python. I always did my best to minimize data marshalling. The Python
objects exposed the C++ objects' interface, directly while holding a
pointer (usually shared) to underlying C++ objects and only marshalling on
method/property calls where needed (i.e. w/ strings, dates, datetimes).
Containers were wrapped to expose a Python interface to an underlying C++
container w/ no copying.

TLDR; Civilization IV shows an antipattern about how to embed Python in a
native app and expecting anything resembling good performance. Civ IV used
Boost Python, but they did it in an extremely poor, suboptimal fashion.
Boost Python itself can be very performant, and I love the library. Boost
Python, however does suffer from a learning curve that is akin to
attempting to scale a 1000ft cliff with no rope or tools or even shoes. Due
to the heavy use of template metaprogramming in C++, compiler errors if
you're even just slightly off can be extremely hard to decipher. I've not
used it lately or on modern compilers, so I don't know if it's gotten
better, but tools like pretty_make.py (can find on github) can help filter
out the compiler spewage from the real compiler error.

PS. I don't think that Python couldn't/shouldn't be used for scripting a
game, I'm just offering up Civ IV as an example of how it can be done
horribly wrong.

Regards,
Nate

On Sun, Nov 13, 2016 at 7:03 PM, Chris Angelico  wrote:

> On Mon, Nov 14, 2016 at 11:40 AM, Steve D'Aprano
>  wrote:
> > On Mon, 14 Nov 2016 12:23 am, Chris Angelico wrote:
> >
> >> Python without its stdlib is a disappointingly featureless
> >> language :)
> >
> >
> > I don't think that's true. You can do a lot in Python without any
> imports in
> > your code:
> >
> > - basic string processing
> > - BigNum (int) and float arithmetic
> > - lists and tuples
> > - dicts
> > - lazy processing of iterators
> > - custom functions and classes
> > - functional style zip, map and filter
> >
> > and more.
> >
> > Some parts of the standard library are required for built-in functions,
> e.g.
> > the io module is needed to open files. But I think you could probably
> > reduce the standard library by, oh, 90% and still have a decent language
> > for game scripting.
>
> Perhaps what would be more accurate is that Python without its stdlib
> is as featureless as (say) Lua, but still without being safe to embed.
> Yes, it's technically usable, but you really don't have a lot. And
> remember, some of the stdlib is what we call builtins; if you embed
> Python and engage "restricted mode", it's by emptying out the
> builtins. You're pretty much down to three things:
>
> 1) Stuff that you could pass to ast.literal_eval
> 2) Control flow statements
> 3) Hacks that get you around the limitations, thus proving that
> Python-without-stdlib is really really hard to actually test anything
> with.
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


help on "from deen import *" vs. "import deen"

2016-11-13 Thread jfong
Running the following codes (deen.py) under Win32 python 3.4.4 terminal:

tbli = [0x66, 0x27, 0xD0]
tblm = [0 for x in range(3)]
def gpa(data):
td = data ^ tblm[2]
return td

I can get a correct answer this way:
>>> import deen
>>> deen.tblm = deen.tbli
>>> deen.gpa(0x7d)
173  # 0xad (= 0x7d ^ 0xd0) is decimal 173

But I get a wrong answer this way:
>>> from deen import *
>>> tblm = tbli
>>> gpa(0x7d)
125  # it's 0x7d, the tblm[2] is 0

Why? why! why:-(

--Jach

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Best way to go about embedding python

2016-11-13 Thread Kaylen Wheeler
I wonder if Lua would be a better option.  Does it suffer from the same 
sandboxing issues that python does?

On Sunday, 13 November 2016 17:38:23 UTC-8, Nathan Ernst  wrote:
> In regards to performance of Lua vs Python, I don't have enough (near zero
> experience) with Lua to comment there.
> 
> But in regards to embedding in a game, the only experience I have w/ Python
> being embedded is while working on modding Civilization IV. What I saw
> there just made me nauseous.
> 
> The reasoning for moving to Lua in Civilization V was performance & memory
> usage - but they completely screwed up exposing the C++ internals to Python
> in Civ IV. They copied object instances & containers to the Python
> embedded, then marshalled them back to the C++ code when the Python code
> was finished. It was horribly inefficient.
> 
> I don't have much experience hosting Python inside of a C/C++ app, but I've
> 10 years of experience consuming C++ APIs from Python, mostly wrapped using
> Boost Python. I always did my best to minimize data marshalling. The Python
> objects exposed the C++ objects' interface, directly while holding a
> pointer (usually shared) to underlying C++ objects and only marshalling on
> method/property calls where needed (i.e. w/ strings, dates, datetimes).
> Containers were wrapped to expose a Python interface to an underlying C++
> container w/ no copying.
> 
> TLDR; Civilization IV shows an antipattern about how to embed Python in a
> native app and expecting anything resembling good performance. Civ IV used
> Boost Python, but they did it in an extremely poor, suboptimal fashion.
> Boost Python itself can be very performant, and I love the library. Boost
> Python, however does suffer from a learning curve that is akin to
> attempting to scale a 1000ft cliff with no rope or tools or even shoes. Due
> to the heavy use of template metaprogramming in C++, compiler errors if
> you're even just slightly off can be extremely hard to decipher. I've not
> used it lately or on modern compilers, so I don't know if it's gotten
> better, but tools like pretty_make.py (can find on github) can help filter
> out the compiler spewage from the real compiler error.
> 
> PS. I don't think that Python couldn't/shouldn't be used for scripting a
> game, I'm just offering up Civ IV as an example of how it can be done
> horribly wrong.
> 
> Regards,
> Nate
> 
> On Sun, Nov 13, 2016 at 7:03 PM, Chris Angelico  wrote:
> 
> > On Mon, Nov 14, 2016 at 11:40 AM, Steve D'Aprano
> >  wrote:
> > > On Mon, 14 Nov 2016 12:23 am, Chris Angelico wrote:
> > >
> > >> Python without its stdlib is a disappointingly featureless
> > >> language :)
> > >
> > >
> > > I don't think that's true. You can do a lot in Python without any
> > imports in
> > > your code:
> > >
> > > - basic string processing
> > > - BigNum (int) and float arithmetic
> > > - lists and tuples
> > > - dicts
> > > - lazy processing of iterators
> > > - custom functions and classes
> > > - functional style zip, map and filter
> > >
> > > and more.
> > >
> > > Some parts of the standard library are required for built-in functions,
> > e.g.
> > > the io module is needed to open files. But I think you could probably
> > > reduce the standard library by, oh, 90% and still have a decent language
> > > for game scripting.
> >
> > Perhaps what would be more accurate is that Python without its stdlib
> > is as featureless as (say) Lua, but still without being safe to embed.
> > Yes, it's technically usable, but you really don't have a lot. And
> > remember, some of the stdlib is what we call builtins; if you embed
> > Python and engage "restricted mode", it's by emptying out the
> > builtins. You're pretty much down to three things:
> >
> > 1) Stuff that you could pass to ast.literal_eval
> > 2) Control flow statements
> > 3) Hacks that get you around the limitations, thus proving that
> > Python-without-stdlib is really really hard to actually test anything
> > with.
> >
> > ChrisA
> > --
> > https://mail.python.org/mailman/listinfo/python-list
> >
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: if iter(iterator) is iterator

2016-11-13 Thread Steven D'Aprano
On Monday 14 November 2016 11:59, Chris Angelico wrote:

> On Mon, Nov 14, 2016 at 11:40 AM, Steve D'Aprano
>  wrote:
>> def isiterable(obj):
>> """Return True if obj is an iterable, and False otherwise.
>>
>> Iterable objects can be iterated over, and they provide either
>> an __iter__ method or a __getitem__ method.
>>
>> Iteration over an object tries calling the object's __iter__
>> method (if any), then repeatedly calls __next__ on the result
>> until a StopIteration exception is raised (the Iterator
>> Protocol). Otherwise, it tries calling __getitem__ with
>> arguments 0, 1, 2, 3 ... until an IndexError exception is
>> raised (the Sequence Protocol).
>>
>> """
>> T = type(obj)
>> return hasattr(T, '__iter__') or hasattr(T, '__getitem__')
> 
> Any particular reason to write it that way, rather than:
> 
> def isiterable(obj):
> try:
> iter(obj)
> return True
> except TypeError:
> return False


class BadIterable:
def __iter__(self):
self.launch_missiles()
return self


In general, merely testing whether something is a certain kind of thing 
shouldn't actually run that thing's code.

(That's not always possible. E.g. the thing's metaclass might launch missiles 
when you check for the existence of an attribute. But reducing the vulnerable 
surface as much as possible is a good thing.)



-- 
Steven
299792.458 km/s — not just a good idea, it’s the law!

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Making stl files with python for 3d printing

2016-11-13 Thread Gregory Ewing

Poul Riis wrote:

However, when sending the .stl file produced to a 3D-printer the vase comes
out as a filled solid - no room for water and flowers!


My guess is that you have a problem with the orientation
of your faces. The inner surface needs to have its triangles
oriented so that their "outside" direction is towards the
centre of the vase.

If you generate the inner surface using the same code as
the outer surface and just change the radius, you will
end up with both surfaces oriented outwards, which would
produce the effect you describe.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: if iter(iterator) is iterator

2016-11-13 Thread Chris Angelico
On Mon, Nov 14, 2016 at 3:54 PM, Steven D'Aprano
 wrote:
>> Any particular reason to write it that way, rather than:
>>
>> def isiterable(obj):
>> try:
>> iter(obj)
>> return True
>> except TypeError:
>> return False
>
>
> class BadIterable:
> def __iter__(self):
> self.launch_missiles()
> return self
>
>
> In general, merely testing whether something is a certain kind of thing
> shouldn't actually run that thing's code.

True, but ISTR there being a possibility that __iter__ could raise to
indicate that this isn't actually iterable. Maybe I'm recalling wrong.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Best way to go about embedding python

2016-11-13 Thread Gregory Ewing

Michael Torrie wrote:

And such bindings may need to be two-way.
For example in Python code you may want to instantiate some new instance
of game object, and you'll need to make sure that the wrapper code will
create the appropriate in-game object.


Another thing that can be tricky about this is object
lifetimes. Python uses reference counting and garbage
collection to manage the lifetime of its data. If
your game engine has its own ideas on how to manage
lifetimes of its data structures, you may have
difficulties.

Typically you end up with a situation where each
game object has an associated "shadow" Python object,
with the two joined together like siamese twins.
You need to worry about keeping the Python object
alive as long as the game object is alive and vice
versa -- while making sure that they don't keep
each other alive forever.

If you have enough freedom, you may find it easier to
turn the problem around -- instead of embedding Python
in the game, embed the game in Python. Implement the
game engine as a Python extension module, where the
game objects are all inherently Python objects, and
Python is responsible for all of the lifetime management.
All the above headaches then go away, and a bonus you
get to write all the high-level logic of the game in Python.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Access to the caller's globals, not your own

2016-11-13 Thread Steven D'Aprano
Suppose I have a library function that reads a global configuration setting:

# Toy example
SPAMIFY = True
def make_spam(n):
if SPAMIFY:
return "spam"*n
else:
return "ham"*n


Don't tell me to make SPAMIFY a parameter of the function. I know that. That's 
what I would normally do, but *occasionally* it is still useful to have a 
global configuration setting, and those are the cases I'm talking about.


Now the caller can say:

import library
library.SPAMIFY = False
result = library.make_spam(99)


but that would be Wrong and Bad and Evil, because you're affecting *other* 
code, not your code, which relies on SPAMIFY being True. Doing this is (maybe) 
okay when testing the library, but not for production use.

What I really want is for make_spam() to be able to look at the caller's 
globals, so that each caller can create their own per-module configuration 
setting:

import library
SPAMIFY = False  # only affects this module, no other modules
result = library.make_spam(99)


But... how can make_spam() look for the caller's globals rather than its own?

I'd rather not do this:


def make_spam(n, namespace):
SPAMIFY = namespace['SPAMIFY']
...

which forces the user to do this:

result = library.make_spam(99, globals())


which defeats the purpose of making it a global setting. (If I wanted to 
*require* the caller to pass a parameter, I would just force them to pass in 
the flag itself. The whole point is to not require that.)

I'd be okay with making the namespace optional:


def make_spam(n, namespace=None):
if namespace is None:
namespace = ... # magic to get the caller's globals
SPAMIFY = namespace['SPAMIFY']
...


but what magic do I need? globals() is no good, because it returns the 
library's global namespace, not the caller's.


Any solution ought to work for CPython, IronPython and Jython, at a minimum.




-- 
Steven
299792.458 km/s — not just a good idea, it’s the law!

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Access to the caller's globals, not your own

2016-11-13 Thread eryk sun
On Mon, Nov 14, 2016 at 5:20 AM, Steven D'Aprano
 wrote:
> but what magic do I need? globals() is no good, because it returns the
> library's global namespace, not the caller's.
>
> Any solution ought to work for CPython, IronPython and Jython, at a minimum.

You can access the globals of the caller's frame, but you'll have to
research to what extent IronPython and Jython support CPython frame
objects.

FWIW:

import inspect

SPAMIFY = True

def make_spam(n):
caller_globals = inspect.currentframe().f_back.f_globals
if caller_globals.get('SPAMIFY', SPAMIFY):
return "spam" * n
else:
return "ham" * n

For example:

>>> import library
>>> library.make_spam(5)
'spamspamspamspamspam'
>>> SPAMIFY = False
>>> library.make_spam(5)
'hamhamhamhamham'
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: if iter(iterator) is iterator

2016-11-13 Thread Steven D'Aprano
On Monday 14 November 2016 16:04, Chris Angelico wrote:

> True, but ISTR there being a possibility that __iter__ could raise to
> indicate that this isn't actually iterable. Maybe I'm recalling wrong.

If __iter__ raises, that's a bug :-)

Raising an exception from __iter__ appears to just fall through. There doesn't 
seem to be any special handling:



py> class X:
... def __iter__(self):
... raise TypeError("foo")
... 
py> iter(X())
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 3, in __iter__
TypeError: foo


Contrast that to actual non-iterables:

py> iter(23)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'int' object is not iterable



The way to indicate a class is not iterable is to not give it an __iter__ 
method in the first place.

If the class inherits __iter__, and you want to over-ride it, you might try 
setting the child class __iter__ to None. That trick works for __hash__. It 
doesn't work for __iter__ in Python 3.3, but it might work in more recent 
versions.



-- 
Steven
299792.458 km/s — not just a good idea, it’s the law!

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: if iter(iterator) is iterator

2016-11-13 Thread Serhiy Storchaka

On 14.11.16 02:40, Steve D'Aprano wrote:

I'm surprised that the inspect module doesn't appear to have isiterable and
isiterator functions. Here's my first attempt at both:


Just use isinstance() with collections ABC classes.


--
https://mail.python.org/mailman/listinfo/python-list


Re: if iter(iterator) is iterator

2016-11-13 Thread eryk sun
On Mon, Nov 14, 2016 at 6:25 AM, Serhiy Storchaka  wrote:
> On 14.11.16 02:40, Steve D'Aprano wrote:
>>
>> I'm surprised that the inspect module doesn't appear to have isiterable
>> and isiterator functions. Here's my first attempt at both:
>
> Just use isinstance() with collections ABC classes.

Except objects that use the legacy __getitem__ iterator aren't
instances of collections.Iterable:

class C:
def __getitem__(self, index):
return index

o = C()

>>> isinstance(o, collections.Iterable)
False
>>> it = iter(o)
>>> type(it)

>>> next(it), next(it), next(it)
(0, 1, 2)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Best way to go about embedding python

2016-11-13 Thread Michael Torrie
On 11/13/2016 08:40 PM, Kaylen Wheeler wrote:
> I wonder if Lua would be a better option.  Does it suffer from the
> same sandboxing issues that python does?

Lua was designed for this sort of thing and it can be secured and sandboxed.
-- 
https://mail.python.org/mailman/listinfo/python-list