Skip to content

Commit 0e753c8

Browse files
committed
feat(pandas): add problem 550
1 parent 42ac353 commit 0e753c8

File tree

4 files changed

+90
-1
lines changed

4 files changed

+90
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Fiddling around with DataFusion, pandas, and PyArrow.
3232
| 1211 | [Queries Quality and Percentage](https://leetcode.com/problems/queries-quality-and-percentage) | Easy ||||
3333
| 1193 | [Monthly Transactions I](https://leetcode.com/problems/monthly-transactions-i) | Medium ||||
3434
| 1174 | [Immediate Food Delivery II](https://leetcode.com/problems/immediate-food-delivery-ii) | Medium ||||
35-
| 550 | [Game Play Analysis IV](https://leetcode.com/problems/game-play-analysis-iv) | Medium || ||
35+
| 550 | [Game Play Analysis IV](https://leetcode.com/problems/game-play-analysis-iv) | Medium || ||
3636
## Sorting and Grouping
3737
| problem_id | title | difficulty | DataFusion | pandas | PyArrow |
3838
|-------------:|:-----------------------------------------------------------------------------------------------------------------------------------|:-------------|:-------------|:---------|:----------|

problems/pandas.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Solutions to LeetCode problems in pandas."""
22

3+
from datetime import timedelta
34
from decimal import ROUND_HALF_UP, Decimal
45

56
import pandas as pd
@@ -87,6 +88,36 @@ def problem_197(weather: pd.DataFrame) -> pd.DataFrame:
8788
return weather[mask][["id"]]
8889

8990

91+
def problem_550(activity: pd.DataFrame) -> pd.DataFrame:
92+
"""Report the fraction of players who logged in the day after their first login.
93+
94+
Write a solution to report the fraction of players that logged in again on the
95+
day after the day they first logged in, rounded to 2 decimal places. In other
96+
words, you need to count the number of players that logged in for at least two
97+
consecutive days starting from their first login date, then divide that number by
98+
the total number of players.
99+
100+
Parameters
101+
----------
102+
activity : pd.DataFrame
103+
This table shows the activity of players of some games.
104+
105+
Returns
106+
-------
107+
pd.DataFrame
108+
109+
"""
110+
grouped = activity.groupby("player_id", as_index=False).aggregate(
111+
min_event_date=pd.NamedAgg("event_date", "min")
112+
)
113+
grouped["event_date"] = grouped["min_event_date"] + timedelta(days=1)
114+
joined = grouped.merge(activity, how="left", on=["player_id", "event_date"])
115+
joined.device_id.notna().sum() / len(joined.index)
116+
return pd.DataFrame(
117+
[joined.games_played.notna().sum() / len(joined.index)], columns=["fraction"]
118+
).round(2)
119+
120+
90121
def problem_620(cinema: pd.DataFrame) -> pd.DataFrame:
91122
"""Report movies with odd IDs and descriptions not equal to "boring".
92123

tests/test_pandas.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,62 @@ def test_problem_197(input_data, expected_data):
153153
)
154154

155155

156+
@pytest.mark.parametrize(
157+
"input_data, expected_data",
158+
[
159+
pytest.param(
160+
{
161+
"player_id": [1, 1, 2, 3, 3],
162+
"device_id": [2, 2, 3, 1, 4],
163+
"event_date": [
164+
datetime(2016, 3, 1),
165+
datetime(2016, 3, 2),
166+
datetime(2017, 6, 25),
167+
datetime(2016, 3, 2),
168+
datetime(2018, 7, 3),
169+
],
170+
"games_played": [5, 6, 1, 0, 5],
171+
},
172+
{"fraction": [0.33]},
173+
id="happy_path_basic",
174+
),
175+
pytest.param(
176+
{
177+
"player_id": [1, 1, 1, 2, 2],
178+
"device_id": [2, 2, 3, 1, 4],
179+
"event_date": [
180+
datetime(2023, 1, 1),
181+
datetime(2023, 1, 2),
182+
datetime(2023, 1, 3),
183+
datetime(2023, 1, 1),
184+
datetime(2023, 1, 2),
185+
],
186+
"games_played": [1, 2, 3, 4, 5],
187+
},
188+
{"fraction": [1.0]},
189+
id="happy_path_multiple_dates",
190+
),
191+
pytest.param(
192+
{
193+
"player_id": [1],
194+
"device_id": [1],
195+
"event_date": [datetime(2023, 1, 1)],
196+
"games_played": [1],
197+
},
198+
{"fraction": [0.0]},
199+
id="edge_case_single_entry",
200+
),
201+
],
202+
)
203+
def test_problem_550(input_data, expected_data):
204+
table = pd.DataFrame(input_data)
205+
expected_table = pd.DataFrame(expected_data)
206+
result = problem_550(table).reset_index(drop=True)
207+
assert_frame_equal(
208+
result, expected_table, check_dtype=False, check_index_type=False
209+
)
210+
211+
156212
@pytest.mark.parametrize(
157213
"input_data, expected_data",
158214
[

tests/test_pyarrow.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ def test_problem_197(input_data, expected_data):
274274
pytest.param(
275275
{
276276
"player_id": [1, 1, 1, 2, 2],
277+
"device_id": [2, 2, 3, 1, 4],
277278
"event_date": [
278279
datetime(2023, 1, 1),
279280
datetime(2023, 1, 2),
@@ -289,6 +290,7 @@ def test_problem_197(input_data, expected_data):
289290
pytest.param(
290291
{
291292
"player_id": [1],
293+
"device_id": [1],
292294
"event_date": [datetime(2023, 1, 1)],
293295
"games_played": [1],
294296
},

0 commit comments

Comments
 (0)