From d44d014f22018aa713c48dfdf14bc3dbcf9fc600 Mon Sep 17 00:00:00 2001 From: mwisnowski Date: Fri, 20 Dec 2024 07:10:53 -0800 Subject: [PATCH] Starting with logic for adding non-basic lands to deck builder --- deck_builder.py | 403 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 346 insertions(+), 57 deletions(-) diff --git a/deck_builder.py b/deck_builder.py index 4da8d20..e6806fe 100644 --- a/deck_builder.py +++ b/deck_builder.py @@ -1,15 +1,16 @@ from __future__ import annotations import inquirer.prompt # type: ignore +import keyboard # type: ignore import pandas as pd # type: ignore import pprint # type: ignore import random from fuzzywuzzy import fuzz, process # type: ignore -import settings +from settings import csv_directory +from setup import determine_commanders, set_lands -from setup import determine_commanders pd.set_option('display.max_columns', None) pd.set_option('display.max_rows', None) @@ -198,6 +199,8 @@ class DeckBuilder: # Set color identity self.color_identity = df.at[0, 'colorIdentity'] + print(self.color_identity) + self.color_identity_full = '' self.determine_color_identity() # Set creature colors @@ -223,7 +226,7 @@ class DeckBuilder: self.commander_dict = { 'Commander Name': self.commander, 'Mana Cost': self.commander_mana_cost, - 'Color Identity': self.color_identity, + 'Color Identity': self.color_identity_full, 'Colors': self.colors, 'Type': self.commander_type, 'Creature Types': self.creature_types, @@ -237,151 +240,162 @@ class DeckBuilder: self.determine_ideals() self.add_lands() - def determine_color_identity(self): # Determine the color identity for later # Mono color if self.color_identity == 'Colorless': - self.color_identity = 'Colorless' + self.color_identity_full = 'Colorless' self.files_to_load = ['colorless'] pass elif self.color_identity == 'B': - self.color_identity = 'Black' + self.color_identity_full = 'Black' self.files_to_load = ['colorless', 'black'] pass elif self.color_identity == 'G': - self.color_identity = 'Green' + self.color_identity_full = 'Green' self.files_to_load = ['colorless', 'green'] pass elif self.color_identity == 'R': - self.color_identity = 'Red' + self.color_identity_full = 'Red' self.files_to_load = ['colorless', 'red'] elif self.color_identity == 'U': - self.color_identity = 'Blue' + self.color_identity_full = 'Blue' self.files_to_load = ['colorless', 'blue'] pass pass elif self.color_identity == 'W': - self.color_identity = 'White' + self.color_identity_full = 'White' self.files_to_load = ['colorless', 'white'] pass # Two-color elif self.color_identity == 'B, G': - self.color_identity = 'Golgari: Black/Green' + self.color_identity_full = 'Golgari: Black/Green' + self.color_identity_options = ['B', 'G', 'B, G'] self.files_to_load = ['colorless', 'black', 'green', 'golgari'] pass elif self.color_identity == 'B, R': - self.color_identity = 'Rakdos: Black/Red' + self.color_identity_full = 'Rakdos: Black/Red' + self.color_identity_options = ['B', 'R', 'B, R'] self.files_to_load = ['colorless', 'black', 'red', 'rakdos'] pass elif self.color_identity == 'B, U': - self.color_identity = 'Dimir: Black/Blue' + self.color_identity_full = 'Dimir: Black/Blue' + self.color_identity_options = ['B', 'U', 'B, U'] self.files_to_load = ['colorless', 'black', 'blue', 'dimir'] pass elif self.color_identity == 'B, W': - self.color_identity = 'Orzhov: Black/White' + self.color_identity_full = 'Orzhov: Black/White' + self.color_identity_options = ['B', 'W', 'B, W'] self.files_to_load = ['colorless', 'black', 'white', 'orzhov'] pass elif self.color_identity == 'G, R': - self.color_identity = 'Gruul: Green/Red' + self.color_identity_full = 'Gruul: Green/Red' + self.color_identity_options = ['G', 'R', 'G, R'] self.files_to_load = ['colorless', 'green', 'red', 'gruul'] pass elif self.color_identity == 'G, U': - self.color_identity = 'Simic: Green/Blue' + self.color_identity_full = 'Simic: Green/Blue' + self.color_identity_options = ['G', 'U', 'G, U'] self.files_to_load = ['colorless', 'green', 'blue', 'simic'] pass elif self.color_identity == 'G, W': - self.color_identity = 'Selesnya: Green/White' + self.color_identity_full = 'Selesnya: Green/White' + self.color_identity_options = ['G', 'W', 'G, W'] self.files_to_load = ['colorless', 'green', 'white', 'selesnya'] pass elif self.color_identity == 'U, R': - self.color_identity = 'Izzet Blue/Red' + self.color_identity_full = 'Izzet Blue/Red' + self.color_identity_options = ['U', 'R', 'U, R'] self.files_to_load = ['colorless', 'blue', 'red', 'azorius'] pass elif self.color_identity == 'U, W': - self.color_identity = 'Azorius: Blue/White' + self.color_identity_full = 'Azorius: Blue/White' + self.color_identity_options = ['U', 'W', 'U, W'] self.files_to_load = ['colorless', 'blue', 'white', 'azorius'] pass elif self.color_identity == 'R, W': - self.color_identity = 'Boros: Red/White' + self.color_identity_full = 'Boros: Red/White' + self.color_identity_options = ['R', 'W', 'R, W'] self.files_to_load = ['colorless', 'red', 'white', 'boros'] pass # Thri-color elif self.color_identity == 'B, G, U': - self.color_identity = 'Sultai: Black/Blue/Green' + self.color_identity_full = 'Sultai: Black/Blue/Green' self.files_to_load = ['colorless', 'black', 'blue', 'green', 'dimir', 'golgari', 'simic', 'sultai'] pass elif self.color_identity == 'B, G, R': - self.color_identity = 'Jund: Black/Green/Red' + self.color_identity_full = 'Jund: Black/Green/Red' self.files_to_load = ['colorless', 'black', 'green', 'red', 'golgari', 'rakdos', 'gruul', 'jund'] pass elif self.color_identity == 'B, G, W': - self.color_identity = 'Abzan: Black/Green/White' + self.color_identity_full = 'Abzan: Black/Green/White' self.files_to_load = ['colorless', 'black', 'green', 'white', 'golgari', 'orzhov', 'selesnya', 'abzan'] pass elif self.color_identity == 'B, R, U': - self.color_identity = 'Grixis: Black/Blue/Red' + self.color_identity_full = 'Grixis: Black/Blue/Red' self.files_to_load = ['colorless', 'black', 'blue', 'red', 'dimir', 'rakdos', 'izzet', 'grixis'] pass elif self.color_identity == 'B, R, W': - self.color_identity = 'Mardu: Black/Red/White' + self.color_identity_full = 'Mardu: Black/Red/White' self.files_to_load = ['colorless', 'black', 'red', 'white', 'rakdos', 'orzhov', 'boros', 'mardu'] pass elif self.color_identity == 'B, U, W': - self.color_identity = 'Esper: Black/Blue/White' + self.color_identity_full = 'Esper: Black/Blue/White' self.files_to_load = ['colorless', 'black', 'blue', 'white', 'dimir', 'orzhov', 'azorius', 'esper'] pass elif self.color_identity == 'G, R, U': - self.color_identity = 'Temur: Blue/Green/Red' + self.color_identity_full = 'Temur: Blue/Green/Red' self.files_to_load = ['colorless', 'green', 'red', 'blue', 'simir', 'izzet', 'gruul', 'temur'] pass elif self.color_identity == 'G, R, W': - self.color_identity = 'Naya: Green/Red/White' + self.color_identity_full = 'Naya: Green/Red/White' self.files_to_load = ['colorless', 'green', 'red', 'white', 'gruul', 'selesnya', 'boros', 'naya'] pass elif self.color_identity == 'G, U, W': - self.color_identity = 'Bant: Blue/Green/White' + self.color_identity_full = 'Bant: Blue/Green/White' self.files_to_load = ['colorless', 'green', 'blue', 'white', 'simir', 'azorius', 'selesnya', 'bant'] pass elif self.color_identity == 'U, R, W': - self.color_identity = 'Jeskai: Blue/Red/White' + self.color_identity_full = 'Jeskai: Blue/Red/White' self.files_to_load = ['colorless', 'blue', 'red', 'white', 'izzet', 'azorius', 'boros', 'jeskai'] pass # Quad-color elif self.color_identity == 'B, G, R, U': - self.color_identity = 'Glint: Black/Blue/Green/Red' + self.color_identity_full = 'Glint: Black/Blue/Green/Red' self.files_to_load = ['colorless', 'black', 'blue', 'green', 'red', 'golgari', 'rakdos', 'dimir', 'gruul', 'simic', 'izzet', 'jund', 'sultai', 'grixis', 'temur', 'glint'] pass elif self.color_identity == 'B, G, R, W': - self.color_identity = 'Dune: Black/Green/Red/White' + self.color_identity_full = 'Dune: Black/Green/Red/White' self.files_to_load = ['colorless', 'black', 'green', 'red', 'white', 'golgari', 'rakdos', 'orzhov', 'gruul', 'selesnya', 'boros', 'jund', 'abzan', 'mardu', 'naya', 'dune'] pass elif self.color_identity == 'B, G, U, W': - self.color_identity = 'Witch: Black/Blue/Green/White' + self.color_identity_full = 'Witch: Black/Blue/Green/White' self.files_to_load = ['colorless', 'black', 'blue', 'green', 'white', 'golgari', 'dimir', 'orzhov', 'simic', 'selesnya', 'azorius', 'sultai', 'abzan', 'esper', 'bant', 'glint'] pass elif self.color_identity == 'B, R, U, W': - self.color_identity = 'Yore: Black/Blue/Red/White' + self.color_identity_full = 'Yore: Black/Blue/Red/White' self.files_to_load = ['colorless', 'black', 'blue', 'red', 'white', 'rakdos', 'dimir', 'orzhov', 'izzet', 'boros', 'azorius', 'grixis', 'mardu', 'esper', 'mardu', 'glint'] pass elif self.color_identity == 'G, R, U, W': - self.color_identity = 'Ink: Blue/Green/Red/White' + self.color_identity_full = 'Ink: Blue/Green/Red/White' + self.color_identity_options = ['G', 'R', 'U', 'W', 'G, R', 'G, U', 'G, W', 'R, U', 'R, W', 'U, W', + 'G, R, U', 'G, R, W', 'G, U, W', 'R, U, W', 'G, R, U, W'] self.files_to_load = ['colorless', 'blue', 'green', 'red', 'white', 'gruul', 'simic', 'selesnya', 'izzet', 'boros', 'azorius', 'temur', 'naya', 'bant', 'jeskai', 'glint'] pass elif self.color_identity == 'B, G, R, U, W': - self.color_identity = 'WUBRG: All colors' + self.color_identity_full = 'WUBRG: All colors' self.files_to_load = ['colorless', 'black', 'green', 'red', 'blue', 'white', 'golgari', 'rakdos',' dimir', 'orzhov', 'gruul', 'simic', 'selesnya', 'izzet', 'boros', 'azorius', 'jund', 'sultai', 'abzan', 'grixis', 'mardu', 'esper', 'temur', 'naya', 'bant', 'jeska', 'glint', 'dune','witch', 'yore', - 'ink', ] + 'ink'] def determine_themes(self): themes = self.commander_tags @@ -483,13 +497,13 @@ class DeckBuilder: # Determine ideal land count print('How many lands would you like to include?\n' - 'Before ramp is taken into account, 38-40 would be "normal" for a deck.\n' + 'Before ramp is taken into account, 38-40 would be "normal" for a deck. I personally use 35.\n' 'Broadly speaking, for every mana produced per 3 mana spent on ramp could reduce land count by 1.\n' 'If you\'re playing landfall, probably consider 40 as baseline before ramp.') question = [ inquirer.Text( 'land_prompt', - message='' + default='35' ) ] answer = inquirer.prompt(question) @@ -504,7 +518,7 @@ class DeckBuilder: question = [ inquirer.Text( 'creature_prompt', - message='' + default='25' ) ] answer = inquirer.prompt(question) @@ -519,7 +533,7 @@ class DeckBuilder: question = [ inquirer.Text( 'removal_prompt', - message='' + default='10' ) ] answer = inquirer.prompt(question) @@ -533,7 +547,7 @@ class DeckBuilder: question = [ inquirer.Text( 'board_wipe_prompt', - message='' + default='2' ) ] answer = inquirer.prompt(question) @@ -547,7 +561,7 @@ class DeckBuilder: question = [ inquirer.Text( 'draw_prompt', - message='' + default='10' ) ] answer = inquirer.prompt(question) @@ -561,7 +575,7 @@ class DeckBuilder: question = [ inquirer.Text( 'ramp_prompt', - message='' + default='8' ) ] answer = inquirer.prompt(question) @@ -577,7 +591,7 @@ class DeckBuilder: question = [ inquirer.Text( 'protection_prompt', - message='' + default='8' ) ] answer = inquirer.prompt(question) @@ -588,6 +602,16 @@ class DeckBuilder: print('Keep in mind that many of the ideals can also cover multiple roles, but this will give a baseline POV.') def add_lands(self): + while True: + try: + with open(f'{csv_directory}/land_cards.csv', 'r', encoding='utf-8') as f: + print('land_cards.csv found.') + f.close() + break + except FileNotFoundError: + print('land_cards.csv not found, regenerating it.') + set_lands() + self.land_df = pd.read_csv(f'{csv_directory}/land_cards.csv') # Begin the process to add lands, the number will depend on ideal land count, ramp, # and if any utility lands may be helpful. # By default, ({self.ideal_land_count} - 5) basic lands will be added, distributed @@ -596,14 +620,29 @@ class DeckBuilder: self.land_count = 0 self.add_basics() self.add_standard_non_basics() + self.add_fetches() + if 'Kindred' in ' '.join(self.themes): + self.add_kindred_lands() + if len(self.colors) >= 2: + self.add_dual_lands() + if len(self.colors) >= 3: + pass - + self.add_misc_lands() + + rows_to_drop = [] + for index, row in self.land_df.iterrows(): + for land in self.land_cards: + if land in row['name']: + rows_to_drop.append(index) + self.land_df = self.land_df.drop(rows_to_drop) + self.land_df.to_csv(f'{csv_directory}/test_lands.csv', index=False) # If over ideal land count, remove random basics until ideal land count while self.land_count > self.ideal_land_count: - self.remove_basic() + self.remove_basic() #if self.land_cards < self.ideal_land_count: # pass @@ -617,7 +656,7 @@ class DeckBuilder: self.land_cards.remove(basic_land) self.land_cards.append(f'{basic_land} x {num_basics}') total_basics += num_basics - #print(*self.land_cards, sep='\n') + print(*self.land_cards, sep='\n') print(f'Total lands: {self.land_count}') print(total_basics) @@ -645,7 +684,6 @@ class DeckBuilder: def add_standard_non_basics(self): # Add lands that are good in most any commander deck print('Adding "standard" non-basics') - generic_fetches = ['Evolving Wilds', 'Terramorphic Expanse', 'Shire Terrace', 'Escape Tunnel', 'Promising Vein'] self.land_cards.append('Reliquary Tower') self.land_count += 1 if 'Landfall' not in self.commander_tags: @@ -660,26 +698,277 @@ class DeckBuilder: self.land_cards.append('Exotic Orchard') self.land_count += 1 - # Adding Evolving Wilds and similar cards - for fetch in generic_fetches: - self.land_cards.append(fetch) - self.land_count += 1 if len(self.colors) <= 2: self.land_cards.append('War Room') self.land_count += 1 if self.commander_power >= 5: self.land_cards.append('Rogue\'s Passage') self.land_count += 1 - + + def add_fetches(self): + # Determine how many fetches in total + print('How many fetch lands would you like to include?\n' + 'For most decks you\'ll likely be good with 3 or 4, just enough to thin the deck and help ensure the color availability.\n' + 'If you\'re doing Landfall, more fetches would be recommended just to get as many Landfall triggers per turn.') + question = [ + inquirer.Text( + 'fetch_prompt', + default='5' + ) + ] + answer = inquirer.prompt(question) + desired_fetches = int(answer['fetch_prompt']) + chosen_fetches = [] + + generic_fetches = ['Evolving Wilds', 'Terramorphic Expanse', 'Shire Terrace', 'Escape Tunnel', 'Promising Vein','Myriad Landscape', 'Fabled Passage', 'Terminal Moraine'] + fetches = generic_fetches + + # Adding in life fetches + print('Would you like to include the pricier fetch-lands (i.e. Prismatic Vista or the Onslaught/Zendikar fetches)?') + question = [ + inquirer.Confirm( + 'yes', + ) + ] + answer = inquirer.prompt(question) + choice = answer['yes'] + if choice: + fetches.append('Prismatic Vista') + if 'W' in self.colors: + white_fetches = ['Flooded Strand', 'Windswept Heath', 'Marsh Flats', 'Arid Mesa'] + for fetch in white_fetches: + if fetch not in fetches: + fetches.append(fetch) + + if 'U' in self.colors: + blue_fetches = ['Flooded Strand', 'Polluted Delta', 'Scalding Tarn', 'Misty Rainforest'] + for fetch in blue_fetches: + if fetch not in fetches: + fetches.append(fetch) + + if 'B' in self.colors: + black_fetches = ['Polluted Delta', 'Bloodstained Mire', 'Marsh Flats', 'Verdant Catacombs'] + for fetch in black_fetches: + if fetch not in fetches: + fetches.append(fetch) + + if 'R' in self.colors: + red_fetches = ['Bloodstained Mire', 'Wooded Foothills', 'Scalding Tarn', 'Arid Mesa'] + for fetch in red_fetches: + if fetch not in fetches: + fetches.append(fetch) + + if 'G' in self.colors: + green_fetches = ['Wooded Foothills', 'Windswept Heath', 'Verdant Catacombs', 'Misty Rainforest'] + for fetch in green_fetches: + if fetch not in fetches: + fetches.append(fetch) + + # Adding in New Capenna Fetches + print('Would you like to include the cheaper, New Capenna fetches?') + question = [ + inquirer.Confirm( + 'yes', + ) + ] + answer = inquirer.prompt(question) + choice = answer['yes'] + if choice: + if 'W' in self.colors: + white_fetches = ['Brokers Hideout', 'Obscura Storefront', 'Cabaretti Courtyard'] + for fetch in white_fetches: + if fetch not in fetches: + fetches.append(fetch) + if 'U' in self.colors: + blue_fetches = ['Brokers Hideout', 'Obscura Storefront', 'Maestros Theater'] + for fetch in blue_fetches: + if fetch not in fetches: + fetches.append(fetch) + + if 'B' in self.colors: + black_fetches = ['Obscura Storefront', 'Maestros Theater', 'Riveteers Overlook'] + for fetch in black_fetches: + if fetch not in fetches: + fetches.append(fetch) + + if 'R' in self.colors: + red_fetches = ['Maestros Theater', 'Riveteers Overlook', 'Cabaretti Courtyard'] + for fetch in red_fetches: + if fetch not in fetches: + fetches.append(fetch) + + if 'G' in self.colors: + green_fetches = ['Brokers Hideout', 'Riveteers Overlook', 'Cabaretti Courtyard'] + for fetch in green_fetches: + if fetch not in fetches: + fetches.append(fetch) + + fetches_chosen = False + # Randomly choose fetches up to the desired number + while not fetches_chosen: + while len(chosen_fetches) < desired_fetches + 3: + fetch_choice = random.choice(fetches) + if fetch_choice not in chosen_fetches: + chosen_fetches.append(fetch_choice) + + print('These are the fetch lands that have been found for you:') + print(chosen_fetches) + print('Do they look good for you?') + question = [ + inquirer.Confirm( + 'yes', + ) + ] + answer = inquirer.prompt(question) + choice = answer['yes'] + if not choice: + print('Reselecting fetches to use.') + chosen_fetches = [] + + else: + fetches_to_add = [] + while len(fetches_to_add) < desired_fetches: + print(f'Please choose {desired_fetches} of them to add to your deck.') + question = [ + inquirer.List('theme', + choices=chosen_fetches, + carousel=True) + ] + answer = inquirer.prompt(question) + choice = answer['theme'] + fetches_to_add.append(choice) + chosen_fetches.remove(choice) + fetches_chosen = True + break + break + for fetch in fetches_to_add: + if fetch not in self.land_cards: + self.land_cards.append(fetch) + self.land_count += 1 + def add_kindred_lands(self): print('Adding lands that care about the commander having a Kindred theme.') print('Adding general Kindred lands.') - if 'Kindred' in ' '.join(self.themes): - kindred_lands = ['Cavern of Souls', 'Path of Ancestry', 'Three Tree City'] - for land in kindred_lands: + kindred_lands = ['Path of Ancestry'] + + print('Would you like to include the pricier Kindred lands (i.e. Cavern of Souls and Three Tree City)?') + question = [ + inquirer.Confirm( + 'yes', + ) + ] + answer = inquirer.prompt(question) + choice = answer['yes'] + if choice: + kindred_lands.extend(['Three Tree City', 'Cavern of Souls']) + + for land in kindred_lands: + if land not in self.land_cards: + self.land_cards.append(land) + self.land_count += 1 + + def add_dual_lands(self): + # Determine dual-color lands available + dual_options = [] + if ('W' in self.colors and 'U' in self.colors): + for index, row in self.land_df.iterrows(): + if 'Land — Plains Island' == row['type']: + dual_options.append(row['name']) + self.land_df = self.land_df.drop(index) + if ('W' in self.colors and 'B' in self.colors): + for index, row in self.land_df.iterrows(): + if 'Land — Plains Swamp' == row['type']: + dual_options.append(row['name']) + self.land_df = self.land_df.drop(index) + if ('U' in self.colors and 'B' in self.colors): + for index, row in self.land_df.iterrows(): + if 'Land — Island Swamp' == row['type']: + dual_options.append(row['name']) + self.land_df = self.land_df.drop(index) + if ('G' in self.colors and 'B' in self.colors): + for index, row in self.land_df.iterrows(): + if 'Land — Forest Swamp' == row['type']: + dual_options.append(row['name']) + self.land_df = self.land_df.drop(index) + if ('B' in self.colors and 'R' in self.colors): + for index, row in self.land_df.iterrows(): + if 'Land — Swamp Mountain' == row['type']: + dual_options.append(row['name']) + self.land_df = self.land_df.drop(index) + if ('G' in self.colors and 'U' in self.colors): + for index, row in self.land_df.iterrows(): + if 'Land — Forest Island' == row['type']: + dual_options.append(row['name']) + self.land_df = self.land_df.drop(index) + if ('R' in self.colors and 'G' in self.colors): + for index, row in self.land_df.iterrows(): + if 'Land — Mountain Forest' == row['type']: + dual_options.append(row['name']) + self.land_df = self.land_df.drop(index) + if ('U' in self.colors and 'R' in self.colors): + for index, row in self.land_df.iterrows(): + if 'Land — Island Mountain' == row['type']: + dual_options.append(row['name']) + self.land_df = self.land_df.drop(index) + if ('G' in self.colors and 'W' in self.colors): + for index, row in self.land_df.iterrows(): + if 'Land — Forest Plains' == row['type']: + dual_options.append(row['name']) + self.land_df = self.land_df.drop(index) + if ('R' in self.colors and 'W' in self.colors): + for index, row in self.land_df.iterrows(): + if 'Land — Mountain Plains' == row['type']: + dual_options.append(row['name']) + self.land_df = self.land_df.drop(index) + + # Determine if using the dual-type lands + print('Would you like to include dual-type lands (i.e. lands that count as both a Plains and a Swamp for example)?') + question = [ + inquirer.Confirm( + 'yes', + ) + ] + answer = inquirer.prompt(question) + choice = answer['yes'] + + + # Add the Duals to a list + while choice: + # Include OG duals + print('Would you like to include the OG dual lands (i.e. Tundra or Plateau)?') + og_question = [ + inquirer.Confirm( + 'no', + ) + ] + og_answer = inquirer.prompt(og_question) + include_ogs = og_answer['no'] + og_duals = ['Tundra', 'Underground Sea', 'Badlands', 'Taiga', 'Savannah', 'Scrubland', 'Volcanic Island', 'Bayou', 'Plateau', 'Tropical Island'] + if not include_ogs: + for land in og_duals: + if land in dual_options: + dual_options.remove(land) + print('Here\'s all the dual-type lands in your commander\'s color identity:') + print(*dual_options, sep='\n') + print('\n') + for land in dual_options: if land not in self.land_cards: self.land_cards.append(land) self.land_count += 1 + break + + def add_misc_lands(self): + + print(self.color_identity) + rows_to_drop = [] + for index, row in self.land_df.iterrows(): + if row['colorIdentity'] not in self.color_identity_options: + rows_to_drop.append(index) + + filtered_lands_df = self.land_df.drop(rows_to_drop) + filtered_lands_df = filtered_lands_df.head(35) + print(filtered_lands_df[['name']]) + def remove_basic(self): basic_lands = []