如何在Sympy中转换单位前缀

时间:2017-02-20 09:22:10

标签: python sympy

我想知道如何将具有物理单位的sympy值转换为具有另一个前缀的同一单元。例如:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

//fix the name of the file we need to recover from
#define NAME_RAW_FILE "card.raw"

//block size is 512
#define BLOCK_SIZE 512

// "jpg.000" + /n   => 8 chars
#define JPEG_NAME_LENGTH 8 

// Format of the jpeg file name, using 3 integers padded with 0's
// see https://www.tutorialspoint.com/c_standard_library/c_function_sprintf.htm 
#define JPEG_FILE_FORMAT "%03d.jpg"

// bool checking if the header is the one of a jpg
bool is_jpeg (unsigned char header [])
{
    /* this is equivalent to saying if(condition), return TRUE. Return gives back to the function 
     * any value that comes out of the expression in its scope, in our case the value is TRUE if the 
     * expression with the equivalences is verified, else false. */
    return (header[0] == 0xff 
            && header[1] == 0xd8 
            && header[2] == 0xff 
            && (header[3] & 0xf0) == 0xe0);
}

int main(int argc, char *argv[])
{
    if (argc != 1)
    {
        //no command line argument after programme name
        fprintf(stderr, "Usage: ./recover\n");
        return 1;
    }

    // open memory card file 
    FILE* raw_file = fopen(NAME_RAW_FILE, "r");
    if (raw_file == NULL)
    {
        fprintf(stderr, "Could not open file %s.\n", NAME_RAW_FILE);
        return 1;
    }

    // Store new JPG name and count them 
    char jpeg_filename[JPEG_NAME_LENGTH];
    int jpeg_recoverd_counter = 0;

    // Currently opened file we're writing to 
    FILE* jpeg_file = NULL; 

    /* we need another buffer to store our jpg data from card.raw  
     * we use unsigned chars because it's basically equivalent to 
     * saying bytes */
    unsigned char buffer [BLOCK_SIZE];

    /* loop over every block of the memory card until EOF.
     * What this loop does is checking if the fread function
     * returned 512 bytes of size 1, and breaks 
     * when there is a block of less than 512 bytes : end of file */
    while (fread (buffer, 1, BLOCK_SIZE, raw_file) == BLOCK_SIZE)
    {
        // checks if the first 4 bytes of the block corresponds to a jpg 
        if (is_jpeg (buffer))
        {
            // Is there a previous jpg file open? If so, close it.
            // This won't close your first jpg file which is set to NULL
            // at line 43. 
            if (jpeg_file != NULL)
            {
                fclose(jpeg_file);
            }

            // This line creates a custom filename that will be stored 
            // in the jpeg_filename array
            sprintf(jpeg_filename, JPEG_FILE_FORMAT, jpeg_recoverd_counter++);

            // Now that I have the name of the file stored in jpeg_filename
            // I open a file in reading and writing mode with that name
            jpeg_file = fopen(jpeg_filename, "w+");

            // Check that jpeg_file opened successfully
            if(jpeg_file == NULL)
            {
                fclose(raw_file);
                fprintf(stderr, "recover: %s: Error creating file", jpeg_filename);
                return 1;
            }
        }

        /* At this stage, if no jpeg was found then no jpeg_file was opened. 
         * so I create a condition to skip any initial bytes not belonging to 
         * a jpeg by checking if there is a jpeg_file open. If we do have a jpeg 
         * file open, then write into it */

        if (jpeg_file != NULL)
        {
            /* So, if I do have a jpeg file opened, then I want to write into it
             * but I also want to make sure that the writing succeeds, so I encase 
             * fwrite function in a if condition that checks the return value of the
             * function (BLOCK_SIZE). If the writing did not succeed then close everything 
             * and print error. */
            if(fwrite(buffer, 1, BLOCK_SIZE, jpeg_file) != BLOCK_SIZE)
            {
                fclose(jpeg_file);
                fclose(raw_file);
                fprintf(stderr, "recover: %s : Error writing the file\n", jpeg_filename);
                return 1;
            }
        }
    }

    // Close last file open, checking that we ever opened one (imagine card.raw had no jpeg!)
    if(jpeg_file != NULL)
    {
        fclose(jpeg_file);
    }

    // Was there an error reading from the card?
    if(ferror(raw_file))
    {
        fclose(raw_file);
        fprintf(stderr, "recover: %s: Error reading file\n", argv[0]);
        return 1;
    }

    // Else, all good. 
    fclose(raw_file);
    return 0;
}

应转换为克。到目前为止,我所采用的方法非常臃肿,结果错误。

>>> import sympy.physics.units as u
>>> x = 0.001 * u.kilogram
0.001kg

应该是>>> x / u.kilogram * u.gram 1.0^-6kg

2 个答案:

答案 0 :(得分:2)

如果您可以接受打印1而不是1g,则可以使用分部:

>>> x / u.g
1.0

否则,您最好切换到sympy.physics.unitsystems

>>> from sympy.physics.unitsystems import Quantity
>>> from sympy.physics.unitsystems.systems import mks
>>> Quantity(0.001, mks['kg'])
0.001kg
>>> _.convert_to(mks['g'])
1g

答案 1 :(得分:1)

>>> u.convert_to(x, u.gram)
1.0*gram