Управление математическим уравнением в Python

Я создал круговую панель просмотра с плавной прокруткой от последнего к первому при пролистывании влево и от первого до последнего при пролистывании вправо.

для этого добавьте последнюю страницу в начальной и первую страницу к последней: внутри addOnPageChangeListener: мы должны сделать некоторые вычисления, когда мы на 0 месте, то на onPageScrollStateChanged установить текущий элемент как последний пункт и наоборот.

Посмотрите код

public class ViewPagerCircular_new extends AppCompatActivity {
ViewPager viewPager;
ArrayList<String> str = new ArrayList<String>();
boolean chageImage = false;
int setPos;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.view_pager_normal);
    viewPager = (ViewPager) findViewById(R.id.vf_home_top_pager);
    str.add("6");         // added the last page to the frist
    str.add("1");        // First item to display in view pager
    str.add("2");
    str.add("3");
    str.add("4");
    str.add("5");
    str.add("6");     // last item to display in view pager
    str.add("1");      // added the first page to the last
    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    viewPager.setAdapter(adapter);
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()
    {

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
        {
            if (position == str.size() - 1)
            {
                chageImage = true;
                setPos = 1;
            } else if (position == 0)
            {
                chageImage = true;
                setPos = str.size() - 2;
            } else
            {
                chageImage = false;
            }
        }

        @Override
        public void onPageSelected(int position)
        {
        }

        @Override
        public void onPageScrollStateChanged(int state)
        {
            if (state == ViewPager.SCROLL_STATE_IDLE && chageImage)
            {
                viewPager.setCurrentItem(setPos, false);
            }
        }
    });
// display the 1st item as current item 
    viewPager.setCurrentItem(1);
}

// адаптер пейджера

public class ViewPagerAdapter extends FragmentStatePagerAdapter
{

    public ViewPagerAdapter(FragmentManager fm)
    {
        super(fm);
    }

    @Override
    public Fragment getItem(int position)
    {
        PagerFragment fragment = new PagerFragment();
        Bundle bundle = new Bundle();
        bundle.putString("pos", str.get(position));
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public int getCount()
    {
        return str.size();
    }

}

// фрагмент для отображения в адаптере

public class PagerFragment extends Fragment
{

    Bundle bundle;
    String pos;

    public PagerFragment()
    {
    }

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        bundle = getArguments();
        pos = bundle.getString("pos");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        TextView textView = new TextView(ViewPagerCircular_new.this);
        textView.setGravity(Gravity.CENTER);
        textView.setTextSize(25);
        textView.setText(pos);
        return textView;
    }

}

}

14
задан Jota 30 June 2015 в 23:07
поделиться

4 ответа

То, что вы хотите сделать, непросто. Некоторые уравнения довольно просто переставить (например, make b предмет a = b * c + d , то есть b = (ad) / c ), в то время как другие не столь очевидны (например, make x предметом y = x * x + 4 * x + 4 ), в то время как другие невозможны (особенно когда вы тригонометрически функции и другие сложности).

Как говорили другие люди, проверьте Sage. Он делает то, что вы хотите:

You can solve equations for one variable in terms of others:

sage: x, b, c = var('x b c')
sage: solve([x^2 + b*x + c == 0],x)
[x == -1/2*b - 1/2*sqrt(b^2 - 4*c), x == -1/2*b + 1/2*sqrt(b^2 - 4*c)]
4
ответ дан 1 December 2019 в 06:54
поделиться

Используя SymPy , ваш пример будет выглядеть примерно так:

>>> import sympy
>>> a,b,c,d,e = sympy.symbols('abcde')
>>> r = (b+c*d)/e
>>> l = a
>>> r = sympy.solve(l-r,d)
>>> l = d
>>> r
[(-b + a*e)/c]
>>> 

Кажется, он работает и для тригонометрических функций:

>>> l = a
>>> r = b*sympy.sin(c)
>>> sympy.solve(l-r,c)
[asin(a/b)]
>>> 

И поскольку вы работаете с графическим интерфейсом , вы (вероятно) захотите преобразовывать туда и обратно из строк в выражения:

>>> r = '(b+c*d)/e'
>>> sympy.sympify(r)
(b + c*d)/e
>>> sympy.sstr(_)
'(b + c*d)/e'
>>> 

или вы можете предпочесть отображать их как визуализированные LaTeX или MathML .

24
ответ дан 1 December 2019 в 06:54
поделиться

Если вы хотите сделать это прямо из коробки, не полагаясь на librairies, я думаю, что проблемы, которые вы обнаружите, не связаны с Python. Если вы хотите найти такие уравнения, вы должны описать эвристику, необходимую для решения этих уравнений.

Во-первых, вы должны представить свое уравнение. А как насчет разделения:

  • операндов:
    • символьные операнды (a, b)
    • числовые операнды (1,2)
  • операторы:
    • унарные операторы (-, триггерные функции)
    • бинарные операторы (+, -, *, /)

Унарные операторы, очевидно, будут включать один операнд, двоичные операторы будут заключать два.

А как насчет типов?

Я думаю, что все эти компоненты должны быть производными от одного общего типа выражения . И этот класс будет иметь метод getsymbols для быстрого поиска символов в ваших выражениях.

А затем различать унарные и бинарные операторы, добавить несколько базовых примитивов дополнения / переупорядочения ...

Что-то вроде:

class expression(object):
    def symbols(self):
        if not hasattr(self, '_symbols'):
            self._symbols = self._getsymbols()
        return self._symbols
    def _getsymbols(self):
        """
        return type: list of strings
        """
        raise NotImplementedError

class operand(expression): pass

class symbolicoperand(operand):
    def __init__(self, name):
        self.name = name
    def _getsymbols(self):
        return [self.name]
    def __str__(self):
        return self.name

class numericoperand(operand):
    def __init__(self, value):
        self.value = value
    def _getsymbols(self):
        return []
    def __str__(self):
        return str(self.value)

class operator(expression): pass

class binaryoperator(operator):
    def __init__(self, lop, rop):
        """
        @type lop, rop: expression
        """
        self.lop = lop
        self.rop = rop
    def _getsymbols(self):
        return self.lop._getsymbols() + self.rop._getsymbols()
    @staticmethod
    def complementop():
        """
        Return complement operator:
         op.complementop()(op(a,b), b) = a
        """
        raise NotImplementedError
    def reorder():
        """
        for op1(a,b) return op2(f(b),g(a)) such as op1(a,b) = op2(f(a),g(b))
        """
        raise NotImplementedError
    def _getstr(self):
        """
        string representing the operator alone
        """
        raise NotImplementedError
    def __str__(self):
        lop = str(self.lop)
        if isinstance(self.lop, operator):
            lop = '(%s)' % lop
        rop = str(self.rop)
        if isinstance(self.rop, operator):
            rop = '(%s)' % rop
        return '%s%s%s' % (lop, self._getstr(), rop)


class symetricoperator(binaryoperator): 
    def reorder(self):
        return self.__class__(self.rop, self.lop)

class asymetricoperator(binaryoperator):
    @staticmethod
    def _invert(operand):
        """
        div._invert(a) -> 1/a
        sub._invert(a) -> -a
        """
        raise NotImplementedError

    def reorder(self):
        return self.complementop()(self._invert(self.rop), self.lop)


class div(asymetricoperator):
    @staticmethod
    def _invert(operand):
        if isinstance(operand, div):
            return div(self.rop, self.lop)
        else:
            return div(numericoperand(1), operand)
    @staticmethod
    def complementop():
        return mul
    def _getstr(self):
        return '/'

class mul(symetricoperator):
    @staticmethod
    def complementop():
        return div
    def _getstr(self):
        return '*'

class add(symetricoperator):
    @staticmethod
    def complementop():
        return sub
    def _getstr(self):
        return '+'

class sub(asymetricoperator):
    @staticmethod
    def _invert(operand):
        if isinstance(operand, min):
            return operand.op
        else:
            return min(operand)
    @staticmethod
    def complementop():
        return add
    def _getstr(self):
        return '-'

class unaryoperator(operator):
    def __init__(self, op):
        """
        @type op: expression
        """
        self.op = op
    @staticmethod
    def complement(expression):
        raise NotImplementedError

    def _getsymbols(self):
        return self.op._getsymbols()

class min(unaryoperator):
    @staticmethod
    def complement(expression):
        if isinstance(expression, min):
            return expression.op
        else:
            return min(expression) 
    def __str__(self):
        return '-' + str(self.op)

Установив эту базовую структуру, вы сможете описать простую эвристику для решения очень простые уравнения. Просто подумайте о простых правилах, которым вы научились решать уравнения, и запишите их. Это должно сработать :)

А затем очень наивный решатель:

def solve(left, right, symbol):
    """
    @type left, right: expression
    @type symbol: string
    """
    if symbol not in left.symbols():
        if symbol not in right.symbols():
            raise ValueError('%s not in expressions' % symbol)
        left, right = right, left

    solved = False
    while not solved:
        if isinstance(left, operator):
            if isinstance(left, unaryoperator):
                complementor = left.complement
                right = complementor(right)
                left = complementor(left)
            elif isinstance(left, binaryoperator):
                if symbol in left.rop.symbols():
                    left = left.reorder()
                else:
                    right = left.complementop()(right, left.rop)
                    left = left.lop
        elif isinstance(left, operand): 
            assert isinstance(left, symbolicoperand)
            assert symbol==left.name
            solved = True

    print symbol,'=',right

a,b,c,d,e = map(symbolicoperand, 'abcde')

solve(a, div(add(b,mul(c,d)),e), 'd') # d = ((a*e)-b)/c
solve(numericoperand(1), min(min(a)), 'a') # a = 1
6
ответ дан 1 December 2019 в 06:54
поделиться

Sage поддерживает символьную математику. Вы можете просто использовать некоторые из встроенных функций для управления уравнениями:

http://sagemath.org/

2
ответ дан 1 December 2019 в 06:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: