ViCalc 4.0 [Release] – Open-Source Zehnfinger-Taschenrechner mit Rechenverlauf in Python

Du hast eine Idee für ein Projekt?
Antworten
Kudaschov
User
Beiträge: 2
Registriert: Sonntag 24. August 2025, 08:27

Hallo zusammen,

ich möchte Euch heute die neue Version meines Projekts ViCalc 4.0 vorstellen.
ViCalc ist ein Taschenrechner für die Tastaturbedienung (Zehnfingerprinzip) mit Rechenverlauf, geschrieben in Python 3 und unter einer Open-Source MIT-Lizenz veröffentlicht.

Die erste Version von ViCalc erschien bereits 2003 – und nach vielen Jahren Weiterentwicklung ist nun Version 4.0 verfügbar.

Bedienung
ViCalc ist in erster Linie für Tastatur-Nutzer optimiert, funktioniert aber selbstverständlich auch mit der Maus, falls jemand lieber so arbeitet.

Zielgruppe
Besonders praktisch ist ViCalc für Softwareentwickler, die beim Programmieren mathematische Modelle kodieren und dafür einen schnellen, schlanken und flexiblen Rechner brauchen.

Mitmachen
👉 Source-Code und Download: https://github.com/Kudaschov/ViCalc
👉 Feedback, Issues oder Pull Requests sind jederzeit willkommen!

Vielleicht ist ViCalc auch für einige von euch ein nützliches Tool im Alltag. Ich freue mich über Rückmeldungen, Verbesserungsvorschläge oder einfach euer Testen.

Viele Grüße
Vitali Kudaschov

Bild
Sirius3
User
Beiträge: 18290
Registriert: Sonntag 21. Oktober 2012, 17:20

In Python werden logische Einheiten in Module zusammengefasst, z.B. alle Mathematischen Funktionen in einem Modul. Dabei kann man sich viel Code sparen, wenn man die Gemeinsamkeiten in einer Funktion abstrahiert.

Code: Alles auswählen

import math
from functools import singledispatchmethod
from .CalcExpression import CalcExpression
from .FloatCellValue import FloatCellValue
from .ResultCellValue import ResultCellValue
from. StringCellValue import StringCellValue

class UnaryExpression(CalcExpression):
    def protocol_result(self, result, column_number):
        ResultCellValue(result, self.row, column_number)        

    @singledispatchmethod
    def protocol(self, arg, column_number):
        """
        Generic report method.
        """
        raise NotImplementedError(f"Reporting not implemented for type {type(arg)}")
    
    @protocol.register(str)
    def _(self, arg: str, column_number: int):
        StringCellValue(arg, self.row, column_number)

    @protocol.register(float)
    def _(self, arg: float, column_number: int):
        FloatCellValue(arg, self.row, column_number)

    def calculate(self, number: float):
        result = self.FUNCTION(number)
        self.insert_scroll_table()
        self.protocol(self.NAME, 0)
        self.protocol(number, 1)
        self.protocol("=", 2)
        self.protocol_result(result, 3)
        return result

class PowExpression(UnaryExpression):
    def calculate(self, number: float):
        result = self.FUNCTION(number)
        self.insert_scroll_table()
        self.protocol(number, 1)
        self.protocol(self.NAME + " =", 1)
        self.protocol_result(result, 2)
        return result

class TrigExpression(UnaryExpression):
    def __init__(self, tableWidget, angle_unit:AngleUnit):
        super().__init__(tableWidget)
        self.angle_unit = angle_unit

    def calculate(self, number: float):
        result = self.FUNCTION(self.angle_unit.to_rad(number))
        self.insert_scroll_table()
        self.protocol(self.NAME, 0)
        self.protocol(number, 1)
        self.protocol(self.angle_unit.angle_symbol() + " =", 2)
        self.protocol_result(result, 3)
        return result

class ArcTrigExpression(UnaryExpression):
    def __init__(self, tableWidget, angle_unit:AngleUnit):
        super().__init__(tableWidget)
        self.angle_unit = angle_unit

    def calculate(self, number: float):
        result = self.angle_unit.from_rad(self.FUNCTION(number))
        self.insert_scroll_table()
        self.protocol(self.NAME, 0)
        self.protocol(number, 1)
        self.protocol("=", 2)
        self.protocol_result(result, 3)
        self.protocol(self.angle_unit.angle_symbol(), 4)
        return result

class ArcCosExpression(ArcTrigExpression):
    NAME = "arccos"
    FUNCTION = math.acos

class ArcSinExpression(ArcTrigExpression):
    NAME = "arcsin"
    FUNCTION = math.asin

class ArcTanExpression(ArcTrigExpression):
    NAME = "arctan"
    FUNCTION = math.atan

class ArcoshExpression(UnaryExpression):
    NAME = "arcosh"
    FUNCTION = math.acosh

class ArsinhExpression(UnaryExpression):
    NAME = "arsinh"
    FUNCTION = math.asinh

class ArtanhExpression(UnaryExpression):
    NAME = "artanh"
    FUNCTION = math.atanh

class CosExpression(TrigExpression):
    NAME = "cos"
    FUNCTION = math.cos

class CoshExpression(UnaryExpression):
    NAME = "cosh"
    FUNCTION = math.cosh

class CubeExpression(PowExpression):
    NAME = "³"
    FUNCTION = lambda number: number ** 3

class CubeRootExpression(UnaryExpression):
    NAME = "³√"
    FUNCTION = lambda number: number ** (1 / 3)

class EPowerXExpression(UnaryExpression):
    NAME = "e^"
    FUNCTION = math.exp

class FactorialExpression(PowExpression):
    NAME = "!"
    FUNCTION = lambda number: math.factorial(int(number))

class FourthPowerExpression(PowExpression):
    NAME = "⁴"
    FUNCTION = lambda number: number ** 4

class FourthRootExpression(UnaryExpression):
    NAME = "⁴√"
    FUNCTION = lambda number: number ** (1 / 4)

class LnExpression(UnaryExpression):
    NAME = "ln"
    FUNCTION = math.log

class LogExpression(UnaryExpression):
    NAME = "log"
    FUNCTION = math.log10

class SinExpression(TrigExpression):
    NAME = "sin"
    FUNCTION = math.sin

class SinhExpression(UnaryExpression):
    NAME = "sinh"
    FUNCTION = math.sinh

class SqrtExpression(UnaryExpression):
    NAME = "√"
    FUNCTION = math.sqrt

class TanExpression(TrigExpression):
    NAME = "tan"
    FUNCTION = math.tan

class TanhExpression(UnaryExpression):
    NAME = "tanh"
    FUNCTION = math.tanh

class TenPowerXExpression(UnaryExpression):
    NAME = "10^"
    FUNCTION = lambda number: 10 ** number
Auch an anderen Stellen gibt es noch sehr viel kopierten Code.
Die größte Baustelle ist aber die AppGlobal-Klasse. In gut strukturierten Programmen darf es keine globalen Variablen geben. Das umzubauen bedeutet aber deutlich mehr Aufwand.
Kudaschov
User
Beiträge: 2
Registriert: Sonntag 24. August 2025, 08:27

Hallo Sirius3,

Vielen Dank für die Info, ich werde es berücksichtigen.
Davor war ViCalc in c# .net WinForms geschrieben, es gibt noch nicht viel Erfahrung in Python.

Viele Grüße,
Vitali Kudaschov.
Antworten