i'm using the api from leaguepedia to receive the informations.
So I have this code to show how many times a champion was picked in a tournament, its working fine, but
right now im trying to show the winrate and i'm having problems,
for example :
Syndra picked 4 Times - Won 3 times - winrate = 75%, thats the result i expect;
Gragas picked 3 Times - Won 3 times - winrate = 100%, thats the result i expect;
what im recieving is :
Syndra picked 4 Times - Won 1 time - winrate = 25%
Gragas picked 3 Times - Won 1 time - winrate = 33,33% , victory is showing 1 for every champion (image)
i know that my problem might be on the "switch / case", but i don't know how to fix
so how can i fix my code to show the properly win rate.
thanks
thats my code
<?php
// $Result is a CURL coming from leaguepedia api
$result = json_decode($file_contents);
$heroPicks = [];
$heroVictory = [];
// Double foreach to access the values from leaguepedia api
foreach ($result as $d) {
foreach ($d as $data) {
//$data->title->Team1Picks and
// $data->title->Team2Picks is coming from leaguepedia api
//as a string separated by "," Ex:("Gragas,Shen,Maokai,etc")
// So i need to explode and merge to an array to count.
$picks1 = explode(",", $data->title->Team1Picks);
$picks2 = explode(",", $data->title->Team2Picks);
$picks = array_merge($picks1, $picks2);
// this switch is to check if
// $data->title->Winner == 1 , it means that
// $picks1 won the game else == 2 $picks2
// won the game ($data->title->Winner is coming from api aswell)
switch ($data->title->Winner) {
case 1:
$w = $picks1;
break;
case 2:
$w = $picks2;
break;
}
//foreach to count the times a champion was picked
foreach ($picks as $pick) {
$pick = trim($pick);
if (!array_key_exists($pick, $heroPicks)) {
$heroPicks[$pick] = 0;
}
$heroPicks[$pick] += 1;
}
//foreach to count how many times a champion won a game
foreach ($w as $victory) {
$victory = trim($victory);
if (!array_key_exists($victory, $heroVictory)) {
$heroVictory[$victory] = 0;
}
$heroVictory[$victory] += 1;
}
}
}
//sorting the arrays
uasort(
$heroPicks,
function ($a, $b) {
return $a - $b;
}
);
uasort(
$heroVictory,
function ($c, $d) {
return $c - $d;
}
);
$heroPicks = array_reverse($heroPicks);
$heroVictory = array_reverse($heroVictory);
//foreach to show the results
echo "Best picks:" . PHP_EOL . "<br />";
foreach ($heroPicks as $heroName => $pickCount) {
foreach ($heroVictory as $heroVictoryName => $totalVictory) {
$total = ($totalVictory * 100) / $pickCount;
}
echo $heroName . " - " . $pickCount . PHP_EOL . " - Victorys = " . $totalVictory . " -- winrate :" . $total . "%" . "<br />";
}
?>
the $result variable for #bassxzero
The outer foreach will loop through all of your heroes that were picked. This is what you want.
The inner foreach is looping through all of your heroes' victories, regardless of the hero the outer loop is currently processing. All the victories are set to 1 because that is how many victories the last hero in your victory array has. This is not what you want.
You don't want a second inner foreach. You just want to lookup the victory stats for the hero currently being processed by the outer foreach.
foreach ($heroPicks as $heroName => $pickCount) {
$totalVictory = $heroVictory[$heroName] ?? 0;
$total = ($totalVictory * 100) / $pickCount;
echo $heroName . " - " . $pickCount . PHP_EOL . " - Victorys = " . $totalVictory . " -- winrate :" . $total . "%" . "<br />";
}
Related
I am working on a "boxing records" database for a school project. The loop retrieves records from a SQL statement. I want to add a "VS" string of text between every other two lines in order to show records outputted somewhat like this.
Upcoming Fights
Sergey Kovalev (28-0-25)
VS
Jean Pascal (30-3-17)
Another Boxer (123-0-5)
VS
Some Boxer (123-3-1)
However, my current loop outputs like this
Sergey Kovalev (28-0-25)
VS
Jean Pascal (30-3-17)
VS
Another Boxer (123-3-1)
VS
Some Other Boxer (123-3-1)
VS
The loop I currently have is the following
foreach($records as $record) {
$i = 0;
echo $record['name'] . " (" . $record['wins'] . "-" . $record['losses'] . "-" . $record['kos'] . ")" . "<br>";
$i=$i*2;
if($i%2 == 0)
{
echo "VS <br/>";
}
else{
echo "<br />";
}
I know I could probably change the SQL in order to display two fighters in the same row, and then append "vs" on the echo, but I thought that just modifying the for loop would work by using a variable counter $i. I thought it would be pretty easy to make the "VS" appear between every two rows but im missing something in my logic.
You need to increment value of $i by one rather than multiplying it by 2 and initialize $i outside foreach loop.
$i = 0; // Initialize counter here
foreach($records as $record) {
echo $record['name'] . " (" . $record['wins'] . "-" . $record['losses'] . "-" . $record['kos'] . ")" . "<br>";
if($i%2 == 0)
{
echo "VS <br/>";
}
else
{
echo "<br />";
}
$i++; // Increment counter here
}
For a surface calculation I am searching for the following solution.
I have a size of the surface like 60m², for this square I have 2 kind of
materials sizes. Material size of 2m² and 4m². The challenge for me now is
to calculate the needed materials efficiently as possible and keep a rest
of the material to the minimum.
So, filling a surface of 60m² with most as possible with 4m² materials and fill it up with 2m2 to keep material to the minimum.
It's simple. With this method, you can use any number and any size of materials.
Store your materials into an array. Loop through on that array, make the calculations, and store the "rest" in another variable. If at the end there will be some rest, then add 1 more from the last item.
$materials = array(2,4,8);
$surface = 63;
rsort($materials);
$rest = $surface;
$isFinished = false;
$data = array();
foreach ($materials as $material) {
$result = $rest / $material;
if ($result >= 1) {
$data[$material] = floor($result);
$rest -= $material * floor($result);
}
}
if ($rest > 0) {
$data[end($materials)]++;
}
echo "For a " . $surface . " you need the following materials: <br />";
foreach ($data as $key => $val) {
echo "Material " . $key . " * " . $val ."<br />";
}
Output is:
For a 63 you need the following materials:
Material 8 * 7
Material 4 * 1
Material 2 * 2
assuming you are using PHP
This will be a start to find the material with minimum rest.
function getMinRest($surface, $num1, $num2){
$rest1 = $surface % $num1;
$rest2 = $surface % $num2;
return $rest2 <= $rest1 ? $num2:$num1;
}
Im trying to get out an average value from a vote function.
<?php
$file = file("textfile.txt");
$textfil = file_get_contents("textfile.txt");
$textfill = str_split($textfil);
echo "Number of votes: " . count($textfill) . "<br>";
$sum = 0;
foreach ($textfill as $vote) {
$sum = $sum + intval($vote);
}
echo "Average: " . $sum;
?>
Simple by substitute (+) with a (/), and even tried a (%). But still getting error message.
Would appreciate alot if anyone could help me out and tell me what im doing wrong.
/thanks
Edit
Sidenote: Please read an explanation under "First answer given" further down below.
This version will take into account any blank lines in a file, if the content looks like:
1
2
3
// <- blank line
Sidenote: Please provide a sample of your text file. A comment has already been given to that effect.
PHP
<?php
// first line not required
// $file = file("textfile.txt");
$textfil = file_get_contents("textfile.txt");
$textfill = array_filter(array_map("trim", file("textfile.txt")), "strlen");
echo "Number of votes: " . count($textfill) . "<br>";
$sum = 0;
foreach ($textfill as $vote) {
$sum += intval($vote);
}
$avg = $sum / count($textfill);
echo "Average: " . $avg;
?>
First answer given
Using the following in a text file: (since no example of file content was given)
5
5
5
IMPORTANT NOTE: There should not be a carriage return after the last entry.
produced
Number of votes: 5
Average: 3
which is false, since there are 3 entries in the text file.
explode() should be used, and not str_split()
The following using the same text file produced:
Number of votes: 3
Average: 5
which is correct. In simple mathematics, averages are done by adding all numbers then dividing them by how many numbers there are.
In this case it's 3 numbers (all 5's) added equals 15, divided by 3 is 5.
Sidenote: The first line is not required $file = file("textfile2.txt");
<?php
// first line not required
// $file = file("textfile.txt");
$textfil = file_get_contents("textfile.txt");
$textfill = explode("\n", $textfil);
echo "Number of votes: " . count($textfill) . "<br>";
$sum = 0;
foreach ($textfill as $vote) {
$sum += intval($vote);
}
$avg = $sum / count($textfill);
echo "Average: " . $avg;
?>
Footnotes:
If the average comes out to 8.33333 and you would like it to be rounded off to 8, use:
echo "Average: " . floor($avg);
If the average comes out to 8.33333 and would like it to be as 9 you would use:
echo "Average: " . ceil($avg);
ceil() function
floor() function
You may be mixing in stuff that can't be divided, like text, etc. I don't know what your text file looks like. intval may be having a problem with arrays. You may try:
foreach ($textfill as $vote) {
if(is_int($vote) {
$sum += $vote;
}
}
echo "Average: " . $sum;
Lower school math says:
foreach ($textfill as $vote) {
$sum += intval($vote);
}
$avg = $sum / count($textfill);
The average value is calculated by divide the sum with the number of votes. This line will print the average value:
echo "Average: " . $sum/count($textfill);
I am using below PHP function in Behat Mink to check the Email column values are in ascending or descending order.But the problem is its always fails.I just want to check if the subject or From of Email column in all rows are in ascending and descending order.Is there are any other way to do this?
public function ValidateColumnSorting($Column, $order) {
$nodes = // Logic goes to retrieve all rows subject or from column value
if (strcasecmp($order, "asc") == 0)
{
for ($i = 1; $i < $sizeof($nodes); $i++)
{
if (strcasecmp($nodes[$i], $nodes[$i - 1]) >= 0)
{
print_r("Row " . $i - 1 . " val is " . $nodes[$i - 1]);
}
else if (strcasecmp($nodes[$i], $nodes[$i - 1]) < 0)
{
throw new Exception($Column . " column ascending sort order failed.".$nodes[$i] . " is less than " . $nodes[$i - 1]);
}
}
}
else
{
for ($i = 1; $i < $sizeof($nodes); $i++)
{
print_r($Column . " column row " . $i . " value is " . $nodes[$i]);
if (strcasecmp($nodes[$i], (string) $nodes[$i - 1]) <= 0) {
print_r($Column . " of Email is same");
} else if (strcasecmp($nodes[$i], $nodes[$i - 1]) > 0) {
throw new Exception($Column . " column descending sort order failed." . $nodes[$i] . " is greater than " . $nodes[$i - 1]);
}
}
}
}
Instead of checking for its order, you can directly sort it in ascending or descending order.
Pass subject or email array to sort() function
$fruits = array("lemon", "orange", "banana", "apple");
sort($fruits);
It will return the sorted array
fruits[0] = apple
fruits[1] = banana
fruits[2] = lemon
fruits[3] = orange
You don't need to do it manually.
Read more here http://in2.php.net/sort
Without thinking if there is a more Behat appropriate way of validating the order of elements, your code would probably fail due to $sizeof($nodes), try sizeof($nodes) instead.
In Behat, the approach I would take would be to create a generic step definition which could be re-used elsewhere...
Then I should see the "css_to_some_elements" ordered as:
| apple |
| banana |
| lemon |
I am working on website that suppose to compare products. So I have reached to this following array
Array ( [iPhone 4 8GB Black] => 319 [iPhone 4S] => 449 [iphone 5] => 529 )
the key of the array is product name and the value of the array is the price. now i want to translate this array into statements like
iphone 4 8GB Black is cheapest!
iPhone 48GB Black is £130(calculation:449-319) cheaper than iphone 4S.
iPhone 48GB Black is £210(calculation:529-319) cheaper than iphone 5.
iPhone 4S is £80(calculation:529-449) cheaper than iphone 5.
iphone 5 is most expensive product from your chosen list.
Please help me on how to output those statements from an array. Your suggestion to do something else with this array in-terms of comparing would also be great. Thank you.
First, you have to sort your array with asort (in order to keep the association between your index and your values, and sort on values).
asort($yourArray);
Then, as your array is sorted, you can isolate price and names.
$names = array_keys($yourArray);
$prices = array_values($yourArray);
At this point you have 2 numerical indexed array containing your label and your prices and these 2 arrays are synchronized.
Finally, you just have to loop from 0 to the length of your array (one of them, its the same size) and made your process:
for($i = 0 ; $i < count($names) ; $i++)
{
if ($i == 0)
{
// First product -> cheapest
echo "The product " . $names[$i] . " is cheapest";
}
else if ($i == (count($names) - 1))
{
// Last product, the most expensive
echo "The product " . $names[$i] . " is the most expensive product of the list";
}
else
{
// calculate the diff between current product and first product
$diff = $price[$i] - $price[0];
echo "The product " . $names[$i] . " is " . $diff . " more expensive than " . $names[0];
}
}
This example make all comparision to the first product.
If you need all combination, it is a little more complexe, you have to make a double loop:
// Hard print the first product
echo "The product " . $names[0] . " is the cheapest";
// Make all possible comparisions
for($j = 0 ; $j < (count($names) - 1) ; $j++)
{
for($i = ($j+1) ; $i < count($names) ; $i++)
{
// calculate the diff between current product and first product
$diff = $price[$i] - $price[$j];
echo "The product " . $names[$i] . " is " . $diff . " more expensive than " . $names[$j];
}
}
// Hard print the last product
echo "The product " . $name[count($names) - 1] . " is the more expensive";