Square Rounding Error (Banker's Rounding) - square-connect

I'm getting an error from square that says
{"errors": [{"code": "BAD_REQUEST","detail": "The total of the requested payments does not match the total of the sale order.","category": "INVALID_REQUEST_ERROR"}]}
The item is 3.00, the tax is 9.5% and our app fee is 3%.
On my end I send over
3.00
+ 0.29 (0.095 * 3.00 = 28.5 rounded up)
+ 0.09
______
3.38
I can clearly see that this is the amount I'm sending in the request and it works if the item is priced at 2.99 or 3.01. When Square responds to the create order it returns $0.28 as the tax amount, which is not Banker's rounding. In this situation is best for me to assume that Square will not fix this error and I should round down taxes?
RESPONSE from order endpoint:
{"order": {"id": "gMTUBc5FrYvLzkoNv6xOYfkLtkUZY","location_id": "RE7KBN4EGW4KT","line_items": [{"uid": "Z3mT3QHmkk4SPCkbrSW5MB","catalog_object_id": "NN5CHF66YK6MUGXG3BNWF6X5","quantity": "1","name": "Steamer","variation_name": "Regular","base_price_money": {"amount": 300,"currency": "USD"},"taxes": [{"uid": "rQurMfiksaO3xTaMqWdb1C","catalog_object_id": "YSI7WUNXGGSJRQEQ4QEQYK5G","name": "Sales Tax","percentage": "9.5","type": "ADDITIVE","applied_money": {"amount": 28,"currency": "USD"},"scope": "LINE_ITEM"}],"gross_sales_money": {"amount": 300,"currency": "USD"},"total_tax_money": {"amount": 28,"currency": "USD"},"total_discount_money": {"amount": 0,"currency": "USD"},"total_money": {"amount": 328,"currency": "USD"},"variation_total_price_money": {"amount": 300,"currency": "USD"},"applied_taxes": [{"uid": "rQurMfiksaO3xTaMqWdb1C","tax_uid": "rQurMfiksaO3xTaMqWdb1C","applied_money": {"amount": 28,"currency": "USD"}}]}],"taxes": [{"uid": "rQurMfiksaO3xTaMqWdb1C","catalog_object_id": "YSI7WUNXGGSJRQEQ4QEQYK5G","name": "Sales Tax","percentage": "9.5","type": "ADDITIVE","applied_money": {"amount": 28,"currency": "USD"},"scope": "LINE_ITEM"}],"fulfillments": [{"uid": "jJtsXtwaWfjJBIpbe7wkk","type": "PICKUP","state": "PROPOSED","pickup_details": {"pickup_at": "2020-06-14T20:58:09.257Z","recipient": {"display_name": "Table: #1"}}}],"created_at": "2020-06-14T20:43:09.731Z","updated_at": "2020-06-14T20:43:09.731Z","state": "OPEN","version": 1,"total_tax_money": {"amount": 28,"currency": "USD"},"total_discount_money": {"amount": 0,"currency": "USD"},"total_tip_money": {"amount": 0,"currency": "USD"},"total_money": {"amount": 337,"currency": "USD"},"service_charges": [{"uid": "2lD47tU2idwjyOpydkfrtB","name": "Service Fee","amount_money": {"amount": 9,"currency": "USD"},"applied_money": {"amount": 9,"currency": "USD"},"calculation_phase": "SUBTOTAL_PHASE","taxable": false,"total_money": {"amount": 9,"currency": "USD"},"total_tax_money": {"amount": 0,"currency": "USD"}}],"total_service_charge_money": {"amount": 9,"currency": "USD"},"net_amounts": {"total_money": {"amount": 337,"currency": "USD"},"tax_money": {"amount": 28,"currency": "USD"},"discount_money": {"amount": 0,"currency": "USD"},"tip_money": {"amount": 0,"currency": "USD"},"service_charge_money": {"amount": 9,"currency": "USD"}},"source": {"name": "Table: #1"}}}

Banker's rounding only applies when the ending number is equidistant between two numbers (in this case, .05).
In your example:
3.00
+ 0.28 (0.095 * 3.00 = 0.285 which according to Banker's rounding, rounds to the closest even number, so this would be 0.28)
+ 0.09
_______
3.37
In your other example (3.01):
3.01
+ 0.29 (0.095 * 3.01 = 0.28595 which would round to 0.286 and then use normal rounding, since it doesn't end in 5, to be 0.29)
+ 0.09
______
3.39

Related

Csv probleme in Ruby

i'am working on a project and i have to deal with disgusting type of data into a csv file.
I know how to put the data into a variable but i can't delete [" "],[" "],from empty lines (not empty at all because there is space into it )
i have tried many things such as gsub with a regex, comparaison string etc etc but nothing works . It's maybe a question of data length because it has to go throught 38000 lines.
can you try it ?
ID ANN;Titre;[Vide];[Vide];ID PRO;ID CLI;Type ann;Prix;[0];[0.0];[0];ID Marque;Cat Véhicule;Cylindrée;Modèle;Année;Année 2;Date;Actif;[Vide];Etat;[0];[0];Achat;ABS;Garantie;Mois garantie;Frais port;Ref contructeur;Cat;sCat;ssCat;Image1;I1 ext;Image2;I2 ext;Image3;I3 ext;[0];[0];agpl_id;agpl_ref;agpl_nom;agpl_prix;agpl_qte;agpl_poids;agpl_desc;baseimageurl;Image 1;Image 1 text;Image 2;Image 2 text;Image 3;Image 3 text;Statut;Log;Log2;Statut Img;IDAP;StN
11;Électrique - Commodo - Commodo gauche & Commodo droit - Moto APRILIA 100 SCARABEO 2004;;APRILIA 100 SCARABEO
COMODO COMMODO DROIT
 
TYPE VAA 4TEMPS - 2004/2009
;55;0;1;10;0;0.40;0;8;1;100;SCARABEO ;2004;2009;27/10/2020 14:34;1;;3;0;0;0;0;0;0;7.91;;4;31;117;ann_11;jpg;ann_11_2;jpg;;;0;0;11;24173;APRILIA 100 SCARABEO COMODO COMMODO DROIT TYPE VAA 4TEMPS - 2004/2009;9.56;1;0.4;desc;http://www.agpl.net/img/p/;3/2/0/1/9/32019.jpg;;3/2/0/2/3/32023.jpg;;;;0;;;1;0;0
12;Moto APRILIA 100 SCARABEO 2004;;APRILIA 100 SCARABEO
DISQUE DE FREIN AVANT
 
TYPE VAA 4TEMPS - 2004/2009
4mm
;55;0;1;28;0;1.50;0;8;1;100;SCARABEO ;2004;2009;27/10/2020 14:34;1;;3;0;0;0;0;0;0;10.90;;2;13;74;ann_12;jpg;;;;;0;0;12;24145;APRILIA 100 SCARABEO DISQUE DE FREIN AVANT TYPE VAA 4TEMPS - 2004/2009;27.53;1;1.5;desc;http://www.agpl.net/img/p/;3/1/9/7/3/31973.jpg;;;;;;0;;;1;0;0
15;Électrique - Allumage - Alternateur / Rotor - Stator - Moto APRILIA 100 SCARABEO 2004;;APRILIA 100 SCARABEO
ROTOR ALLUMAGE ALTERNATEUR
 
TYPE VAA 4TEMPS - 2004/2009
;55;0;1;30;0;1.00;0;8;1;100;SCARABEO ;2004;2009;27/10/2020 14:34;1;;3;0;0;0;0;0;0;9.49;;4;147;150;ann_15;jpg;;;;;0;0;15;24141;APRILIA 100 SCARABEO ROTOR ALLUMAGE ALTERNATEUR TYPE VAA 4TEMPS - 2004/2009;29.90;1;1;desc;http://www.agpl.net/img/p/;3/1/9/6/8/31968.jpg;;;;;;0;;;1;0;0
69;Électrique - Relais et capteurs - Relais divers - Moto APRILIA 125 RSV TUONO (R), (RACING) 2004;;APRILIA 1000 RSV R
5 RELAIS CENTRALES ELECTRIQUE
CAPTEUR CHUTE RENVERSEMENT
 
TYPE ZD4RRA - 2004/2005
;55;0;1;27;0;0.20;0;8;1;125;RSV TUONO (R), (RACING);2004;2005;27/10/2020 14:34;1;;3;0;0;0;0;0;0;6.79;;4;29;154;ann_69;jpg;ann_69_2;jpg;ann_69_3;jpg;0;0;69;170327;APRILIA 1000 RSV R 5 RELAIS CENTRALES ELECTRIQUE TYPE ZD4RRA - 2004/2005;26.90;1;0.2;desc;http://www.agpl.net/img/p/;2/7/0/2/4/1/270241.jpg;;2/7/0/2/4/2/270242.jpg;;2/7/0/2/4/3/270243.jpg;;0;;;1;0;0
103;Cycle - Frein arrière - Disque de frein - Moto APRILIA 1000 RS 1998;;APRILIA
125 RS-1998/09
125 TUONO-2004/05
250 RS-1995/05
1000 TUONO FIGHTER 02/05
1000 TUONO RACING 03/08
1000 TUONO RR 03/08
1000 RSV 1998/08
1000 RSV R 98/08
1000 RSV FACTORY 04/07
1000 RSV SP 99/03
1000 SL FALCO 00/04
DISQUE DE FREIN ARRIERE
4.8mm
Mini 4.5mm
;55;0;1;40;0;1.00;0;8;1;1000;RS;1998;2009;27/10/2020 14:34;1;;3;0;0;0;0;0;0;9.49;;2;14;75;ann_103;jpg;;;;;0;0;103;169793;APRILIA 1000 TUONO / RSV / FALCO-125 RS-250 RS-DISQUE DE FREIN ARRIERE;39.90;1;1;desc;http://www.agpl.net/img/p/;2/6/9/1/4/1/269141.jpg;;;;;;0;;;1;0;0
112;Moto APRILIA 125 ATLANTIC 2002;;APRILIA 125 ATLANTIC
CABLE DE COMPTEUR
 
TYPE ZD4SP - 2002/2010
;55;0;1;9;0;0.15;0;8;1;125;ATLANTIC;2002;2010;27/10/2020 14:34;1;;3;0;0;0;0;0;0;6.79;;2;23;223;ann_112;jpg;;;;;0;0;112;112549;APRILIA 125 ATLANTIC CABLE DE COMPTEUR TYPE ZD4SP - 2002/2010;8.40;1;0.15;desc;http://www.agpl.net/img/p/;1/5/8/9/9/3/158993.jpg;;;;;;0;;;1;0;0
128;Cycle - Jantes - Jante & axe de roue - Moto APRILIA 125 CLASSIC 1995;;APRILIA 125 CLASSIC
AXE DE ROUE ARRIERE
 
1995/2003
 
Nu sans vistendeur ni entretoises
;55;0;1;17;0;0.90;0;8;1;125;CLASSIC;1995;2003;27/10/2020 14:34;1;;3;0;0;0;0;0;0;9.49;;2;15;194;ann_128;jpg;;;;;0;0;128;137394;APRILIA 125 CLASSIC AXE DE ROUE ARRIERE 1995/2003;16.90;1;0.9;desc;http://www.agpl.net/img/p/;2/0/0/7/7/3/200773.jpg;;;;;;0;;;1;0;0
129;Cycle - Jantes - Jante & axe de roue - Moto APRILIA 125 CLASSIC 1995;;APRILIA 125 CLASSIC
AXE DE ROUE AVANT
1995/2003
;55;0;1;17;0;0.40;0;8;1;125;CLASSIC;1995;2003;27/10/2020 14:34;1;;3;0;0;0;0;0;0;7.91;;2;15;194;ann_129;jpg;;;;;0;0;129;42366;APRILIA 125 CLASSIC AXE DE ROUE AVANT 1995/2003;16.90;1;0.4;desc;http://www.agpl.net/img/p/;1/4/4/9/2/0/144920.jpg;;;;;;0;;;1;0;0
130;Moteur - Echappement - Sonde lambda & Valve échappement - Moto APRILIA 125 CLASSIC 1995;;APRILIA 125 CLASSIC
BALANCIER BOITE 
 
- 1995/2003
ETAT OK
;55;0;1;12;0;0.30;0;8;1;125;CLASSIC;1995;2003;27/10/2020 14:34;1;;3;0;0;0;0;0;0;7.91;;3;20;89;ann_130;jpg;ann_130_2;jpg;;;0;0;130;103916;APRILIA 125 CLASSIC BALANCIER BOITE - 1995/2003;11.34;1;0.299;desc;http://www.agpl.net/img/p/;1/4/5/8/4/9/145849.jpg;;1/4/5/8/5/0/145850.jpg;;;;0;;;1;0;0
131;Cycle - Béquille - Béquille latérale / béquille centrale - Moto APRILIA 125 CLASSIC 1995;;APRILIA 125 CLASSIC
BEQUILLE LATERALE
 
1995/2003
;55;0;1;16;0;1.10;0;8;1;125;CLASSIC;1995;2003;27/10/2020 14:34;1;;3;0;0;0;0;0;0;10.90;;2;9;53;ann_131;jpg;;;;;0;0;131;42367;APRILIA 125 CLASSIC BEQUILLE LATERALE 1995/2003;15.90;1;1.1;desc;http://www.agpl.net/img/p/;1/4/0/8/5/6/140856.jpg;;;;;;0;;;1;0;0
132;Moto APRILIA 125 CLASSIC 1995;;APRILIA 125 CLASSIC
CACHE CARTER MOTEUR DROIT
 
1995/2003
 
Rapé léger
;55;0;1;6;0;2.00;0;8;1;125;CLASSIC;1995;2003;27/10/2020 14:34;1;;3;0;0;0;0;0;0;10.90;;3;16;79;ann_132;jpg;;;;;0;0;132;56839;APRILIA 125 CLASSIC CACHE CARTER MOTEUR DROIT 1995/2003;5.90;1;2;desc;http://www.agpl.net/img/p/;1/4/5/0/7/0/145070.jpg;;;;;;0;;;1;0;0
133;Moto APRILIA 125 CLASSIC 1995;;APRILIA 125 CLASSIC
CACHE CARTER MOTEUR GAUCHE
 
1995/2003
 
Rapé léger
;55;0;1;6;0;1.00;0;8;1;125;CLASSIC;1995;2003;27/10/2020 14:34;1;;3;0;0;0;0;0;0;9.49;;3;16;79;ann_133;jpg;;;;;0;0;133;50829;APRILIA 125 CLASSIC CACHE CARTER MOTEUR GAUCHE 1995/2003;5.90;1;1;desc;http://www.agpl.net/img/p/;2/1/2/1/7/7/212177.jpg;;;;;;0;;;1;0;0
135;Électrique - Eclairage - Clignotant - Moto APRILIA 125 CLASSIC 1995;;APRILIA 125 CLASSIC
CLIGNOTANT ARRIERE GAUCHE
 
- 1995/2003
;55;0;1;9;0;0.10;0;8;1;125;CLASSIC;1995;2003;27/10/2020 14:34;1;;3;0;0;0;0;0;0;6.79;;4;24;106;ann_135;jpg;;;;;0;0;135;170050;APRILIA 125 CLASSIC CLIGNOTANT ARRIERE GAUCHE - 1995/2003;8.90;1;0.1;desc;http://www.agpl.net/img/p/;2/6/9/6/3/0/269630.jpg;;;;;;0;;;1;0;0
136;Moteur - Echappement - Collecteur & Ligne d'échappement - Moto APRILIA 125 CLASSIC 1995;;APRILIA 125 CLASSIC
COLLECTEUR ECHAPPEMENT
 
1995/2003
;55;0;1;12;0;1.50;0;8;1;125;CLASSIC;1995;2003;27/10/2020 14:34;1;;3;0;0;0;0;0;0;10.90;;3;20;87;ann_136;jpg;;;;;0;0;136;56829;APRILIA 125 CLASSIC COLLECTEUR ECHAPPEMENT 1995/2003;11.45;1;1.5;desc;http://www.agpl.net/img/p/;7/7/3/3/3/77333.jpg;;;;;;0;;;1;0;0
137;Moto APRILIA 125 CLASSIC 1995;;APRILIA 125 CLASSIC
FEU ARRIERE
1995/2003
Feu repeint
;55;0;1;10;0;0.50;0;8;1;125;CLASSIC;1995;2003;27/10/2020 14:34;1;;3;0;0;0;0;0;0;7.91;;4;24;104;ann_0;png;;;;;0;0;137;100693;APRILIA 125 CLASSIC FEU ARRIERE 1995/2003;9.71;1;0.5;desc;http://www.agpl.net/img/p/;1/4/0/8/7/0/140870.jpg;;;;;;0;[I137]:HTTP/1.1 301 Moved Permanently
;;5;0;0
139;Moto APRILIA 125 CLASSIC 1995;;APRILIA 125 CLASSIC
FLASQUE DE FREIN ARRIERE
here is my code
def analyze(document_csv)
trash = []
files = CSV.foreach((document_csv), headers: false, col_sep: "\n", skip_blanks: true) do |row|
a = row.join.split(";")
next if a == [" "] || a == [" "]
trash << a
end
trash.each do |str|
print str
end
end
Please help me fixing this
bit of data that i get from my code
["Embouts coupés"][" "][" "]["", "55", "0", "1", "37", "0", "5.00", "0", "234", "1", "650", "TL S", "1997", "2001", "27/10/2020 14:35", "1", "", "3", "0", "0", "0", "0", "0", "0", "15.90", "", "3", "20", "87", "ann_6778", "jpg", "ann_6778_2", "jpg", "ann_6778_3", "jpg", "0", "0", "6778", "67614", "SUZUKI 1000 TLS COLLECTEUR D'ECHAPPEMENT N°1 TYPE JS1AG31/21 1997/2001", "36.65", "1", "5", "desc", "http://www.agpl.net/img/p/", "1/4/4/4/9/1/144491.jpg", "", "1/4/4/4/9/2/144492.jpg", "", "1/4/5/2/9/3/145293.jpg", "", "0", "", "", "1", "0", "0"]["6824", "Moto SUZUKI 1100 GSX F 1988", "", "SUZUKI 1100 GSXF"]["POIGNEE DE MAINTIEN PASSAGER ARRIERE DROITE"][" "]```

Groupby and sort Pandas

I have a dataframe:
df = pd.DataFrame({
'Metric': ['Total Assets', 'Total Promo', 'Total Assets', 'Total Promo'],
'Risk': ['High', 'High','Low', 'Low'],
'2021': [ 200, 100, 400, 50]})
I want to groupby the Metric column and sort by '2021' column.
I tried:
df = df.sort_values(['2021'],ascending=False).groupby(['Metric', 'Risk'])
But I get the following output:
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x00000213CA672B48>
The output should look like:
df = pd.DataFrame({
'Metric': ['Total Assets', 'Total Assets', 'Total Promo', 'Total Promo'],
'Risk': ['Low', 'High', 'High', 'Low'],
'2021': [ 400, 200, 100, 50]})
If I understand you right, you want to sort by column "Metric" (ascending) and then "2021" (descending):
df = df.sort_values(["Metric", "2021"], ascending=[True, False])
print(df)
Prints:
Metric Risk 2021
0 Total Assets Low 400
1 Total Assets High 200
2 Total Promo High 100
3 Total Promo Low 50

Spring Boot Actuator 'http.server.requests' metric MAX time

I have a Spring Boot application and I am using Spring Boot Actuator and Micrometer in order to track metrics about my application. I am specifically concerned about the 'http.server.requests' metric and the MAX statistic:
{
"name": "http.server.requests",
"measurements": [
{
"statistic": "COUNT",
"value": 2
},
{
"statistic": "TOTAL_TIME",
"value": 0.079653001
},
{
"statistic": "MAX",
"value": 0.032696019
}
],
"availableTags": [
{
"tag": "exception",
"values": [
"None"
]
},
{
"tag": "method",
"values": [
"GET"
]
},
{
"tag": "status",
"values": [
"200",
"400"
]
}
]
}
I suppose the MAX statistic is the maximum time of execution of a request (since I have made two requests, it's the the time of the longer processing of one of them).
Whenever I filter the metric by any tag, like localhost:9090/actuator/metrics?tag=status:200
{
"name": "http.server.requests",
"measurements": [
{
"statistic": "COUNT",
"value": 1
},
{
"statistic": "TOTAL_TIME",
"value": 0.029653001
},
{
"statistic": "MAX",
"value": 0.0
}
],
"availableTags": [
{
"tag": "exception",
"values": [
"None"
]
},
{
"tag": "method",
"values": [
"GET"
]
}
]
}
I am always getting 0.0 as a max time. What is the reason of this?
What does MAX represent (MAX Discussion)
MAX represents the maximum time taken to execute endpoint.
Analysis for /user/asset/getAllAssets
COUNT TOTAL_TIME MAX
5 115 17
6 122 17 (Execution Time = 122 - 115 = 17)
7 131 17 (Execution Time = 131 - 122 = 17)
8 187 56 (Execution Time = 187 - 131 = 56)
9 204 56 From Now MAX will be 56 (Execution Time = 204 - 187 = 17)
Will MAX be 0 if we have less number of request (or 1 request) to the particular endpoint?
No number of request for particular endPoint does not affect the MAX (see an image from Spring Boot Admin)
When MAX will be 0
There is Timer which set the value 0. When the endpoint is not being called or executed for sometime Timer sets MAX to 0. Here approximate timer value is 2 to 2.30 minutes (120 to 150 seconds)
DistributionStatisticConfig has .expiry(Duration.ofMinutes(2)) which sets the some measutement to 0 if there is no request has been made for last 2 minutes (120 seconds)
Methods such as public TimeWindowMax(Clock clock,...), private void rotate() Clock interface has been written for the same. You may see the implementation here
How I have determined the timer value?
For that, I have taken 6 samples (executed the same endpoint for 6 times). For that, I have determined the time difference between the time of calling the endpoint - time for when MAX set back to zero
MAX property belongs to enum Statistic which is used by Measurement
(In Measurement we get COUNT, TOTAL_TIME, MAX)
public static final Statistic MAX
The maximum amount recorded. When this represents a time, it is
reported in the monitoring system's base unit of time.
Notes:
This is the cases from metric for a particular endpoint (here /actuator/metrics/http.server.requests?tag=uri:/user/asset/getAllAssets).
For generalize metric of actuator/metrics/http.server.requests
MAX for some endPoint will be set backed to 0 due to a timer. In my view for MAX for /http.server.requests will be same as a particular endpoint.
UPDATE
The document has been updated for the MAX.
NOTE: Max for basic DistributionSummary implementations such as
CumulativeDistributionSummary, StepDistributionSummary is a time
window max (TimeWindowMax). It means that its value is the maximum
value during a time window. If the time window ends, it'll be reset to
0 and a new time window starts again. Time window size will be the
step size of the meter registry unless expiry in
DistributionStatisticConfig is set to other value explicitly.
You can see the individual metrics by using ?tag=url:{endpoint_tag} as defined in the response of the root /actuator/metrics/http.server.requests call. The details of the measurements values are;
COUNT: Rate per second for calls.
TOTAL_TIME: The sum of the times recorded. Reported in the monitoring system's base unit of time
MAX: The maximum amount recorded. When this represents a time, it is reported in the monitoring system's base unit of time.
As given here, also here.
The discrepancies you are seeing is due to the presence of a timer. Meaning after some time currently defined MAX value for any tagged metric can be reset back to 0. Can you add some new calls to your endpoint then immediately do a call to /actuator/metrics/http.server.requests to see a non-zero MAX value for given tag?
This is due to the idea behind getting MAX metric for each smaller period. When you are seeing these metrics, you will be able to get an array of MAX values rather than a single value for a long period of time.
You can get to see this in action within Micrometer source code. There is a rotate() method focused on resetting the MAX value to create above described behaviour.
You can see this is called for every poll() call, which is triggered every some period for metric gathering.

Greedy conditional algorithm

I have a list of k artistes mapped to their respective music videos that they have starred in. This is represented in a multidimensional array:
musicvid_arr =
[["MUSICVID 1", 2014, ["ARTISTE 1", "ARTISTE 2", "ARTISTE 3"]],
["MUSICVID 2", 2014, ["ARTISTE 4", "ARTISTE 1", "ARTISTE 9", "ARTISTE 10"]],
["MUSICVID 3", 1935, ["ARTISTE 2", "ARTISTE 10", "ARTISTE 6"]],
["MUSICVID 4", 2010, ["ARTISTE 1", "ARTISTE 2", "ARTISTE 3"]],
["MUSICVID 5", 2009, ["ARTISTE 4", "ARTISTE 1", "ARTISTE 9", "ARTISTE 2", "ARTISTE 6", "ARTISTE 5"]],
["MUSICVID 6", 2014, ["ARTISTE 18", "ARTISTE 10", "ARTISTE 6", "ARTISTE 2"]],
["MUSICVID 7", 2014, ["ARTISTE 9", "ARTISTE 2", "ARTISTE 3", "ARTISTE 0", "ARTISTE 9"]],
["MUSICVID 8", 2000, ["ARTISTE 8", "ARTISTE 3", "ARTISTE 9", "ARTISTE 11", "ARTISTE 2", "ARTISTE 1"]],
["MUSICVID 9", 2014, ["ARTISTE 21", "ARTISTE 0", "ARTISTE 6"]],
["MUSICVID 10", 2014, ["ARTISTE 12", "ARTISTE 2", "ARTISTE 3"]],
["MUSICVID 11", 2013, ["ARTISTE 14", "ARTISTE 1", "ARTISTE 9", "ARTISTE 12"]],
["MUSICVID 12", 2014, ["ARTISTE 2"]]]
I want to create a method get_artistes that takes the parameters: k , r, and musicvid_arr:
def get_artistes(k, r, musicvid_arr)
# the code here
end
where
k: the number of artistes to return
r: the least number of artistes found in the return array of k artistes that must appear in each music video for the music video to be counted/valid
This method should return a list of artistes. If k = 3:
["ARTISTE 1", "ARTISTE 2", "ARTISTE 9"]
This image gives a better understanding of how k and r affect the most number. With reference to the image above,
# for r = 1 , it would have 11 valid music videos.
# for r = 2 , it would have 6 valid music videos.
# for r = 3 , it would have 3 valid music videos.
No matter what r and k we pass to this method, we want an array of artistes that have the most number of valid music videos.
What would be an effective and efficient approach on tackling this problem?
I attempted to do this via the following algorithm. I do not think that it is the most effective. With big datasets, it takes very long to run.
def get_artistes(k, r, musicvid_arr)
musicvid_arr=musicvid_arr.select{|t| t[2].size>=r}
artiste_arr = musicvid_arr.map.reduce({}){|a,vs|vs[2].each{|v|(a[v]||= [])<< vs[0]};a}.to_a.sort_by{|x| -x[1].count}
output = []
for i in 0...k
output << artiste_arr[i]
end
return output
end
Often Jr. Programmers doing something new see the problem as complex and feel the solution should have equal complexity.
Regardless of the complexity of any problem when writing code, the solution, should be clear and readable. If you can't speak your code aloud it's too complicated.
You should create a class ex: ParseArtists with multiple methods that clearly state each step in the process of parsing artists. This class should have the single responsibility of parsing artists with descriptive variable names, and small obvious methods.

What is a regex to capture the total amount from strings? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I need to parse the total amount from different files. The layout of each file is different so the lines I need to parse vary.
What should be the regex for capturing from a sting a number that falls after "Total"?
It needs to be case insensitive and should consider the closest match after "Total". There can be anything before or after the word "Total", and I need the first number that comes after it.
For example:
from string "Service charges: 10 Total: 100 Shipping: 10"
from string "Service charges: 10 Total Amount: 100 Shipping: 10"
from string "Service charges: 10 Grand Total: 100 Shipping: 10"
from string "Service charges: 10 Total Amount (Rs.): 100 Shipping: 10"
The output should be 100 in all the above cases.
If all you're really asking about is a pattern match for various strings, look at using scan and grab the numeric strings:
[
"Service charges: 10 Total: 100 Shipping: 10",
"Service charges: 10 Total Amount: 100 Shipping: 10",
"Service charges: 10 Grand Total: 100 Shipping: 10",
"Service charges: 10 Total Amount (Rs.): 100 Shipping: 10",
].map{ |s| s.scan(/\d+/)[1] }
=> ["100", "100", "100", "100"]
This assumes you want the second number in each string.
If that order is going to change, which is unlikely because it looks like you're scanning invoices, then variations on the pattern and/or scan will work. This switches it up and uses a standard regex search based on the location of "Total", some possible intervening text, followed by ":" and the total value:
[
"Service charges: 10 Total: 100 Shipping: 10",
"Service charges: 10 Total Amount: 100 Shipping: 10",
"Service charges: 10 Grand Total: 100 Shipping: 10",
"Service charges: 10 Total Amount (Rs.): 100 Shipping: 10",
].map{ |s| s[/Total.*?: (\d+)/, 1] }
=> ["100", "100", "100", "100"]
To get the integer values append to_i inside the map statement:
[
"Service charges: 10 Total: 100 Shipping: 10",
"Service charges: 10 Total Amount: 100 Shipping: 10",
"Service charges: 10 Grand Total: 100 Shipping: 10",
"Service charges: 10 Total Amount (Rs.): 100 Shipping: 10",
].map{ |s| s[/Total.*?: (\d+)/, 1].to_i }
=> [100, 100, 100, 100]
For your example strings, it's probably preferable to use case-sensitive patterns to match "Total" unless you have knowledge that you will encounter "total" in lower-case. And, in that case, you should show such an example.
I think you can do this:
/Total[^:]*:\s+([0-9]+)/i
Explanation:
Total seach for "total"
[^:]* followed by anything or nothing until a colon ":" is found
:\s+ read over the colon and any following white space (maybe take * instead of +)
([0-9]+) read the numbers into a group for later retrieval -> 100
I am not sure how to indicate case insensitivity in the environment you use, but usually this can be done with some flags like I indicated with the i
here is a fiddle as an example
# assuming you have all your files ready in an array
a = ["Service charges: 10 Total: 100 Shipping: 10", "Service charges: 10 Total Amount: 100 Shipping: 10", "Service charges: 10 Grand Total: 100 Shipping: 10", "Service charges: 10 Total Amount (Rs.): 100 Shipping: 10"]
# we find every total with the following regexp
a.map {|s| s[/total[^\d]*(?<total>\d+)/i, 'total']}
#=> ["100", "100", "100", "100"]
The regexp is /total[^\d]*(?<total>\d*)/i. It looks for the word "total" and ignores any following character, until it finds a number (which it returns in a capture group). The i option makes it case insensitive.

Resources