FAQ
Hi.

I'm having some fun with numbers. I've extraced an image sizes from a jpeg
file

img_x,img_y=image.getsize()

then I'm trying to use those sizes to scale the image, but because python
has decided that they are integers, I keep getting division by zero errors

eg
xscale=xframe/img_x

where xframe will be say 300, and img_x will be 1800
xscale has the value 0.

I've tried doing img_x=1.0 to force it to be a float, but I'm getting a bit
frustrated as it seems to make no difference - once image.getsize returns
the (integer) value of the x size, it simply converts back to an int. I've
tried this at the command line, and it seems to confirm that behaviour -
eg:
graham at rocklap:~/work/hsb/pdflive> python
Python 2.3b1 (#3, Jun 17 2003, 23:06:11)
[GCC 3.3 20030226 (prerelease) (SuSE Linux)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
x=1.0
xf=1.0
scale=1.0
x00
xf00
scale=xf/x
scale
>>>




Heres the relevant code in full:

img_x=1.0
img_y=1.0
img_x,img_y=image.getsize()
except "Not_JPEG":
if warn:
print ("WARNING: Image file %s is not a jpeg file" % fname)
sys.exit(OPEN_ERR)
# How many pixels per mm do we have
# On a4 paper, using pdfrw ? Docs seem to suggest between 60-160
# which seems a lot.

xscale=1.0
yscale=1.0
scale=1.0
xscale=1/(xframe/img_x)
yscale=1/(yframe/img_y)
#import pdb
#pdb.set_trace()
print ("xscale=%f,yscale=%f" %(xscale,yscale))
scale=min(xscale,yscale) * 100
print ("xframe=%d,yframe=%d, x=%d,y=%d scale=%f\n" %(xframe, yframe,
img_x, img_y, scale))

I'd really appreciate some help, thanks!
Graham
--
Graham Nicholls
Rock Computer Consultancy

Search Discussions

  • Charl P. Botha at Aug 11, 2003 at 12:47 pm
    In article <3f378fac$0$10778$afc38c87 at auth.uk.news.easynet.net>,
    Graham Nicholls wrote:
    then I'm trying to use those sizes to scale the image, but because python
    has decided that they are integers, I keep getting division by zero errors

    eg
    xscale=xframe/img_x

    where xframe will be say 300, and img_x will be 1800
    xscale has the value 0.
    Have you tried doing it this way:
    xscale = xframe / float(img_x)
  • Graham Nicholls at Aug 11, 2003 at 12:58 pm

    Charl P. Botha wrote:

    In article <3f378fac$0$10778$afc38c87 at auth.uk.news.easynet.net>,
    Graham Nicholls wrote:
    then I'm trying to use those sizes to scale the image, but because
    python has decided that they are integers, I keep getting division by
    zero errors

    eg
    xscale=xframe/img_x

    where xframe will be say 300, and img_x will be 1800
    xscale has the value 0.
    Have you tried doing it this way:
    xscale = xframe / float(img_x)
    Thats what I wanted to do, but was sure I'd read that python didn't have
    casts, and that _looks_ like a cast to me!

    Thanks
    Graham
    >

    --
    Graham Nicholls
    Rock Computer Consultancy
  • Istvan Albert at Aug 11, 2003 at 1:47 pm

    Graham Nicholls wrote:

    Have you tried doing it this way:
    xscale = xframe / float(img_x)

    Thats what I wanted to do, but was sure I'd read that python didn't have
    casts, and that _looks_ like a cast to me!
    You can also force floating point math by muliplying with 1.0
    before the division:

    xscale = 1.0 * xframe/img_x

    Istvan.
  • Graham Nicholls at Aug 11, 2003 at 3:37 pm

    Istvan Albert wrote:

    Graham Nicholls wrote:
    Have you tried doing it this way:
    xscale = xframe / float(img_x)

    Thats what I wanted to do, but was sure I'd read that python didn't have
    casts, and that _looks_ like a cast to me!
    You can also force floating point math by muliplying with 1.0
    before the division:

    xscale = 1.0 * xframe/img_x

    Istvan.
    Thanks everybody! I'm now sorted with numbers. At least 2.0+2.0 now equals
    about 4.0, anyway.
    Graham
    --
    Graham Nicholls
    Rock Computer Consultancy
  • Alex Martelli at Aug 11, 2003 at 2:38 pm
    Graham Nicholls wrote:
    ...
    xscale = xframe / float(img_x)
    Thats what I wanted to do, but was sure I'd read that python didn't have
    casts, and that _looks_ like a cast to me!
    Well, Python surely has the ability to create new objects, and the most
    typical way to do that is to call a type, possibly passing it, as the
    call's arguments, the value[s] that direct the new object's creation.


    So, for example, if you have a string S and want to create a list L
    whose items are the string's characters, you typically code:

    L = list(S)


    Similarly, if you have a number N and want to create a float F whose
    value is the floating-point equivalent of N's value, you code:

    F = float(N)


    Whether these are "casts" is, I guess, a pretty moot issue. Me, I'd
    call them "type calls" (or "explicit constructor calls" if I were in a C++
    mood:-), reserving the terminology "cast" for the C/Java notation:

    (sometype)somevalue

    or the C++ notations of forms such as:

    static_cast<sometype>(somevalue)

    But, of course (in C++), explicitly calling a costructor of (e.g.) float,
    with an integer argument; or statically casting an int to float; or even
    using the old C-ish "prepended type in parenthesis" notation; have much
    the same effect in most contexts. As long as you're quite clear that
    what you're actually doing is "create a new value of a specified type
    by calling the type with suitable argument[s]", rather than (the typical
    idea of "cast") "reinterpreting an existing value AS IF it was of some
    other type rather than of the type it actually is", it may not be a
    problem if you like to call the operation "a cast".


    Alex
  • Bengt Richter at Aug 11, 2003 at 8:35 pm

    On Mon, 11 Aug 2003 14:38:24 GMT, Alex Martelli wrote:
    Graham Nicholls wrote:
    ...
    xscale = xframe / float(img_x)
    Thats what I wanted to do, but was sure I'd read that python didn't have
    casts, and that _looks_ like a cast to me!
    Well, Python surely has the ability to create new objects, and the most
    typical way to do that is to call a type, possibly passing it, as the
    call's arguments, the value[s] that direct the new object's creation.


    So, for example, if you have a string S and want to create a list L
    whose items are the string's characters, you typically code:

    L = list(S)


    Similarly, if you have a number N and want to create a float F whose
    value is the floating-point equivalent of N's value, you code:

    F = float(N)


    Whether these are "casts" is, I guess, a pretty moot issue. Me, I'd
    call them "type calls" (or "explicit constructor calls" if I were in a C++
    mood:-), reserving the terminology "cast" for the C/Java notation:

    (sometype)somevalue

    or the C++ notations of forms such as:

    static_cast<sometype>(somevalue)

    But, of course (in C++), explicitly calling a costructor of (e.g.) float,
    with an integer argument; or statically casting an int to float; or even
    using the old C-ish "prepended type in parenthesis" notation; have much
    the same effect in most contexts. As long as you're quite clear that
    what you're actually doing is "create a new value of a specified type
    by calling the type with suitable argument[s]", rather than (the typical
    idea of "cast") "reinterpreting an existing value AS IF it was of some
    other type rather than of the type it actually is", it may not be a
    problem if you like to call the operation "a cast".
    <nit>I'd prefer adding the [] items in that last, to make it clear that a
    reinterpreting cast is about representations, not about the associated
    abstract values. I.e.,

    "..., rather than (the typical idea of "cast") "reinterpreting an existing [representation of a]
    value AS IF it was [a representation] of some other type rather than [being a representation]
    of the type it actually is", ..."
    </nit>

    One of the things I like about Python is the apparent motivation to unify according to what
    makes sense with the abstract aspects of represented values (even though it may sometimes take
    some getting used to if one has been steeped in representational details for decades).
    E.g., one might find
    [{1:'one'}[k] for k in [1, 1.0, 1L, 1e0]]
    ['one', 'one', 'one', 'one']

    surprising at first ;-)

    Interesting also the way the initial key's representational type is retained
    even when an abstract-value-as-effective-key is used to change the
    associated value:
    d = {1.0:'one'}
    d[1]
    'one'
    d
    {1.0: 'one'}
    d[1] = 'integer one'
    d
    {1.0: 'integer one'}
    d[1], d[1.0]
    ('integer one', 'integer one')

    And of course true division goes in the same direction.

    Regards,
    Bengt Richter
  • Terry Reedy at Aug 11, 2003 at 5:21 pm
    "Graham Nicholls" <graham at rockcons.co.uk> wrote in message
    news:3f3792f2$0$18258$afc38c87 at auth.uk.news.easynet.net...
    Have you tried doing it this way:
    xscale = xframe / float(img_x)
    Thats what I wanted to do, but was sure
    I'd read that python didn't have casts,
    Correct. Aside from re-classing of user-class instances, Python
    objects are more strongly typed than C values.
    and that _looks_ like a cast to me!
    No, quite different. A C cast (at least usually) recasts a block of
    bits in a new role without changing the bits. Type constructors
    (unless redundant as in int(1)) return a different object with a
    different set of bits.

    TJR
  • Erik Max Francis at Aug 11, 2003 at 6:15 pm

    Terry Reedy wrote:

    No, quite different. A C cast (at least usually) recasts a block of
    bits in a new role without changing the bits. Type constructors
    (unless redundant as in int(1)) return a different object with a
    different set of bits.
    Well, the issue is that, in C, a cast can mean a lot of different
    things. That's why, in C++, casts are separated into template like
    syntaxes depending on their purpose. The unsafe form of C cast is a
    reinterpret_cast in C++, and sometimes a const_cast (if you actually
    cast away constness of a truly const object and then attempt to mutate
    it). The other two -- static_cast and dynamic_cast -- are "safe" in the
    sense of being well-defined when the compiler accepts them, and merely
    invoke a well-defined conversion and do a runtime type cast,
    respectively.

    --
    Erik Max Francis && max at alcyone.com && http://www.alcyone.com/max/
    __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
    / \ Nobody can reach me, nobody can touch me; it's a wonderful feeling.
    \__/ Aaliyah
  • Carl Banks at Aug 11, 2003 at 11:46 pm

    Terry Reedy wrote:
    No, quite different. A C cast (at least usually) recasts a block of
    bits in a new role without changing the bits.
    Certainly not. Most type casts actually change bits. For example,
    supposing floats and longs are both 32 bits, the expression (float)1L
    will *not* return the floating point number with the same bit pattern
    as 1L. It returns 1.0.

    Usually, the only casts that preserve the bit pattern are integer to
    pointer casts, and the C standard doesn't even guarantee that (unless
    C 2000 changed it). In fact, the C standard says (or used to say)
    that 0 must always cast to a null pointer, even if the system
    represents integer 0 and null pointer with different bits, which does
    (or used to) happen.


    IMO, a type cast is just a fancy name for an operator that takes an
    object and returns an object with the same "value" (whatever that
    means) but a different type. In C, type casting happens to have a
    funny syntax. In Python, it does not. If someone asked, "does Python
    have type casting?", I would say yes, except there's no special syntax
    for it. Rather, type casting is done by the calling type objects
    themselves.



    --
    CARL BANKS
    "You don't run Microsoft Windows. Microsoft Windows runs you."
  • Erik Max Francis at Aug 12, 2003 at 12:36 am

    Carl Banks wrote:

    Certainly not. Most type casts actually change bits.
    Some casts do. Some merely invoke conversions.
    For example,
    supposing floats and longs are both 32 bits, the expression (float)1L
    will *not* return the floating point number with the same bit pattern
    as 1L. It returns 1.0.
    But the C++ equivalent, something like (float) 1, would _not_ return the
    floating point number with the same bit pattern as 1L either. It would
    simply invoke the conversion from int to float. What you're talking
    about would be something like *(float *) &i.

    --
    Erik Max Francis && max at alcyone.com && http://www.alcyone.com/max/
    __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
    / \ Life is an effort that deserves a better cause.
    \__/ Karl Kraus
  • Carl Banks at Aug 12, 2003 at 12:57 am

    Erik Max Francis wrote:
    Carl Banks wrote:
    Certainly not. Most type casts actually change bits.
    Some casts do. Some merely invoke conversions.
    For example,
    supposing floats and longs are both 32 bits, the expression (float)1L
    will *not* return the floating point number with the same bit pattern
    as 1L. It returns 1.0.
    But the C++ equivalent, something like (float) 1, would _not_ return the
    floating point number with the same bit pattern as 1L either. It would
    simply invoke the conversion from int to float. What you're talking
    about would be something like *(float *) &i.

    It seems you didn't read what I wrote carefully. I was talking about
    C, not C++. Neither I nor the post I replied to mentioned C++ once.
    I mentioned the C standard several times, never the C++ standard.

    Type casts in C are as I described.



    --
    CARL BANKS
    "You don't run Microsoft Windows. Microsoft Windows runs you."
  • Erik Max Francis at Aug 12, 2003 at 1:32 am

    Carl Banks wrote:

    It seems you didn't read what I wrote carefully. I was talking about
    C, not C++. Neither I nor the post I replied to mentioned C++ once.
    I mentioned the C standard several times, never the C++ standard.

    Type casts in C are as I described.
    C++ was mentioned by the original poster; either way, C and C++ casts
    act precisely the same in this context. (float) 1 and *(float *) &i
    have precisely the same meanings both in C and C++.

    --
    Erik Max Francis && max at alcyone.com && http://www.alcyone.com/max/
    __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
    / \ If you don't take chances, you can't do anything in life.
    \__/ Michael Spinks
  • Bengt Richter at Aug 12, 2003 at 2:41 am

    On Mon, 11 Aug 2003 18:32:12 -0700, Erik Max Francis wrote:
    Carl Banks wrote:
    It seems you didn't read what I wrote carefully. I was talking about
    C, not C++. Neither I nor the post I replied to mentioned C++ once.
    I mentioned the C standard several times, never the C++ standard.

    Type casts in C are as I described.
    C++ was mentioned by the original poster; either way, C and C++ casts
    act precisely the same in this context. (float) 1 and *(float *) &i
    have precisely the same meanings both in C and C++.
    <nit>With (float) 1 it can optimize to one instruction with immediate
    operand constant. With the other it needs (at least on x86) to move via
    EAX, for two instructions (e.g., assigning the resp values).

    Where x&y are extern floats, to make sure unused vars don't get optimized away:

    ; 3 : int i = 1;

    00004 c7 45 fc 01 00
    00 00 mov DWORD PTR _i$[ebp], 1

    ; 4 : x = (float) 1;

    0000b c7 05 00 00 00
    00 00 00 80 3f mov DWORD PTR _x, 1065353216 ; 3f800000H

    ; 5 : y = *(float *) &i;

    00015 8b 45 fc mov eax, DWORD PTR _i$[ebp]
    00018 a3 00 00 00 00 mov DWORD PTR _y, eax


    I agree the bits are just being moved in either case for assignment. But
    then if you multiply by 5.0, the compiler will fold one constant expression,
    but not the other (even with max optimizimg and declaring const stuff not shown here)

    ; 3 : int i = 1;

    00004 c7 45 fc 01 00
    00 00 mov DWORD PTR _i$[ebp], 1

    ; 4 : x = 5.0*((float) 1);

    0000b c7 05 00 00 00
    00 00 00 a0 40 mov DWORD PTR _x, 1084227584 ; 40a00000H

    ; 5 : y = 5.0*(*(float *) &i);

    00015 d9 45 fc fld DWORD PTR _i$[ebp]
    00018 dc 0d 00 00 00
    00 fmul QWORD PTR __real at 8@4001a000000000000000
    0001e d9 1d 00 00 00
    00 fstp DWORD PTR _y

    </nit>

    So what a source spelling "really means" depends on what aspect you are concentrating,
    I think you might agree? Sometimes the context does not result in code that will
    "act precisely the same." Depending ;-)

    Regards,
    Bengt Richter
  • Erik Max Francis at Aug 12, 2003 at 3:05 am

    Bengt Richter wrote:

    <nit>With (float) 1 it can optimize to one instruction with immediate
    operand constant. With the other it needs (at least on x86) to move
    via
    EAX, for two instructions (e.g., assigning the resp values).
    This is wholly an implementation detail. The point is, in C and C++,
    casts have different purposes. Some are compile-time, some are
    run-time; some are safe and are simply conversion, others are unsafe and
    result in implementation-defined or undefined behavior. Not all C casts
    are unsafe; some simply invoke conversions.

    --
    Erik Max Francis && max at alcyone.com && http://www.alcyone.com/max/
    __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
    / \ Come not between the dragon and his wrath.
    \__/ King Lear (Act I, Scene I)
  • Bengt Richter at Aug 12, 2003 at 1:23 am

    On Mon, 11 Aug 2003 23:46:38 GMT, Carl Banks wrote:
    Terry Reedy wrote:
    No, quite different. A C cast (at least usually) recasts a block of
    bits in a new role without changing the bits.
    Certainly not. Most type casts actually change bits. For example,
    supposing floats and longs are both 32 bits, the expression (float)1L
    will *not* return the floating point number with the same bit pattern
    as 1L. It returns 1.0.

    Usually, the only casts that preserve the bit pattern are integer to
    pointer casts, and the C standard doesn't even guarantee that (unless
    C 2000 changed it). In fact, the C standard says (or used to say)
    that 0 must always cast to a null pointer, even if the system
    represents integer 0 and null pointer with different bits, which does
    (or used to) happen.


    IMO, a type cast is just a fancy name for an operator that takes an
    object and returns an object with the same "value" (whatever that
    means) but a different type. In C, type casting happens to have a
    funny syntax. In Python, it does not. If someone asked, "does Python
    have type casting?", I would say yes, except there's no special syntax
    for it. Rather, type casting is done by the calling type objects
    themselves.
    Well, there is one way to look at existing bits exactly as they are in
    terms of an alternate type representation. The easy way is to do reinterpret cast
    on a pointer to change a pointer to the old type into a pointer to a new type,
    without changing location. E.g., how else to print out the bit representation
    of something? E.g., here's a hack to see floats and doubles as little-ending python strings:

    ====< castf.c >======================================
    #include <stdio.h>
    #include <stdlib.h>

    int main(int argc, char *argv[]){
    float f4;
    double f8;
    int i;
    if(argc<2){ printf("Usage: castf <floating point number for atof>\n"); return 0;}
    f8 = atof(argv[1]); f4=f8;
    printf("\"");
    for(i=0; i<sizeof(f4); ++i){ printf("\\x%02x",((unsigned char *)(&f4))[i]);};
    printf("\"\n");
    printf("\"");
    for(i=0; i<sizeof(f8); ++i){ printf("\\x%02x",((unsigned char *)(&f8))[i]);};
    printf("\"\n");
    return 0;
    }
    =====================================================
    [18:04] C:\pywk\clp>castf
    Usage: castf <floating point number for atof>

    [18:04] C:\pywk\clp>castf 1.625
    "\x00\x00\xd0\x3f"
    "\x00\x00\x00\x00\x00\x00\xfa\x3f"

    [18:04] C:\pywk\clp>castf -1.625
    "\x00\x00\xd0\xbf"
    "\x00\x00\x00\x00\x00\x00\xfa\xbf"

    [18:04] C:\pywk\clp>castf 0
    "\x00\x00\x00\x00"
    "\x00\x00\x00\x00\x00\x00\x00\x00"

    [18:04] C:\pywk\clp>castf 1
    "\x00\x00\x80\x3f"
    "\x00\x00\x00\x00\x00\x00\xf0\x3f"

    [18:04] C:\pywk\clp>castf -1
    "\x00\x00\x80\xbf"
    "\x00\x00\x00\x00\x00\x00\xf0\xbf"

    Actually, it's a little confusing to look at numbers in that order, especially
    since the hex for the bits in the bytes is big-end-on-the-left ;-)

    2**54-1 (naturally I used python to get the number ;-)
    [18:12] C:\pywk\clp>castf 18014398509481983
    "\x00\x00\x80\x5a"
    "\xff\xff\xff\xff\xff\xff\x4f\x43"

    2**53-1
    [18:12] C:\pywk\clp>castf 9007199254740991
    "\x00\x00\x00\x5a"
    "\xff\xff\xff\xff\xff\xff\x3f\x43"

    2**52-2**12
    [18:12] C:\pywk\clp>castf 9007199254736896
    "\x00\x00\x00\x5a"
    "\x00\xf0\xff\xff\xff\xff\x3f\x43"
    ^^ ^-bits 8-11 (the f is bits 12-15)
    ^^-bits 0-7

    Of course, the cleaner way would have been to factor that instead of cutting and pasting:
    Some architectures might not like addressing arbitrary bytes, but we'll leave that as exercise
    material ;-)

    ====< castf.c >======================================
    #include <stdio.h>
    #include <stdlib.h>

    void prnch(void *pthing, int n){
    int i;
    printf("\"");
    for(i=0; i<n; ++i){ printf("\\x%02x",((unsigned char *)(pthing))[i]);};
    printf("\"\n");
    }

    int main(int argc, char *argv[]){
    float f4; double f8;
    if(argc<2){ printf("Usage: castf <floating point number for atof>\n"); return 0;}
    f8 = atof(argv[1]); f4=f8;
    prnch(&f4, sizeof(f4));
    prnch(&f8, sizeof(f8));
    return 0;
    }
    ==========================================
    Regards,
    Bengt Richter
  • Terry Reedy at Aug 12, 2003 at 2:09 am
    "Carl Banks" <imbosol at aerojockey.com> wrote in message
    news:yVVZa.764$u%2.33 at nwrdny02.gnilink.net...
    Terry Reedy wrote:
    No, quite different. A C cast (at least usually) recasts a block
    of
    bits in a new role without changing the bits.
    Certainly not. Most type casts actually change bits.
  • Carl Banks at Aug 12, 2003 at 4:13 am

    Terry Reedy wrote:
    "Carl Banks" <imbosol at aerojockey.com> wrote in message
    news:yVVZa.764$u%2.33 at nwrdny02.gnilink.net...
    Terry Reedy wrote:
    No, quite different. A C cast (at least usually) recasts a block
    of
    bits in a new role without changing the bits.
    Certainly not. Most type casts actually change bits.
    From what I remember both in my own code and others that I have read,
    most casts, where 'most' is measured in frequency of occurence in
    actual code, which is what I meant by 'usually'.
    I didn't like the wording. The way you said it, it sounded (whether
    you intended it or not) like you were saying: "C generally casts by
    preserving the bit pattern, except for a few exceptions," but that's
    not how it is.

    Even if they are more commonly used, casts that preserve the bit
    pattern are the special ones. The general rule is that C casts
    preserve "value." Sometimes the equivalent "value" happens to have
    equivalent bits: that's the case for int-to-pointer and
    pointer-to-pointer.


    [snip]
    and the C standard doesn't even guarantee that (unless
    C 2000 changed it). In fact, the C standard says (or used to say)
    that 0 must always cast to a null pointer, even if the system
    represents integer 0 and null pointer with different bits, which does
    (or used to) happen.
    On which systems? How widely used? I also added 'at least usually'
    to account for systems I don't know about ;-)
    Don't know of any examples off hand. The comp.lang.c FAQ lists some.

    IMO, a type cast is just a fancy name for an operator that takes an
    object and returns an object with the same "value" (whatever that
    means) but a different type. In C, type casting happens to have a
    funny syntax. In Python, it does not. If someone asked, "does Python
    have type casting?", I would say yes, except there's no special syntax
    for it. Rather, type casting is done by the calling type objects
    themselves.
    In my opinion, it is unhelpful to refer to type-function calls as
    casts. To me, the baggage 'cast' carries is more confusing than
    helpful. For instance, a common conversion, between number and
    string, cannot be done in C with a type cast but must also (as in
    Python) be done with a function call. Would you call C's atoi(),
    atof(), and sprintf casts? In C, the 'funny syntax' defines what I
    believe most people call a type cast versus a function call. This is
    certainly true for both K&R and the Standard C committee.
    On one hand, I respect that opinion. OTOH, I think the assertion that
    Python has no type casting leads to misunderstanding. Take the OP for
    example. Because of the statement that Python has no type casts, he
    didn't realize that Python does have functionality of type casting.

    So I don't think anyone should say simply, "Python does not have type
    casts." Better, I think, to say, yes, Python has type casts, although
    we don't call them type casts 'round here because they look and act
    like regular function calls.

    And to answer your question, no: atoi, atof, and sprintf are not type
    casts even by my definition, because string is not a type in C.


    --
    CARL BANKS
    "You don't run Microsoft Windows. Microsoft Windows runs you."
  • Erik Max Francis at Aug 11, 2003 at 6:12 pm

    Graham Nicholls wrote:

    Thats what I wanted to do, but was sure I'd read that python didn't
    have
    casts, and that _looks_ like a cast to me!
    It's a function call, not a conversion. Even in C++, conversion by
    constructor is not considered a cast. A cast would be:

    xframe/static_cast<float>(image_x)

    and there is no analogous structure to this in Python.

    --
    Erik Max Francis && max at alcyone.com && http://www.alcyone.com/max/
    __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
    / \ Nobody can reach me, nobody can touch me; it's a wonderful feeling.
    \__/ Aaliyah
  • Erik Max Francis at Aug 11, 2003 at 6:43 pm

    Erik Max Francis wrote:

    It's a function call, not a conversion.
    Oops, that was supposed to be, "It's a functional call, not a cast."

    --
    Erik Max Francis && max at alcyone.com && http://www.alcyone.com/max/
    __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
    / \ Nobody can reach me, nobody can touch me; it's a wonderful feeling.
    \__/ Aaliyah
  • Duncan Booth at Aug 11, 2003 at 12:56 pm
    Graham Nicholls <graham at rockcons.co.uk> wrote in
    news:3f378fac$0$10778$afc38c87 at auth.uk.news.easynet.net:
    eg
    xscale=xframe/img_x

    where xframe will be say 300, and img_x will be 1800
    xscale has the value 0.

    I've tried doing img_x=1.0 to force it to be a float, but I'm getting
    a bit frustrated as it seems to make no difference - once
    image.getsize returns the (integer) value of the x size, it simply
    converts back to an int.
    Variables don't have types in Python, objects have types. Assigning a float
    object to a variable doesn't have any effect on the type of the next
    object assigned to the same variable.

    To get the behaviour you want either convert at least one of your values to
    a float:

    xscale = float(xframe)/img_x

    or add the following 'magic' line to the top of your sourcefile:

    from __future__ import division

    If your file has that line at the top, division will behave more the way
    you expect: casting to float automatically whenever you divide integers.

    --
    Duncan Booth duncan at rcp.co.uk
    int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
    "\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?
  • Richard Brodie at Aug 11, 2003 at 1:01 pm
    "Graham Nicholls" <graham at rockcons.co.uk> wrote in message
    news:3f378fac$0$10778$afc38c87 at auth.uk.news.easynet.net...
    I've tried doing img_x=1.0 to force it to be a float, but I'm getting a bit
    frustrated as it seems to make no difference - once image.getsize returns
    the (integer) value of the x size, it simply converts back to an int.
    Yes. Types are properties of values, not names. There is no implied
    declaration: you can assign a float to img_x then later an int, string,
    function or whatever.

    To get floating point division you can use a cast like syntax, by using
    the builtin float() function.
    1 / 2
    float (1) / float(2)
    0.5

    In future versions of Python, / will become a floating point division operator.
    // will be used for truncating division. For compatibility, you need to
    explicitly enable the new behaviour at present, either with a from __future__
    or a -Q option. These activate Guido's famous time machine, which add
    new features to Python before you ask for them.
    from __future__ import division
    1 / 2
    0.5
    1 // 2

    U:\>python -Qwarn
    ActivePython 2.2.2 Build 224 (ActiveState Corp.) based on
    Python 2.2.2 (#37, Nov 26 2002, 10:24:37) [MSC 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    1/2
    __main__:1: DeprecationWarning: classic int division
  • Torsten Marek at Aug 11, 2003 at 1:09 pm

    Graham Nicholls schrieb:
    Hi.

    I'm having some fun with numbers. I've extraced an image sizes from a jpeg
    file

    img_x,img_y=image.getsize()

    then I'm trying to use those sizes to scale the image, but because python
    has decided that they are integers, I keep getting division by zero errors

    eg
    xscale=xframe/img_x

    where xframe will be say 300, and img_x will be 1800
    xscale has the value 0.

    I've tried doing img_x=1.0 to force it to be a float, but I'm getting a bit
    frustrated as it seems to make no difference - once image.getsize returns
    the (integer) value of the x size, it simply converts back to an int. I've
    tried this at the command line, and it seems to confirm that behaviour -
    eg:
    graham at rocklap:~/work/hsb/pdflive> python
    Python 2.3b1 (#3, Jun 17 2003, 23:06:11)
    [GCC 3.3 20030226 (prerelease) (SuSE Linux)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    x=1.0
    xf=1.0
    scale=1.0
    x00
    xf00
    scale=xf/x
    scale






    Heres the relevant code in full:

    img_x=1.0
    img_y=1.0
    img_x,img_y=image.getsize()
    except "Not_JPEG":
    if warn:
    print ("WARNING: Image file %s is not a jpeg file" % fname)
    sys.exit(OPEN_ERR)
    # How many pixels per mm do we have
    # On a4 paper, using pdfrw ? Docs seem to suggest between 60-160
    # which seems a lot.

    xscale=1.0
    yscale=1.0
    scale=1.0
    xscale=1/(xframe/img_x)
    yscale=1/(yframe/img_y)
    #import pdb
    #pdb.set_trace()
    print ("xscale=%f,yscale=%f" %(xscale,yscale))
    scale=min(xscale,yscale) * 100
    print ("xframe=%d,yframe=%d, x=%d,y=%d scale=%f\n" %(xframe, yframe,
    img_x, img_y, scale))

    I'd really appreciate some help, thanks!
    Graham
    The type of a variable does not depend on the type it was initialized with.
    You could do
    t = 1
    t = 1.1
    t = "1"
    t = [1,]
    and the type changes each time. There is no concept of "int xscale" what
    you might have in mind.
    You just should convert the integer into a float with
    xscale=1/(xframe/float(img_x)).


    greetings
    Torsten
  • Andrew Koenig at Aug 11, 2003 at 1:51 pm
    Graham> I'm having some fun with numbers. I've extraced an image
    Graham> sizes from a jpeg file

    Graham> img_x,img_y=image.getsize()

    Graham> then I'm trying to use those sizes to scale the image, but
    Graham> because python has decided that they are integers, I keep
    Graham> getting division by zero errors

    Graham> eg
    Graham> xscale=xframe/img_x

    Graham> where xframe will be say 300, and img_x will be 1800
    Graham> xscale has the value 0.

    Graham> I've tried doing img_x=1.0 to force it to be a float, but I'm
    Graham> getting a bit frustrated as it seems to make no difference -
    Graham> once image.getsize returns the (integer) value of the x size,
    Graham> it simply converts back to an int.

    Two possibilities:

    1) Create a floating-point value from the dividend or divisor,
    which will cause the other one to be converted to float:

    xscale = float(xframe) / img_x

    or

    xscale = xframe / float(img_x)

    2) At the beginning of your source file, execute:

    from __future__ import division

    Python is going to change its behavior so that division always
    returns a floating-point value. This statement causes that new
    behavior to occur now.

    --
    Andrew Koenig, ark at acm.org
  • Istvan Albert at Aug 11, 2003 at 6:40 pm

    Andrew Koenig wrote:
    Python is going to change its behavior so that division always
    returns a floating-point value. This statement causes that new
    behavior to occur now.
    Will there be a keyword/function for integer division after that?

    Not that my opinion has any weight in this matter, but I got used
    to integer division as default behavior after all C, and java
    work that way too, it is not like it is a pythonic oddity.

    Once it gets implemented then there will be numerous questions about
    doing integer division.

    Istvan.
  • Erik Max Francis at Aug 11, 2003 at 6:55 pm

    Istvan Albert wrote:

    Will there be a keyword/function for integer division after that?
    Yes, the // operator.

    --
    Erik Max Francis && max at alcyone.com && http://www.alcyone.com/max/
    __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
    / \ Nobody can reach me, nobody can touch me; it's a wonderful feeling.
    \__/ Aaliyah
  • Andrew Koenig at Aug 11, 2003 at 8:16 pm
    Istvan> Will there be a keyword/function for integer division after that?

    Yes -- a//b is the integer part of a/b.

    --
    Andrew Koenig, ark at acm.org
  • Hannu Kankaanpää at Aug 11, 2003 at 8:36 pm
    Andrew Koenig <ark at acm.org> wrote in message news:<yu99fzk8715z.fsf at tinker.research.att.com>...
    2) At the beginning of your source file, execute:

    from __future__ import division

    Python is going to change its behavior so that division always
    returns a floating-point value. This statement causes that new
    behavior to occur now.
    By the way, do you know a reason why after doing

    from __future__ import division

    this still happens:
    3.0 // 2
    1.0

    Wouldn't it be more convenient to present the resulting whole
    number as an integer now, since division operation on integers
    works correctly? At least IMO the operation
    3.0 // 2
    1

    would be more convenient and natural, and floor division could then be
    used to get array indices for example:

    print arr[position // scale]

    Not that I -really- care either way, since casting division result
    to int isn't verbose either. Just curious, if you or anyone
    knows the reason for new floor div working this way.
  • Terry Reedy at Aug 12, 2003 at 1:26 am
    "Hannu Kankaanp??" <hanzspam at yahoo.com.au> wrote in message
    news:840592e1.0308111236.63bd85c0 at posting.google.com...
    By the way, do you know a reason why after doing

    from __future__ import division

    this still happens:
    3.0 // 2
    1.0
    This follows the general rule that float op int is a float.
    Wouldn't it be more convenient to present the resulting whole
    number as an integer now, since division operation on integers
    works correctly? At least IMO the operation
    3.0 // 2
    1

    would be more convenient and natural, and floor division could then be
    used to get array indices for example:
    A language designer has to think through all the ramifications of each
    decision and not locally optimize. Guido has done fairly well at
    this, and probably better than most of us would. He might someday
    decide to go for further number unification -- of integers and
    floats -- but there are questions to consider. What would you have
    2.22222e300/2 be? A loooong long? Should 2.5*4.0 become an int (so
    it can be an array index)? Should 'normal' users of floats (for math
    calculation) be time-penalized by automatically adding an isint? check
    to each float operation just so the occasional user who actually want
    the conversion can get it without being explicit?
    (I think not.)

    Terry J. Reedy

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedAug 11, '03 at 12:44p
activeAug 12, '03 at 4:13a
posts29
users13
websitepython.org

People

Translate

site design / logo © 2022 Grokbase