Я создал круговую панель просмотра с плавной прокруткой от последнего к первому при пролистывании влево и от первого до последнего при пролистывании вправо.
для этого добавьте последнюю страницу в начальной и первую страницу к последней: внутри 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;
}
}
}
То, что вы хотите сделать, непросто. Некоторые уравнения довольно просто переставить (например, 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)]
Используя 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 .
Если вы хотите сделать это прямо из коробки, не полагаясь на librairies, я думаю, что проблемы, которые вы обнаружите, не связаны с Python. Если вы хотите найти такие уравнения, вы должны описать эвристику, необходимую для решения этих уравнений.
Во-первых, вы должны представить свое уравнение. А как насчет разделения:
Унарные операторы, очевидно, будут включать один операнд, двоичные операторы будут заключать два.
А как насчет типов?
Я думаю, что все эти компоненты должны быть производными от одного общего типа выражения
.
И этот класс будет иметь метод 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
Sage поддерживает символьную математику. Вы можете просто использовать некоторые из встроенных функций для управления уравнениями: