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

Bug on calculating % #163

Open
tarcisiosluna opened this issue Mar 29, 2024 · 3 comments
Open

Bug on calculating % #163

tarcisiosluna opened this issue Mar 29, 2024 · 3 comments

Comments

@tarcisiosluna
Copy link

Describe the bug
Little background, I'm located in Brazil and the decimal separator here is the comma (,). While I'm trying to do some math with % I think I've encountered a bug. I have Alfred's calculator set to use comma as decimal separator as well as the Calculate Anything workflow.

To Reproduce
Steps to reproduce the behavior:

  1. Open Alfred '...'
  2. Type '10,5+5%'
  3. See error "Search Google for..."

Expected behavior
There should be the result of the calculations which should be 11,025

Debug Output
[12:40:44.428 AM] Logging Started...
[12:40:46.228 AM] Calculate Anything[Script Filter] Queuing argument '0,5+5%'
[12:40:46.295 AM] Calculate Anything[Script Filter] Script with argv '(null)' finished
[12:40:46.300 AM] Calculate Anything[Script Filter] {"items":[]}

System information:

  • OS: Mac OS 14.4.1
  • Alfred Version 5.5
  • PHP Version - v8.3.4

Additional context
With comma as the decimal separator, if I try "10.5+5%" I get "110.25". So my only workaround is to set period as the decimal separate value.
SCR-20240329-bqbg
SCR-20240329-bqdw
SCR-20240329-bqjt

@tarcisiosluna
Copy link
Author

tarcisiosluna commented Mar 30, 2024

So, I took a stab at trying to fix it and I noticed that the regex in the shouldProcess method of the percentage.php file doesn't consider the input decimal separator picked by the user.

To test my hypothesis I updated the regex to consider the , as the decimal separator and it worked. So I went to to implementing the following changes:

class Percentage extends CalculateAnything implements CalculatorInterface
{
private $query;
private $stop_words;
private $keywords;
private $lang;
private $parsed;
private $decimal_separator;

/**
 * Construct
 */
public function __construct($query)
{
    $this->query = $query;
    $this->keywords = $this->getKeywords('percentage');
    $this->stop_words = $this->getStopWords('percentage');
    $this->lang = $this->getTranslation('percentage');
    $this->decimal_separator = $this->getSetting('decimal_separator', 'dot');
}


/**
 * shouldProcess
 *
 * @param string $query
 * @param integer $strlenght
 * @return bool
 */
public function shouldProcess(int $strlenght = 0)
{
    $query = trim($this->query);
    if ($strlenght < 3 || !strpos($query, '%')) {
        return false;
    }

    $stopwords = ['+', '-', '%'];
    $stopwords = array_merge($stopwords, $this->stop_words);
    $stopwords = implode('|', $stopwords);
    $stopwords = $this->escapeKeywords($stopwords);
    $stopwords = '(' . $stopwords . ')';

    $keys = $this->keywords;
    foreach ($keys as $k => $value) {
        if (is_array($value)) {
            continue;
        }
        $query = str_replace($k, $value, trim($query));
    }

    $decimalSeparator = $this->decimal_separator === 'dot' ? '.' : ',';
    $regexToCheck = '/^(\d*\\' . $decimalSeparator . '?\d*%?)\s?' . $stopwords . '\s?(\d*\\' . $decimalSeparator . '?\d*%?)/i';
    
    preg_match($regexToCheck, $query, $matches);

    if (empty($matches)) {
        return false;
    }

    $matches = array_filter($matches);
    if (count($matches) < 4) {
        return false;
    }
    $this->parsed = $matches;
    return true;
}

...

That seemed to have fixed the issue with the input, but the output still shows with the '.'. I think that's because the call to the cleanUp method. I can take a look at that too and submit a PR with the fixes.

Would you be so kind as to tell me if I'm heading the right direction?

Much appreciated

@tarcisiosluna
Copy link
Author

So I noticed that change the output format fix the last issue I had. I also noticed that the other two ways to calculate % are broken ("30,5% of 100" and "10,5 % 100"). I will take a look at those two as well

@tarcisiosluna
Copy link
Author

Ok, so adding the same regex cleanup treatment on percentageOf() seemed to have fixed the issue:

private function percentageOf()
{
$decimalSeparator = $this->decimal_separator === 'dot' ? '.' : ',';
$query = $this->query;
$query = preg_replace('/[^0-9' . $decimalSeparator . '%]/', ' ', $query);
$query = preg_replace('!\s+!', ' ', $query);
$data = explode(' ', $query);

    if (count($data) < 2) {
        return false;
    }
    $percent = $this->cleanupNumber($data[0]);
    $amount = $this->cleanupNumber($data[1]);

    return $this->formatNumber(($percent / 100) * $amount);
}

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

1 participant