Returning count of more persons - python

I am new in python and I have problem in my code. My function count_transitive_sellers_with_degree is returning count only from person sellers. I need to get it return count of person sellers and seller sellers and so on. I do not know how to write it.. Could you help me and say where it is a problem? Thank you :)
class Person:
def __init__(self, name, year_of_birth, degree):
self.name = name
self.year_of_birth = year_of_birth
self.degree = degree
self.leader = None
self.sellers = []
def create_leadership(leader, seller):
seller.leader = leader
leader.sellers.append(seller)
def count_transitive_sellers_with_degree(person, degree):
count = 0
for seller in person.sellers:
if seller.degree == degree:
count += 1 + count_transitive_sellers_with_degree(seller,degree)
return count
>>> martin = Person('Martin', 1991, 'phd')
>>> tom = Person('Tom', 1993, 'mgr')
>>> josh = Person('Josh', 1995, 'bc')
>>> create_leadership(martin, tom)
>>> create_leadership(tom, josh)
>>> count_transitive_sellers_with_degree(martin, 'bc')
what it should write... -> 1
what it is writing now... -> 0

Currently you're only calling count_transitive_sellers_with_degree on sellers who themselves have the degree you're testing for, I haven't tested the below, but I think it should work.
def count_transitive_sellers_with_degree(person, degree):
count = 0
for seller in person.sellers:
if seller.degree == degree:
count += 1
# A seller's sellers should be counted irrespective of
# if they have the degree or not
count += count_transitive_sellers_with_degree(seller,degree)
return count

Your problem is here. Your if condition is not allowing you to go the recursive part as Tom's degree is not 'bc'.
if seller.degree == degree:
count += 1 + count_transitive_sellers_with_degree(seller,degree)

if seller.degree == degree:
does not reflect what you say your program is supposed to do: it will only add the children of the person if they have the same degree

Related

how can I create class objects using a list?

This is my class program, for the instances I've created so far, it's worked fine.
from random import random
class team:
wins = 0
losses = 0
def __init__(self,name):
self.name = name
def win(self):
self.wins += 1
def lose(self):
self.losses += 1
def play(self,opponent):
if random()<0.5:
self.win()
opponent.lose()
print(self.name,"won",opponent.name,"lost")
else:
self.lose()
opponent.win()
print(opponent.name,"won",self.name,"lost")
def record(self):
return (self.wins,'-',self.losses)
def startgames(self, array_of_team_objects):
k = 1
outer = 0
space = True
while outer<len(array_of_team_objects):
inner = 0
while space == True:
inner = outer + k
if inner == len(Teams): space = False
array_of_team_objects[outer].play(array_of_team_objects[inner])
k +=1
#whileinner
outer+=1
#whileouter
print("Every team has now played every other team once")
team1 = team("Yankees") # creates a team object with given name
team2 = team("Mets") # each new team starts with 0 wins and 0 losses
team1.play(team2) #prints "Yankees won, Mets lost" or "Mets won, Yankees lost"
print(team1.record()) # should print "1-0" or "0-1" depending on above
print(team2.record()) # should print "0-1" or "1-0" depending on above
For the next part of this program, which I will use the 'startgames' method for, I want to make every element of the list 'Names' an object of the class. How can I do this?
Names =["Mets","Yankees","Dodgers","Cubs","Nationals","Rays","Marlins","Braves","Twins","Athletics","Orioles","Royals","Phillies","Pirates"]

Class for database of recipes not working? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
there are 3 files, and I moved a condensed database into one of the files so that I could just prove that the concept works.
the first file is called find_a_recipe.py which is the one that is run
[find_a_recipe.py]
from random import sample
from typing import List
from main import *
#from cfonts import render
## main logic for type ingredient mode
def type_mode():
print("Let's find the ingredient you are looking for...")
keep_choosing = True
recipes = recipe_list
ingredient_list = get_ingredient_list(recipe_list)
ingredients_sorted = quicksort(ingredient_list)
while keep_choosing:
ingredients = ingredient_filtering(ingredients_sorted)
recipes = filter_recipes(ingredients, recipes)
ingredient_list = get_ingredient_list(recipes)
ingredients_sorted = quicksort(ingredient_list)
print(f"\nWe have {len(recipes)} recipes with those ingredients.")
keep_choosing = bolean_test("Want to choose other ingredients?")
if len(recipes) > 5:
recipe_choice_list = sample(recipes, 5)
else:
recipe_choice_list = recipes
print("\nHere are a few suggestions! Choose one and good luck!")
chosen_recipe = choose_recipe(recipe_choice_list, "Ok! Just choose one of those!")
print(chosen_recipe)
## main logig for yes/no mode
def yes_no_mode():
pass
recipe_dictionary = [
{'id': '192281',
'name': 'southern butter mints',
'minutes': '15',
'steps': 'melt cream cheese and butter in large saucepan over low heat, etc',
'ingredients': ['cream cheese', 'butter']},
{'id': '15017',
'name': 'baked ricotta with parmesan and thyme',
'minutes': '70',
'steps': 'preheat oven to 150c, place the parmesan',
'ingredients': ['parmesan cheese', 'thyme leaves', 'chili flakes']},
{'id': '193618',
'name': 'spaghetti with italian sausage spinach and diced tomatoes',
'minutes': '60',
'steps': 'boil spaghetti until al dente',
'ingredients': ['spaghetti', 'sweet italian turkey sausage', 'diced tomatoes']}]
##Print Welcome message
title = "Find A Recipe"
title_message = """
Welcome to Find A Recipe, the Recipe suggestion app that will blow your...kitchen?!
"""
#print(render(title))
print(title_message)
##create Recipe instances from dictionary
recipe_list = []
print(recipe_dictionary)
for i in recipe_dictionary:
id = i ["id"]
print(id)
#id = Recipe(i, id)
#recipe_list.append(id)
## Get an input on suggestion mode
choose_mode = "Please, choose a suggestion mode:"
modes_list = ["Type an ingredient", "Yes or No"]
suggestion_mode = get_choice(modes_list, choose_mode)
# Based on suggestion mode, run suggestion logic
if suggestion_mode == modes_list[0]:
type_mode()
else:
yes_no_mode()
the second file holds all the logic [main.py]
#import recipe_dict
from recipes import Recipe
from math import inf
from random import randrange
# ingredient list function
def get_ingredient_list(recipes):
ingredient_list = []
for recipe in recipes:
for ingredient in recipe.ingredients:
if ingredient not in ingredient_list:
ingredient_list.append(ingredient)
return ingredient_list
# ingredient count function
def get_ingredient_count(recipes):
ingredient_count = {}
for recipe in recipes:
for ingredient in recipe.ingredients:
if ingredient not in ingredient_count.keys():
ingredient_count[ingredient] = 1
else:
ingredient_count[ingredient] += 1
return ingredient_count
# def recipe_by_ingredient function
def get_recipes_by_ingredient(recipes, ingredient):
recipes_by_ingredient = []
for recipe in recipes:
if ingredient in recipe.ingredients:
recipes_by_ingredient.append(recipe)
return recipes_by_ingredient
# ingredient for optimal subset function
def get_optimal_ingredient(recipes):
best_subset_possible = len(recipes) // 2
optimal_ing = ""
optimal_count = inf
ingredient_count = get_ingredient_count(recipes)
for ingredient, count in ingredient_count.items():
if abs(best_subset_possible - count) < abs(best_subset_possible - optimal_count):
optimal_ing = ingredient
optimal_count = count
return optimal_ing
# logic for getting user recipe choice
def choose_recipe(choices, input_text):
count = 0
for choice in choices:
count += 1
print(f"{count}) {choice.name}\n")
choice_range = [f"{num}" for num in range(1, count + 1)]
user_choice = input(input_text)
if user_choice not in choice_range:
print(f"invalid input: please choose from 1 to {count}")
choose_recipe(choices, input_text)
else:
return choices[int(user_choice) - 1]
# quicksort function
def quicksort(arr):
if len(arr) <= 1: return arr
m = arr[randrange(0, len(arr))]
return quicksort([i for i in arr if i < m]) + \
[i for i in arr if i == m] + \
quicksort([i for i in arr if i > m])
# quick search in sorted list
def check_match(input, text):
match_count = 0
for char in range(len(input)):
if len(input) > len(text):
return False
elif input[char] == text[char]:
match_count += 1
else:
break
if match_count == len(input):
return True
return False
def find_match(list, input):
# base case
if len(list) == 1:
if check_match(input, list[0]) is True:
return list[0]
return "no match found..."
# define slicers
pivot = len(list) // 2
start = pivot
end = pivot
# check for match
if check_match(input, list[pivot]) is True:
while start >= 0 and check_match(input, list[start]) is True:
start -= 1
while end <= (len(list) - 1) and check_match(input, list[end]) is True:
end += 1
# else call recursive steps
else:
if input < list[pivot]:
return find_match(list[:pivot + 1], input)
return find_match(list[pivot:], input)
# return sliced list
return list[start + 1:end]
##helper variables and functions
def bolean_test(prompt):
user_input = input(f"{prompt} [y/n]")
if user_input.lower() == "y":
return True
elif user_input.lower() == "n":
return False
else:
return bolean_test(prompt)
def get_choice(choices, input_text):
count = 0
for choice in choices:
count += 1
print(f"{count}) {choice}\n")
choice_range = [f"{num}" for num in range(1, count)]
user_choice = input(input_text)
if user_choice not in choice_range:
print(f"invalid input: please choose from 1 to {count}")
return get_choice(choices, input_text)
else:
return choices[int(user_choice) - 1]
# ingredient filtering logic
def ingredient_filtering(ingredient_list):
search_ingredient_input = input("Type the first letter or first few letters of the ingredient you are looking for:")
match = find_match(ingredient_list, search_ingredient_input)
if type(match) is list:
print("\nMatches found:\n")
for i in match:
print(i)
test = bolean_test("Want to filter some more?")
elif type(match) is str:
print(match)
test = False
if test is True:
return ingredient_filtering(match)
else:
if type(match) is list:
return match
return ingredient_list
# recipe filtering logic
def filter_recipes(ingredients, recipes):
recipes_filtered = []
for i in ingredients:
subset = get_recipes_by_ingredient(recipes, i)
for r in subset:
if r not in recipes_filtered:
recipes_filtered.append(r)
return recipes_filtered
and the third holds the classes which I am having issues with, called [recipes.py]
class Recipe():
def __init__(self, dict, id):
self.id = id
self.name = dict["name"]
self.minutes = dict["minutes"]
self.steps = eval(dict["steps"])
self.ingredients = eval(dict["ingredients"])
def has_ingredient(self, ingredient):
return ingredient in self.ingredients
def __str__(self):
print(self.name.title() + "\n")
print(f"Preparation time: {self.minutes} minutes \n")
print("Ingredients:")
for i in self.ingredients:
print(f"- {i};")
print("\nPreparation Steps:")
for s in self.steps:
print(f"- {s};")
return ""
when I moved the database into the one file I stared getting a whole bunch of errors
third holds the classes which I am having issues with
At least one of these lines will fail because you are trying to eval() non-Python code.
self.steps = eval(dict["steps"])
self.ingredients = eval(dict["ingredients"])
Refer
'steps': 'melt cream cheese and butter in large saucepan over low heat, etc',
'ingredients': ['cream cheese', 'butter']},
e.g.
>>> eval('melt cream cheese and butter in large saucepan over low heat, etc')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
melt cream cheese and butter in large saucepan over low heat, etc
^
SyntaxError: invalid syntax
Instead, you should make your class like this (or better, use a dataclass)
class Recipe():
def __init__(self, id, name, minutes, steps, ingredients):
self.id = id
self.name = name
self.minutes = minutes
self.steps = steps
self.ingredients = ingredients
Then remove the need for dictionaries
##create Recipe instances
recipe_list = [
Recipe(id='192281',name='southern butter mints', minutes='15', steps='melt cream cheese and butter in large saucepan over low heat, etc', ingredients=['cream cheese', 'butter']),
...
]
If you want in recipes conditional to work, you need to implement __eq__ function in that class. If you want to be able to sort the list, then __cmp__
If you want a proper database where you can filter, sort, and query, then start with sqlite3

How to select between two values, using one 60% of the times and the other 40% of the time

I'm sorry for the really shitty title but i cant explain it better in a short way.
What im trying to do is to create a generator that generates people. i want the user to be able to specify how many men vs women there should be.
Right now i set gender by
gender = random.randint(1, 2)
where 1 = male and 2 = female.
lets say i want to create 100 people where 60% of them are women, how do i keep track of it?
my code right
while count != num_of_names:
l_num = random.randint(0, 149)
f_num = random.randint(0, 200)
f_name_male = f_names_males[f_num]
f_name_female = f_names_females[f_num]
gender = random.randint(1, 2)
if gender == 1:
f_name = f_name_male
else:
f_name = f_name_female
l_name = l_names[l_num]
names.append((f_name, l_name, gender))
count += 1
If you want to always have an exact distribution, just create the list and use random.shuffle to randomize the values within the list.
from random import shuffle
gender = [1] * 40 + [2] * 60
shuffle(gender)
Use random.shuffle() and call it to randomise a list. Here is a generator that yields random values 'M' or "F' from a fixed pool in the relative amounts requested:
import random
def gender(n_male, n_female):
population = list('M' * n_male + 'F' * n_female)
random.shuffle(population)
for i in range(len(population)):
yield population[i]
>>> l = [g for g in gender(40, 60)]
>>> assert l.count('M') == 40
>>> assert l.count('F') == 60
>>> print(f"male : {l.count('M')}, female : {l.count('F')}")
male : 40, female : 60
>>> l = [g for g in gender(50, 50)]
>>> print(f"male : {l.count('M')}, female : {l.count('F')}")
male : 50, female : 50
Something like this perhaps:
gender_array = ["Male" if x > 60 else "Female" for x in range(0, 100)]
gender = gender_array[random.randint(0, len(gender_array))]
print(gender)
I came to this solution
import random
population = []
def generate_sex(no_of_generate_people, percent):
male = "male"
female = "female"
ratio = no_of_generate_people * percent
for i in range(no_of_generate_people):
if float(population.count("male")) > float(ratio):
population.append("female")
else:
population.append("male")
if len(population) > no_of_generate_people:
return population
generate_sex(100, 0.7)
print(population.count("male"))
I would write a few small functions and tie them together:
def random_male():
return (random.choice(f_names_male), random.choice(l_names), 'male')
def random_female():
return (random.choice(f_names_female), random.choice(l_names), 'female')
def random_males(amount):
return [random_male() for _ in range(amount)]
def random_females(amount):
return [random_female() for _ in range(amount)]
def random_people(males, females):
return random_males(males) + random_females(females)
or even
def make_stuff(generator, amount):
return [generator() for _ in range(amount)]
def make_people(males, females):
return make_stuff(random_male, males) + make_stuff(random_female, females)

Get sum of goals scored by each team

I am analyzing a football games dataset and I want to answer a question - how many goals each team has scored and lost.
My dataset:
date home_team away_team home_score away_score
1873-03-08 England Scotland 0 1
1873-03-09 Scotland England 1 0
... ... ... ... ...
The function takes in 2 parameters - start year and end year
I've tried to have an empty list at a start, while iterating through the whole set add the name of the country and append the goals they've scored but since there are many different teams my list is not correct.
def total_goals(start, end):
x = 0
goals_scored = 0
goals_scored_list = []
goals_lost = 0
goals_lost_list = []
complete_list = []
for item in range(len(data['home_team'])):
date = int(data['date'][x][:4])
if date >= start:
if date <= end:
if int(data['home_score'][x]) > int(data['away_score'][x]):
goals_scored_list.append(data['home_team'])
goals_scored_list.append(data['home_score'])
x += 1
else:
x += 1
return goals_scored_list
My desired output would be a list which would contain a list for each unique team, that list would have country name, goals scored and goals lost:
[['England',1,1],['Scotland',0,2],[...]]
I assume I would need to create a list for each unique country, maybe using something like
if country not in data['home_team']:
goals_scored_list.append(data['home_team'][x]
But I believe there is a more sophisticated way to achieve my goal.
I believe this should work:
class Team:
def __init__(self,name):
self.name = name
self.wins = 0
self.losses = 0
def addEl(self,pos,score):
try:
score = int(score)
except Exception as e:
print e
if pos:
self.wins += score
else:
self.loss += score
def total_goals(start,end):
d = {}
for i in range(len(data)):
date = int(data['date'][i])
if date >= start and date <= end: #make sure it's in the params
pos = int(data['home_score'][i]) > int(data['away_score'][i]) #true if home wins, false otherwise
if data['home_team'][i] in d: #check if home_team already exists
d[data['home_team']].addEl(pos,data['home_score'][i]) #add score to wins/losses
else:
d[data['home_team'][i]] = Team(data['home_score'][i])
d[data['home_team'][i]].addEl(pos,data['home_score'][i])
if data['away_team'][i] in d:
d[data['away_team']].addEl(not(pos),data['away_score'][i])
else:
d[data['away_team'][i]] = Team(data['away_score'][i])
d[data['away_team'][i]].addEl(not(pos),data['away_score'][i])
return d
Using a custom class has the advantage of letting you add more characteristics like how many games were won/lost, additional statistics etc.etc.

Finding number in list of tuple

Suppose a functionget_number(directory, person), which returns the person's phone number. If the number is not found, return 0.
def make_directory():
return []
def add_number(directory, person, number):
directory.append((person,number))
print(str(person) + ' ' +'added!')
return(directory)
def get_number(directory, person):
if person == directory[0][0]:
return directory[0][1]
elif len(directory) >= 1:
return get_number(directory[1:],person)
else:
return 0
phonebook = make_directory()
add_number(phonebook, 'Police', 999)
add_number(phonebook, 'Lynna', 8444)
add_number(phonebook, 'Jack', 1123)
add_number(phonebook, 'Sister', 5720)
print(get_number(phonebook, 'Jack')) # I should be getting 1123
print_list(phonebook) #[('Police', 999), ('Lynna', 8444), ('Jack', 1123), ('Sister', 5720)]
But I am not able to get it. May I know what is the problem?
Because, you are comparing the name against the number. What you should have is
if person == directory[0][0]:
Also, the condition should if the directory has enough values in it first. So, the conditions will become like this
if len(directory) >= 1:
return 0
elif person == directory[0][1]:
return directory[0][1]
else:
return get_number(directory[1:], person)
Note: I would recommend using a Python dictionary here. They are there for this very purpose.

Categories

Resources