Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

py2php转换错误例子 #32

Open
he426100 opened this issue Dec 29, 2023 · 1 comment
Open

py2php转换错误例子 #32

he426100 opened this issue Dec 29, 2023 · 1 comment

Comments

@he426100
Copy link
Contributor

he426100 commented Dec 29, 2023

  1. Parse error: syntax error, unexpected token ")" on line 18
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");
$str_val = "apples";
$num_val = 42;
PyCore::print($num_val . " " . $str_val);
$str_val = "apples";
$num_val = 42;
PyCore::print("str_val=" . $str_val . ", num_val = " . $num_val);
$num_val = 42;
PyCore::print("num_val % 2 = " . $num_val % 2);
$str_val = "apples";
PyCore::print($str_val);
$price_val = 6.12658;
PyCore::print(round($price_val, 2));
$datetime = PyCore::import('datetime')->datetime;
$date_val = $datetime->utcnow();
PyCore::print("date_val=" . );
str_val = 'apples'
num_val = 42

print(f'{num_val} {str_val}') # 42 apples

str_val = 'apples'
num_val = 42

print(f'{str_val=}, {num_val = }') # str_val='apples', num_val = 42

num_val = 42

print(f'{num_val % 2 = }') # num_val % 2 = 0

str_val = 'apples'

print(f'{str_val!r}') # 'apples'

price_val = 6.12658

print(f'{price_val:.2f}') # 6.13

from datetime import datetime;

date_val = datetime.utcnow()

print(f'{date_val=:%Y-%m-%d}') # date_val=2021-07-09
  1. Warning: Undefined variable $timedelta on line 9
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");
$date = PyCore::import('datetime')->date;
$datetime = PyCore::import('datetime')->datetime;
$timedelta = PyCore::import('datetime')->timedelta;

function add_days($n, $d) {
    return $d + $timedelta($n);
}


add_days(5, $date(2020, 10, 25));
add_days(-5, $date(2020, 10, 25));
from datetime import date, datetime, timedelta

def add_days(n, d = datetime.today()):
  return d + timedelta(n)

add_days(5, date(2020, 10, 25)) # date(2020, 10, 30)
add_days(-5, date(2020, 10, 25)) # date(2020, 10, 20)
  1. Parse error: syntax error, unexpected variable "$x", expecting ":" on line 18
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function average_by($lst, $fn) {
    return PyCore::sum(PyCore::map($fn, $lst), 0) / PyCore::len($lst);
}


average_by(new PyList([new PyDict([
    "n" => 4,
]), new PyDict([
    "n" => 2,
]), new PyDict([
    "n" => 8,
]), new PyDict([
    "n" => 6,
])]), return $x->__getitem__("n");

});
def average_by(lst, fn = lambda x: x):
  return sum(map(fn, lst), 0.0) / len(lst)

average_by([{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }], lambda x: x['n'])
# 5.0
  1. Parse error: syntax error, unexpected token "$", expecting variable on line 6
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function bifurcate($lst, $filter) {
    return new PyList([(function($) {
        $___ = [];
        $elts = [];
        foreach($ as [$x, $flag]) {
            $elts[0] = [$x, $flag];
        }
        $___[] = $elts;
        return $___;
    })($), (function($) {
        $___ = [];
        $elts = [];
        foreach($ as [$x, $flag]) {
            $elts[0] = [$x, $flag];
        }
        $___[] = $elts;
        return $___;
    })($)]);
}


bifurcate(new PyList(["beep", "boop", "foo", "bar"]), new PyList([true, true, false, true]));
def bifurcate(lst, filter):
  return [
    [x for x, flag in zip(lst, filter) if flag],
    [x for x, flag in zip(lst, filter) if not flag]
  ]

bifurcate(['beep', 'boop', 'foo', 'bar'], [True, True, False, True])
# [ ['beep', 'boop', 'bar'], ['foo'] ]
  1. Fatal error: Uncaught Error: Call to a member function encode() on string in /home/mrpzx/git/phpy/phpy-examples/30s/python-code/byte-size.php:6
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function byte_size($s) {
    return PyCore::len($s->encode("utf-8"));
}


byte_size("😀");
byte_size("Hello World");
def byte_size(s):
  return len(s.encode('utf-8'))

byte_size('😀') # 4
byte_size('Hello World') # 11
  1. Fatal error: Uncaught Error: Call to a member function title() on string in /home/mrpzx/git/phpy/phpy-examples/30s/python-code/capitalize-every-word.php:6
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function capitalize_every_word($s) {
    return $s->title();
}


capitalize_every_word("hello world!");
def capitalize_every_word(s):
  return s.title()

capitalize_every_word('hello world!') # 'Hello World!'
  1. Fatal error: Uncaught ArgumentCountError: Too few arguments to function capitalize(), 1 passed on line 10
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function capitalize($s, $lower_rest) {
    return PyCore::str("")->join(new PyList([$s->__getitem__(PyCore::slice(null, 1, null))->upper(), $lower_rest ? $s->__getitem__(PyCore::slice(1, null, null))->lower() : $s->__getitem__(PyCore::slice(1, null, null))]));
}


capitalize("fooBar");
capitalize("fooBar", true);
def capitalize(s, lower_rest = False):
  return ''.join([s[:1].upper(), (s[1:].lower() if lower_rest else s[1:])])

capitalize('fooBar') # 'FooBar'
capitalize('fooBar', True) # 'Foobar'
  1. Warning: Undefined variable $tuple on line 6
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function cast_list($val) {
    return PyCore::isinstance($val, [$tuple, $list, $set, $dict]) ? PyCore::list($val) : new PyList([$val]);
}


cast_list("foo");
cast_list(new PyList([1]));
cast_list(["foo", "bar"]);
def cast_list(val):
  return list(val) if isinstance(val, (tuple, list, set, dict)) else [val]

cast_list('foo') # ['foo']
cast_list([1]) # [1]
cast_list(('foo', 'bar')) # ['foo', 'bar']
  1. Parse error: syntax error, unexpected variable "$lst", expecting ":" on line 8
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");
$ceil = PyCore::import('math')->ceil;

function chunk_into_n($lst, $n) {
    $size = $ceil(PyCore::len($lst) / $n);
    return PyCore::list(PyCore::map(return $lst->__getitem__(PyCore::slice($x * $size, $x * $size + $size, null));

    }, PyCore::list(PyCore::range($n))));
}


chunk_into_n(new PyList([1, 2, 3, 4, 5, 6, 7]), 4);
from math import ceil

def chunk_into_n(lst, n):
  size = ceil(len(lst) / n)
  return list(
    map(lambda x: lst[x * size:x * size + size],
    list(range(n)))
  )

chunk_into_n([1, 2, 3, 4, 5, 6, 7], 4) # [[1, 2], [3, 4], [5, 6], [7]]
  1. Parse error: syntax error, unexpected token "!", expecting ":" on line 72
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function difference($a, $b) {
    return (function($a) {
        $___ = [];
        $elts = [];
        foreach($a as $item) {
            $elts[0] = $item;
        }
        $___[] = $elts;
        return $___;
    })($a);
}



function difference($a, $b) {
    return (function($a) {
        $___ = [];
        $elts = [];
        foreach($a as $item) {
            $elts[0] = $item;
        }
        $___[] = $elts;
        return $___;
    })($a);
}



function difference($a, $b) {
    return (function($a) {
        $___ = [];
        $elts = [];
        foreach($a as $item) {
            $elts[0] = $item;
        }
        $___[] = $elts;
        return $___;
    })($a);
}



function make_set($itr) {
    PyCore::print("Making set...");
    return PyCore::set($itr);
}


PyCore::print(difference(new PyList([1, 2, 3]), new PyList([1, 2, 4])));

function difference($a, $b) {
    $_b = PyCore::set($b);
    return (function($a) {
        $___ = [];
        $elts = [];
        foreach($a as $item) {
            $elts[0] = $item;
        }
        $___[] = $elts;
        return $___;
    })($a);
}



function difference($a, $b) {
    $_b = PyCore::set($b);
    return PyCore::list(PyCore::filter(return !$_b->__contains__($item)

    }, $a));
}

def difference(a, b):
  return [item for item in a if item not in b]



def difference(a, b):
  return [item for item in a if item not in set(b)]



def difference(a, b):
  return [item for item in a if item not in make_set(b)]

def make_set(itr):
  print('Making set...')
  return set(itr)

print(difference([1, 2, 3], [1, 2, 4]))
# Making set...
# Making set...
# Making set...
# [3]



def difference(a, b):
  _b = set(b)
  return [item for item in a if item not in _b]



def difference(a, b):
  _b = set(b)
  return list(filter(lambda item: item not in _b, a))
  1. Fatal error: Cannot redeclare compact() on line 6
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function compact($lst) {
    return PyCore::list(PyCore::filter(null, $lst));
}


compact(new PyList([0, 1, false, 2, "", 3, "a", "s", 34]));
def compact(lst):
  return list(filter(None, lst))

compact([0, 1, False, 2, '', 3, 'a', 's', 34]) # [ 1, 2, 3, 'a', 's', 34 ]
  1. Fatal error: Can't use method return value in write context on line 12
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");
$defaultdict = PyCore::import('collections')->defaultdict;
$floor = PyCore::import('math')->floor;

function count_by($lst, $fn) {
    $count = $defaultdict($int);
    $__iter = PyCore::iter(PyCore::map($fn, $lst));
    while($current = PyCore::next($__iter)) {
        $val = $current;
        $countval->__setitem__($val, $__value) += 1;    
    }
    return PyCore::dict($count);
}


count_by(new PyList([6.1, 4.2, 6.3]), $floor);
count_by(new PyList(["one", "two", "three"]), $len);
from collections import defaultdict
from math import floor

def count_by(lst, fn = lambda x: x):
  count = defaultdict(int)
  for val in map(fn, lst):
    count[val] += 1
  return dict(count)

count_by([6.1, 4.2, 6.3], floor) # {6: 2, 4: 1}
count_by(['one', 'two', 'three'], len) # {3: 2, 5: 1}
  1. Fatal error: Uncaught PyError: ('min',) in /home/mrpzx/git/phpy/phpy-examples/30s/python-code/dict-getkey-vs-dictkey.php:14
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");
$a = new PyDict([
    "max" => 200,
]);
$b = new PyDict([
    "min" => 100,
    "max" => 250,
]);
$c = new PyDict([
    "min" => 50,
]);
$a->__getitem__("min") + $b->__getitem__("min") + $c->__getitem__("min");
$a->get("min", 0) + $b->get("min", 0) + $c->get("min", 0);
a = { 'max': 200 }
b = { 'min': 100, 'max': 250 }
c = { 'min': 50 }

a['min'] + b['min'] + c['min'] # throws KeyError
a.get('min', 0) + b.get('min', 0) + c.get('min', 0) # 150
  1. Warning: Undefined variable $int on line 6
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function digitize($n) {
    return PyCore::list(PyCore::map($int, PyCore::str($n)));
}


digitize(123);
def digitize(n):
  return list(map(int, str(n)))

digitize(123) # [1, 2, 3]
  1. Warning: Undefined variable $print on line 14
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function for_each($itr, $fn) {
    $__iter = PyCore::iter($itr);
    while($current = PyCore::next($__iter)) {
        $el = $current;
        $fn($el);    
    }
}


for_each(new PyList([1, 2, 3]), $print);
def for_each(itr, fn):
  for el in itr:
    fn(el)

for_each([1, 2, 3], print) # 1 2 3
  1. Fatal error: Uncaught TypeError: Unsupported operand types: PyList + PyList on line 6
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function have_same_contents($a, $b) {
    $__iter = PyCore::iter(PyCore::set($a + $b));
    while($current = PyCore::next($__iter)) {
        $v = $current;
        if ($a->count($v) != $b->count($v)) {
            return false;
        }
    
    }
    return true;
}


have_same_contents(new PyList([1, 2, 4]), new PyList([2, 4, 1]));
def have_same_contents(a, b):
  for v in set(a + b):
    if a.count(v) != b.count(v):
      return False
  return True

have_same_contents([1, 2, 4], [2, 4, 1]) # True
  1. Error: Unsupported Python Syntax, Line: 3, Type: GeneratorExp
Error: Unsupported Python Syntax, Line: 3, Type: GeneratorExp
def hex_to_rgb(hex):
  return tuple(int(hex[i:i+2], 16) for i in (0, 2, 4))

hex_to_rgb('FFA501') # (255, 165, 1)
  1. Parse error: syntax error, unexpected double-quoted string " ", expecting ":" on line 7
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");
$sub = PyCore::import('re')->sub;

function kebab($s) {
    return PyCore::str("-")->join($sub("(\\s|_|-)+", " ", $sub("[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+", return " " + $mo->group(0)->lower();

    }, $s))->split());
}


kebab("camelCase");
kebab("some text");
kebab("some-mixed_string With spaces_underscores-and-hyphens");
kebab("AllThe-small Things");
from re import sub

def kebab(s):
  return '-'.join(
    sub(r"(\s|_|-)+"," ",
    sub(r"[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+",
    lambda mo: ' ' + mo.group(0).lower(), s)).split())

kebab('camelCase') # 'camel-case'
kebab('some text') # 'some-text'
kebab('some-mixed_string With spaces_underscores-and-hyphens')
# 'some-mixed-string-with-spaces-underscores-and-hyphens'
kebab('AllThe-small Things') # 'all-the-small-things'
  1. Fatal error: Uncaught TypeError: Unsupported operand types: PyObject - int in /home/mrpzx/git/phpy/phpy-examples/30s/python-code/median.php:9
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function median($list) {
    $list->sort();
    $list_length = PyCore::len($list);
    if ($list_length % 2 == 0) {
        return $list->__getitem__(PyCore::int($list_length / 2) - 1) + $list->__getitem__(PyCore::int($list_length / 2)) / 2;
    }

    return PyCore::float($list->__getitem__(PyCore::int($list_length / 2)));
}


median(new PyList([1, 2, 3]));
median(new PyList([1, 2, 3, 4]));
def median(list):
  list.sort()
  list_length = len(list)
  if list_length % 2 == 0:
    return (list[int(list_length / 2) - 1] + list[int(list_length / 2)]) / 2
  return float(list[int(list_length / 2)])

median([1, 2, 3]) # 2.0
median([1, 2, 3, 4]) # 2.5
  1. Fatal error: Cannot redeclare append() (previously declared on line 20
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function append($n, $l) {
    $l->append($n);
    return $l;
}


append(0);
append(1);

function append($n, $l) {
    if ($l == null) {
        $l = new PyList([]);
    }

    $l->append($n);
    return $l;
}


append(0);
append(1);
def append(n, l = []):
  l.append(n)
  return l

append(0) # [0]
append(1) # [0, 1]



def append(n, l = None):
  if l is None:
    l = []
  l.append(n)
  return l

append(0) # [0]
append(1) # [1]
  1. Fatal error: Uncaught TypeError: Unsupported operand types: string * int in /home/mrpzx/git/phpy/phpy-examples/30s/python-code/n-times-string.php:6
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function n_times_string($s, $n) {
    return $s * $n;
}


n_times_string("py", 4);
def n_times_string(s, n):
  return (s * n)

n_times_string('py', 4) #'pypypypy'
  1. Fatal error: Uncaught TypeError: Unsupported operand types: PyObject / PyObject in /home/mrpzx/git/phpy/phpy-examples/30s/python-code/num-to-range.php:6
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function num_to_range($num, $inMin, $inMax, $outMin, $outMax) {
    return $outMin + PyCore::float($num - $inMin) / PyCore::float($inMax - $inMin) * $outMax - $outMin;
}


num_to_range(5, 0, 10, 0, 100);
def num_to_range(num, inMin, inMax, outMin, outMax):
  return outMin + (float(num - inMin) / float(inMax - inMin) * (outMax
                  - outMin))

num_to_range(5, 0, 10, 0, 100) # 50.0
  1. Fatal error: Uncaught Error: Call to a member function getitem() on string in /home/mrpzx/git/phpy/phpy-examples/30s/python-code/reverse.php:6
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function reverse($itr) {
    return $itr->__getitem__(PyCore::slice(null, null, -1));
}


reverse(new PyList([1, 2, 3]));
reverse("snippet");
def reverse(itr):
  return itr[::-1]

reverse([1, 2, 3]) # [3, 2, 1]
reverse('snippet') # 'teppins'
  1. Fatal error: Uncaught PyError: attempt to assign sequence of size 3 to extended slice of size 2 in /home/mrpzx/git/phpy/phpy-examples/30s/python-code/slice-assignment.php:31
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");
$nums = new PyList([1, 2, 3, 4, 5]);
$__value = new PyList([6]);
$nums->__setitem__(PyCore::slice(null, 1, null), $__value);
$__value = new PyList([7, 8]);
$nums->__setitem__(PyCore::slice(1, 3, null), $__value);
$__value = new PyList([9, 0]);
$nums->__setitem__(PyCore::slice(-2, null, null), $__value);
$nums = new PyList([1, 2, 3, 4, 5]);
$__value = new PyList([6, 7]);
$nums->__setitem__(PyCore::slice(1, 4, null), $__value);
$__value = new PyList([8, 9, 0]);
$nums->__setitem__(PyCore::slice(-1, null, null), $__value);
$__value = new PyList([]);
$nums->__setitem__(PyCore::slice(null, 1, null), $__value);
$nums = new PyList([1, 2, 3, 4, 5]);
$__value = new PyList([6, 7]);
$nums->__setitem__(PyCore::slice(2, 2, null), $__value);
$__value = new PyList([8, 9]);
$nums->__setitem__(PyCore::slice(7, null, null), $__value);
$__value = new PyList([0]);
$nums->__setitem__(PyCore::slice(null, 0, null), $__value);
$__value = new PyList([4, 2]);
$nums->__setitem__(PyCore::slice(null, null, null), $__value);
$nums = new PyList([1, 2, 3, 4, 5]);
$__value = new PyList([6, 7]);
$nums->__setitem__(PyCore::slice(2, 5, 2), $__value);
$__value = new PyList([6, 7, 8]);
$nums->__setitem__(PyCore::slice(2, 5, 2), $__value);
$__value = new PyList([9, 0]);
$nums->__setitem__(PyCore::slice(1, null, -1), $__value);
nums = [1, 2, 3, 4, 5]

nums[:1] = [6]        # [6, 2, 3, 4, 5]   (replace elements 0 through 1)
nums[1:3] = [7, 8]    # [6, 7, 8, 4, 5]   (replace elements 1 through 3)
nums[-2:] = [9, 0]    # [6, 7, 8, 9, 0]   (replace the last 2 elements)

nums = [1, 2, 3, 4, 5]

nums[1:4] = [6, 7]    # [1, 6, 7, 5]        (replace 3 elements with 2)
nums[-1:] = [8, 9, 0] # [1, 6, 7, 8, 9, 0]  (replace 1 element with 3)
nums[:1] = []         # [6, 7, 8, 9, 0]     (replace 1 element with 0)

nums = [1, 2, 3, 4, 5]

nums[2:2] = [6, 7]    # [1, 2, 6, 7, 3, 4, 5]   (insert 2 elements)
nums[7:] = [8, 9]     # [1, 2, 6, 7, 3, 4, 5, 8, 9] (append 2 elements)
nums[:0] = [0]        # [0, 1, 2, 6, 7, 3, 4, 5, 8, 9] (prepend 1 element)
nums[:] = [ 4, 2]     # [4, 2]         (replace whole list with a new one)

nums = [1, 2, 3, 4, 5]

nums[2:5:2] = [6, 7]  # [1, 2, 6, 4, 7] (replace every 2nd element, 2 through 5)
nums[2:5:2] = [6, 7, 8] # Throws a ValueError (can't replace 2 elements with 3)
nums[1::-1] = [9, 0]  # [0, 9, 6, 4, 7] (reverse replace, 1 through start)
  1. Fatal error: Uncaught Error: Call to a member function lower() on string in /home/mrpzx/git/phpy/phpy-examples/30s/python-code/slugify.php:7
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");
$re = PyCore::import('re');

function slugify($s) {
    $s = $s->lower()->strip();
    $s = $re->sub("[^\\w\\s-]", "", $s);
    $s = $re->sub("[\\s_-]+", "-", $s);
    $s = $re->sub("^-+|-+$", "", $s);
    return $s;
}


slugify("Hello World!");
import re

def slugify(s):
  s = s.lower().strip()
  s = re.sub(r'[^\w\s-]', '', s)
  s = re.sub(r'[\s_-]+', '-', s)
  s = re.sub(r'^-+|-+$', '', s)
  return s

slugify('Hello World!') # 'hello-world'
  1. Parse error: syntax error, unexpected token "return" on line 6
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function sort_dict_by_value($d, $reverse) {
    return PyCore::dict(PyCore::sorted($d->items(), key: return $x->__getitem__(1);

    }, reverse: $reverse));
}


$d = new PyDict([
    "one" => 1,
    "three" => 3,
    "five" => 5,
    "two" => 2,
    "four" => 4,
]);
sort_dict_by_value($d);
sort_dict_by_value($d, true);
def sort_dict_by_value(d, reverse = False):
  return dict(sorted(d.items(), key = lambda x: x[1], reverse = reverse))

d = {'one': 1, 'three': 3, 'five': 5, 'two': 2, 'four': 4}
sort_dict_by_value(d) # {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5}
sort_dict_by_value(d, True)
# {'five': 5, 'four': 4, 'three': 3, 'two': 2, 'one': 1}
  1. Fatal error: Uncaught Error: Call to a member function split() on string in /home/mrpzx/git/phpy/phpy-examples/30s/python-code/split-lines.php:6
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function split_lines($s) {
    return $s->split("\n");
}


split_lines("This\nis a\nmultiline\nstring.\n");
def split_lines(s):
  return s.split('\n')

split_lines('This\nis a\nmultiline\nstring.\n')
# ['This', 'is a', 'multiline', 'string.' , '']
  1. Fatal error: Uncaught TypeError: Unsupported operand types: PyStr * int in /home/mrpzx/git/phpy/phpy-examples/30s/python-code/to-roman-numeral.php:12
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function to_roman_numeral($num) {
    $lookup = new PyList([[1000, "M"], [900, "CM"], [500, "D"], [400, "CD"], [100, "C"], [90, "XC"], [50, "L"], [40, "XL"], [10, "X"], [9, "IX"], [5, "V"], [4, "IV"], [1, "I"]]);
    $res = "";
    $__iter = PyCore::iter($lookup);
    while($current = PyCore::next($__iter)) {
        [$n, $roman] = $current;
        [$d, $num] = PyCore::divmod($num, $n);
        $res += $roman * $d;    
    }
    return $res;
}


to_roman_numeral(3);
to_roman_numeral(11);
to_roman_numeral(1998);
def to_roman_numeral(num):
  lookup = [
    (1000, 'M'),
    (900, 'CM'),
    (500, 'D'),
    (400, 'CD'),
    (100, 'C'),
    (90, 'XC'),
    (50, 'L'),
    (40, 'XL'),
    (10, 'X'),
    (9, 'IX'),
    (5, 'V'),
    (4, 'IV'),
    (1, 'I'),
  ]
  res = ''
  for (n, roman) in lookup:
    (d, num) = divmod(num, n)
    res += roman * d
  return res

to_roman_numeral(3) # 'III'
to_roman_numeral(11) # 'XI'
to_roman_numeral(1998) # 'MCMXCVIII'
  1. Fatal error: Uncaught TypeError: Unsupported operand types: PyList + array in /home/mrpzx/git/phpy/phpy-examples/30s/python-code/union-by.php:15
<?php
$operator = PyCore::import("operator");
$builtins = PyCore::import("builtins");

function union_by($a, $b, $fn) {
    $_a = PyCore::set(PyCore::map($fn, $a));
    return PyCore::list(PyCore::set($a + (function($b) {
        $___ = [];
        $elts = [];
        foreach($b as $item) {
            $elts[0] = $item;
        }
        $___[] = $elts;
        return $___;
    })($b)));
}


$floor = PyCore::import('math')->floor;
union_by(new PyList([2.1]), new PyList([1.2, 2.3]), $floor);
def union_by(a, b, fn):
  _a = set(map(fn, a))
  return list(set(a + [item for item in b if fn(item) not in _a]))

from math import floor

union_by([2.1], [1.2, 2.3], floor) # [2.1, 1.2]

以上python代码来自 https://github.com/Chalarangelo/30-seconds-of-code/tree/master/content/snippets/python/s,相关提取、转换、测试代码如下

  • md.php
<?php

$files = glob('python-md/*.md');
array_map(function ($file) {
    preg_match_all('/```py([\s\S]+?)```/', file_get_contents($file), $matches);
    file_put_contents(substr($file, 0, -3) . '.py', implode("\n\n", $matches[1]));
}, $files);
  • py.php
<?php

$files = glob('python-code/*.py');
array_map(function ($file) {
    file_put_contents(substr($file, 0, -3) . '.php', convert(file_get_contents($file)));
}, $files);

function convert($code)
{
    return json_decode(request('https://swoole.com/py2php/convert.php', 'POST', ['code' => $code])[0])?->data?->code;
}

/**
 * http request
 * from swoole/ide-helper
 * @param string $url 
 * @param string $method 
 * @param mixed $data 
 * @param array $options 
 * @param null|array $headers 
 * @param null|array $cookies
 * @return array 
 */
function request(
    string $url,
    string $method = 'GET',
    $data = null,
    array $options = ['timeout' => 30],
    array $headers = null,
    array $cookies = null
): array {
    $ch = curl_init($url);
    if (empty($ch)) {
        throw new \Exception('failed to curl_init');
    }
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($method));
    if ($data) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }
    if ($headers) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }
    if ($cookies) {
        $cookie_str = '';
        foreach ($cookies as $k => $v) {
            $cookie_str .= "{$k}={$v}; ";
        }
        curl_setopt($ch, CURLOPT_COOKIE, $cookie_str);
    }
    if (isset($options['timeout'])) {
        if (is_float($options['timeout'])) {
            curl_setopt($ch, CURLOPT_TIMEOUT_MS, intval($options['timeout'] * 1000));
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, intval($options['timeout'] * 1000));
        } else {
            curl_setopt($ch, CURLOPT_TIMEOUT, intval($options['timeout']));
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, intval($options['timeout']));
        }
    }
    if (isset($options['connect_timeout'])) {
        if (is_float($options['connect_timeout'])) {
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, intval($options['connect_timeout'] * 1000));
        } else {
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, intval($options['connect_timeout']));
        }
    }
    if (isset($options['verify'])) {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 从证书中检查SSL加密算法是否存在
        // curl_setopt($ch, CURLOPT_SSLVERSION, 2);//设置SSL协议版本号
    }
    $body = curl_exec($ch);
    if ($body !== false) {
        return [$body, curl_getinfo($ch, CURLINFO_HTTP_CODE)];
    }
    throw new \Exception(curl_error($ch), curl_errno($ch));
}
  • test.php
<?php

$files = glob('python-code/*.php');

$i = 0;
$errs = [];
array_map(function ($file) use (&$i, &$errs) {
    $proc = proc_open('php ' . $file, [0 => STDIN, 1 => ['pipe', 'w'], 2 => ['redirect', 1]], $pipes);
    $stdout = stream_get_contents($pipes[1]);
    $status = proc_get_status($proc);
    proc_close($proc);

    if ($status['exitcode']) {
        $msg = explode("\n", trim($stdout))[0];
        if (!preg_match('/(.+?)in \/home.+?\s*(on line \d+)/', $msg, $match)) {
            $match = ['', $msg];
        }
        if (isset($errs[$match[1]])) {
            return;
        }
        $errs[$match[1]] = 0;
        echo (++$i) . '. ', $match[1], ' ', $match[2] ?? '', PHP_EOL;

        $pycode = file_get_contents(substr($file, 0, -4) . '.py');
        $phpcode = file_get_contents($file);
        echo <<<CODE
\```php
$phpcode
\```
CODE;
        echo PHP_EOL;
        echo <<<CODE
\```python
$pycode
\```
CODE;
        echo PHP_EOL;
    }
}, $files);
\```
@matyhtf
Copy link
Member

matyhtf commented Aug 29, 2024

正在尝试解决。

相当一部分的代码可能无法在 php 中很好地实现。

  1. 函数捕获的问题,例子 2 ,PHP 必须要显式传递,或者使用 global 变量,但是 global 不是正确的实现方式
  2. 函数重定义,PHP 不支持重定义,例子 14
  3. 运算符号重载,例如 PyList() + PyList ,PHP 不支持运算符重载
  4. Generator 语法,暂时无法支持
  5. 字符串方法,常量字符串会作为 PHP 的原生类型,需要转为 PyStr 才可以使用方法
  6. 类型符号,例如 int、tuple ,被转为 $int, $tuple ,Python 可以直接传递,而 PHP 里是不支持的,暂时不好解决

可以解决,并且已解决的问题:

  1. fstring 中的日期格式化
  2. 函数定义中的参数默认值

@matyhtf matyhtf pinned this issue Sep 6, 2024
@matyhtf matyhtf unpinned this issue Sep 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants