What should I change in my currency converter?
First, there's very little point in using a class like you are here. You're essentially just using the constructor as a function to ask for input. You're also needlessly making some variables attributes of the object, like self.features, self.x, and self.d. The only use of features is to be iterated over within the constructor, and the only use of the latter two are inside of input_process. Even if this were an appropriate use of a class, that data doesn't need to be retained in the object itself. That just wastes memory.

To remedy this, I'd take everything in __init__, and move it into a regular function. To store the data, I'd use a NamedTuple returned from the function.



Your prints are also needlessly verbose. You're using print("") as a way to print newlines. Newlines can simply be added using "\n" though.

print("")
print(Fore.GREEN + "-" * 76)
print("")


Can simply be:

print("\n" + (Fore.GREEN + "-" * 76) + "\n")


And since you use (Fore.GREEN + "-" * 76) multiple times, I'd save that into a string at the top of the file:

SEPARATOR = "\n" + (Fore.GREEN + "-" * 76) + "\n"




Your loop over features is also unnecessary. It can be done simply using join:

print("\n".join(features))




Your names are also poor. c1, c2, c, x and d are very vague and give little information about what they hold. I would make those names much longer.





After making the mentioned changes, and I ended up with:

from currency_converter import CurrencyConverter
from datetime import date
from colorama import Fore
import datetime
from typing import NamedTuple, Optional, Tuple

# These are constants. They should be defined externally, and have capitalized names
FEATURES = ["1. Convert using the last available rate.", "2. Convert using specific dates."]
SEPARATOR = "\n" + (Fore.GREEN + "-" * 76) + "\n"

class ConversionInformation(NamedTuple):  # A simple class to hold information
    feature_type: str
    amount: str
    source_currency: str
    target_currency: str
    conversion_date: Optional[Tuple]

def ask_for_input() -&gt; ConversionInformation:
    print(SEPARATOR)
    print("\n".join(FEATURES))

    feature_type = input("Select a feature: ")

    print(SEPARATOR)

    amount = input("Amount: ")
    source_cur = input("Currency1: ")
    target_cur = input("Currency2: ")

    conversion_date = None

    if feature_type == "2":
        conversion_date = (int(input("Year: ")),
                           int(input("Month: ")),
                           int(input("Day: ")))

    return ConversionInformation(feature_type, amount, source_cur, target_cur, conversion_date)

def process_input(info: ConversionInformation):
    conv = CurrencyConverter()  # This wasn't needed when asking for input

    if info.feature_type == "1":
        # Note the more descriptive names
        result = round(conv.convert(info.amount, info.source_currency, info.target_currency), 2)
        cur_date = datetime.datetime.now()

        print(f"{info.amount} {info.source_currency} is {result} {info.target_currency} on {cur_date}")

    elif info.feature_type == "2":
        result = round(conv.convert(info.amount, info.source_currency, info.target_currency,
                                    date=date(*info.conversion_date)))

        print(f"{info.amount} {info.source_currency} was {result} {info.target_currency} in" +
              "-".join(str(d) for d in info.conversion_date))

    else:
        print("Illegal Feature Type:", info.feature_type)  # Tell the user that they entered an illegal type


# Also a constant
CURRENCIES = ["USD", "SEK", "GBP", "EUR"]


if __name__ == '__main__':
    print(Fore.GREEN + f"This is a Currency converter, the main currencies are {', '.join(CURRENCIES)}")
    print(SEPARATOR)

    while True:
        info = ask_for_input()
        process_input(info)

        print(SEPARATOR)

        if input("Finished. Do another? (Y/N)\n").lower() != 'y':
            break


It's far more verbose, but I believe it's much cleaner and easier to understand.

My main issue with what I've done here is package all the data into ConversionInformation just so it can be passed into process_input. You may find that it ends up being cleaner to make this all one large function.