<jupyter_start><jupyter_text>Question 1:<jupyter_code>Create a class Smoothie and do the following:
    
 - Create an instance attribute called ingredients.
 - Create a get_cost method which calculates the total cost of the ingredients used to make the smoothie.

 - Create a get_price method which returns the number from get_cost plus the 
    number from get_cost multiplied by 1.5. Round to two decimal places.
 - Create a get_name method which gets the ingredients and puts them in alphabetical 
        order into a nice descriptive sentence. If there are multiple
        ingredients, add the word "Fusion" to the end but otherwise,
        add "Smoothie". Remember to change "-berries" to "-berry". See the examples below.
        
Ingredient        Price
Strawberries      $1.50
Banana            $0.50
Mango             $2.50
Blueberries       $1.00
Raspberries       $1.00
Apple             $1.75
Pineapple         $3.50

Examples

s1 = Smoothie(["Banana"])

s1.ingredients ["Banana"]
s1.get_cost() "$0.50"
s1.get_price() "$1.25"
s1.get_name() "Banana Smoothie"

s2 = Smoothie(["Raspberries", "Strawberries", "Blueberries"])

s2.ingredients ["Raspberries", "Strawberries", "Blueberries"]
s2.get_cost() "$3.50"
s2.get_price() "$8.75"
s2.get_name() "Blueberry Raspberry Strawberry Fusion"<jupyter_output><empty_output><jupyter_text>Answer :<jupyter_code>class Smoothie:
    
    def __init__(self,ingredients):
        self.ingredients = ingredients
        self.price_dic = {  "Strawberries":1.50, 
                            "Banana":0.50,
                            "Mango":2.50,
                            "Blueberries":1.00,
                            "Raspberries":1.00,
                            "Apple":1.75,
                            "Pineapple":3.50 }
        
    def get_cost(self):
        self.tot_cast = sum([self.price_dic[i] for i in self.ingredients])
        return "$"+str(round(self.tot_cast,2))
    
    def get_price(self):
        price = round(self.tot_cast + 1.5*self.tot_cast,2)
        return "$" + str(price)
    
    def get_name(self):
        name = []
        for i in self.ingredients:
            if "berries" in i:
                idx = i.index("berries")
                name.append(i[0:idx]+"berry")
            else:
                name.append(i)
        if len(self.ingredients)==1:
            return  name[0] + " Smoothie"
        else:
            return " ".join(sorted(name)) + " Fusion"
s1 = Smoothie(["Banana"])

print(s1.ingredients)
print(s1.get_cost()) 
print(s1.get_price())
print(s1.get_name())
s2 = Smoothie(["Raspberries", "Strawberries", "Blueberries"])

print(s2.ingredients)
print(s2.get_cost()) 
print(s2.get_price())
print(s2.get_name())<jupyter_output>['Raspberries', 'Strawberries', 'Blueberries']
$3.5
$8.75
Blueberry Raspberry Strawberry Fusion<jupyter_text>Question 2:<jupyter_code>Your task is to write a program which allows teachers to create a multiple choice test 
in a class called Testpaper and to be also able to assign a minimum pass mark.
The testpaper's subject should also be included. The attributes are in the following order:

 1. subject
 2. markscheme
 3. pass_mark
    
As well as that, we need to create student objects to take the test itself!
Create another class called Student and do the following:
    
 - Create an attribute called tests_taken and set the default as 'No tests taken'.

 - Make a method called take_test(), which takes in the testpaper object they are completing and 
    the student's answers. Compare what they wrote to the mark scheme, and append 
    to the/create a dictionary assigned to tests_taken in the way as shown in the point below.
    
 - Each key in the dictionary should be the testpaper subject and each value should
    be a string in the format seen in the examples below (whether or not the student has 
    failed, and their percentage in brackets).
    
Examples

paper1 = Testpaper("Maths", ["1A", "2C", "3D", "4A", "5A"], "60%")
paper2 = Testpaper("Chemistry", ["1C", "2C", "3D", "4A"], "75%")
paper3 = Testpaper("Computing", ["1D", "2C", "3C", "4B", "5D", "6C", "7A"], "75%")

student1 = Student()
student2 = Student()

student1.tests_taken "No tests taken"
student1.take_test(paper1, ["1A", "2D", "3D", "4A", "5A"])
student1.tests_taken {"Maths" : "Passed! (80%)"}
student2.take_test(paper2, ["1C", "2D", "3A", "4C"])
student2.take_test(paper3, ["1A", "2C", "3A", "4C", "5D", "6C", "7B"])
student2.tests_taken {"Chemistry" : "Failed! (25%)", "Computing" : "Failed! (43%)"}<jupyter_output><empty_output><jupyter_text>Answer :<jupyter_code>import re 

class Testpaper:
    
    def __init__(self, subject, markscheme, pass_mark):
        self.subject = subject
        self.markscheme = markscheme
        self.pass_mark = pass_mark
        
class Student:
    
    def __init__(self,tests_taken="No tests taken"):
        self.tests_taken = tests_taken
        
    def take_test(self,obj,ans):
        
        self.obj = obj
        self.ans = ans
        
        mark = round(100*sum([i == j for i, j in zip(ans,obj.markscheme)])/len(ans))
        pass_mark = int(re.findall("\d+",obj.pass_mark)[0])
        
        if mark>pass_mark:
            result = "Passed!"
        else:
            result = "Failed!"
            
        if type(self.tests_taken) == str:
            self.tests_taken = dict()
        self.tests_taken[obj.subject] = f"{result} ({mark}%)"
paper1 = Testpaper("Maths", ["1A", "2C", "3D", "4A", "5A"], "60%")
paper2 = Testpaper("Chemistry", ["1C", "2C", "3D", "4A"], "75%")
paper3 = Testpaper("Computing", ["1D", "2C", "3C", "4B", "5D", "6C", "7A"], "75%")

student1 = Student()
student2 = Student()

student1.tests_taken
student1.take_test(paper1, ["1A", "2D", "3D", "4A", "5A"])
student1.tests_taken
student2.take_test(paper2, ["1C", "2D", "3A", "4C"])
student2.take_test(paper3, ["1A", "2C", "3A", "4C", "5D", "6C", "7B"])
student2.tests_taken<jupyter_output><empty_output><jupyter_text>Question 3:<jupyter_code>Due to unforseen circumstances in Suburbia, the trains will be delayed by a further 10 minutes.
Create a function that will help to plan out and manage these delays! 
Create a function called manage_delays that does the following:
    
 - Parameters will be the train object, a destination and number of minutes the delay is.
 - Increment to the train object's expected_time by the delay, if the
    destination given is in the train object's destinations.
    
Examples

trains = [
 Train(["Townsville", "Suburbia", "Urbantska"], "13:04"),
Train(["Farmsdale", "Suburbia", "Lakeside Valley"], "13:20"),
Train(["Suburbia", "Townsville", "Lakeside Valley"], "13:22")
]

for t in trains:
 manage_delays(t, "Lakeside Valley", 60)
trains[0].expected_time "13:04"
trains[1].expected_time "14:20"
trains[2].expected_time "14:22"<jupyter_output><empty_output><jupyter_text>Answer :<jupyter_code>import re

from datetime import timedelta
class Train:
    
    def __init__(self,destinations,expected_time):
        self.destinations = destinations
        self.expected_time = expected_time

def manage_delays(obj, destination,delay):
    if destination in obj.destinations:
        exp_hour, exp_minutes = [int(i) for i in re.findall("\d+",obj.expected_time)]
        del_hour, del_minutes = divmod(delay,60)
        t1 = timedelta(days=0, hours=exp_hour, minutes=exp_minutes)
        t2 = timedelta(days=0, hours=del_hour, minutes=del_minutes)
        obj.expected_time = str(t1+t2)[0:~2]
trains = [
 Train(["Townsville", "Suburbia", "Urbantska"], "13:04"),
Train(["Farmsdale", "Suburbia", "Lakeside Valley"], "13:20"),
Train(["Suburbia", "Townsville", "Lakeside Valley"], "13:22")
]

for t in trains:
    manage_delays(t, "Lakeside Valley", 60)
trains[0].expected_time
trains[1].expected_time
trains[2].expected_time<jupyter_output><empty_output><jupyter_text>Question 4<jupyter_code>Ted works as a computer programmer at Minecraft Inc. His boss has just given him
an important assignment to update the code for the minecart tracks by the end of April.
However, he has recently had to self-isolate due to
Corvid-19 and has left the code for the tracks BACK AT WORK!! 
He has the shorthand for the tracks he's supposed to look at, and where the carts are
suppost to end up, but not the actual code.

He knows that:
    
 1. "-->" = "Speed-Up Track" — If a minecart interacts with this track, it's
velocity increases by 2.67 BPS unless it's at its maximum speed of 8 BPS.

 2. "<-->" = "Powered Track" — If a minecart interacts with this track, it's
velocity remains the same.

 3. "<--" = "Slow-Down Track" — If a minecart interacts with this track, 
    it's velocity decreases by 2.67 BPS unless it's velocity equals 0, at which point it stops.
    
 4. "---" = "Unpowered Track" — If a minecart interacts with this track, 
    it's velocity decreases by 1 BPS unless it's velocity equals 0, at which point it stops.
    
Help Ted by writing a class for the tracks that interact with the provided
Minecart class as shown above. And then write a function that will take a list of the shorthand tracks and:
    
 - If the Minecart reaches the last peice of Track, return True.
 - Else return the index of the Track where the Minecart stops.

Examples

mine_run(["-->", "-->", "-->", "<--", "<--", "<--"]) True
mine_run(["-->", "<--", "-->", "-->", "<-->", "---"]) 1<jupyter_output><empty_output><jupyter_text>Answer :<jupyter_code>class Track:
    def __init__(self,tracks ={}):
        self.tracks = {"-->":2.67,"<-->":0,"<--":-2.67,"---":-1}
        
track = Track()

def mine_run(M_tracks):
    BPS = 0
    for i,j in enumerate(M_tracks):
        BPS += track.tracks[j]
        if BPS<=0 and i<len(M_tracks)-1:
            return i
    return True
print(mine_run(["-->", "-->", "-->", "<--", "<--", "<--"]))
print(mine_run(["-->", "<--", "-->", "-->", "<-->", "---"]))<jupyter_output>True
1<jupyter_text>Question 5:<jupyter_code>Make a Rectangle class with four parameters, an x, a y (representing the top-left corner
of the rectangle), a width and a height exclusively in that order.
Lastly, make a function intersecting that takes two Rectangle objects and
returns True if those objects are intersecting (colliding), else return False.

Examples


a = Rectangle(10, 20, 100, 20)
b = Rectangle(10, 40, 15, 20)
c = Rectangle(50, 50, 20, 30)
intersecting(a, b) True
intersecting(a, c) False
intersecting(b, c) True<jupyter_output><empty_output><jupyter_text>Answer :<jupyter_code>class Rectangle:
    
    def __init__(self, x, y, w, h):
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        
def intersecting(obj1,obj2):
    # object 1
    #  bottom-left, top-right
    ob1_x1, ob1_x2 = obj1.x, obj1.x + obj1.w # x
    ob1_y1, ob1_y2 = obj1.y - obj1.h, obj1.y # y
    #print(ob1_x1, ob1_x2 )
    #print(ob1_y1, ob1_y2)
    
    # object 2
    ob2_x = obj2.x, obj2.x, obj2.x + obj2.w, obj2.x + obj2.w # x
    ob2_y = obj2.y, obj2.y - obj2.h,obj2.y - obj2.h,  obj2.y # y
    #print(ob2_x)
    #print(ob2_y)
    bool_ = []
    for x,y in zip(ob2_x, ob2_y):
        if (x > ob1_x1 and x < ob1_x2 and
            y > ob1_y1 and y < ob1_y2) :
            bool_.append(True)
        else :
            bool_.append(False)
    #print(bool_)
            
    return any(bool_)
a = Rectangle(10, 20, 100, 20)
b = Rectangle(10, 40, 15, 20)
c = Rectangle(50, 50, 20, 30)
intersecting(a, b)
intersecting(a, c)
intersecting(b, c)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13799720865317516, 'fraction_numerical': 0.03480460572226099, 'mean_word_length': 3.1934893928310166, 'pattern_counts': {'":': 11, '<': 57, '<?xml version=': 0, '>': 60, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '39726', 'license': 'MIT', 'n_tokens_mistral': 4173, 'n_tokens_neox': 3920, 'n_words': 1175, 'path': 'Python Advance Programming Assignment/Assignment_22.ipynb', 'repo_name': 'kpsanjeet/Python-Programming-Basic-Assignment', 'size': '11464'}