Skip to content

Commit

Permalink
MIME Type
Browse files Browse the repository at this point in the history
  • Loading branch information
charlesfranciscodev committed Oct 21, 2024
1 parent 9f03d92 commit f6fb1fe
Show file tree
Hide file tree
Showing 7 changed files with 265 additions and 109 deletions.
105 changes: 52 additions & 53 deletions puzzles/python3/mime-type/README.md
Original file line number Diff line number Diff line change
@@ -1,82 +1,81 @@
# Mime Type
# MIME Type

This is a solution to the "Mime Type" problem on [Codingame](https://www.codingame.com/training/easy/mime-type).
## Description

## Problem Description
The task involves creating a program to determine the MIME type of files based on their names. This involves associating file extensions with MIME types. The program reads an association table with N elements and a list of Q file names to be analyzed. For each file name, the program identifies the extension by finding the substring after the last dot character. If the extension is found in the association table (case insensitive), it prints the corresponding MIME type. If the MIME type cannot be determined or the file has no extension, it outputs UNKNOWN. The program takes the number of elements in the table, the number of file names, the extension-MIME associations, and the file names as input, and outputs the corresponding MIME types or UNKNOWN.

You are given a list of file names and their corresponding MIME types. You need to read a list of file names and determine the corresponding MIME type for each file name. If the MIME type cannot be determined, the program should output `UNKNOWN`.
## Solution Overview

The MIME type is determined by the file extension. The table of file extensions and their corresponding MIME types is given.
To solve this problem, we need to map file extensions to their respective MIME types, and then analyze the file names to determine the MIME type by extracting the extension from the file name. If the extension matches one in our table (case insensitive), we return the MIME type; otherwise, we return `UNKNOWN`.

| Extension | MIME Type |
|-----------|-----------|
|html |text/html |
|htm |text/html |
|png |image/png |
|jpeg |image/jpeg |
|jpg |image/jpeg |
|gif |image/gif |
|bmp |image/bmp |
|txt |text/plain|
|pdf |application/pdf|
### Explanation:

The file name may have multiple periods (.) in it, but the extension is always the substring that follows the last period.
- We use a dictionary `mime_table` to store the file extensions and their corresponding MIME types, converting extensions to lowercase to handle case insensitivity.
- For each file name, the program finds the last occurrence of a `.` in the string, and extracts the file extension if valid.
- The MIME type is printed if the extension is found in the dictionary, otherwise `UNKNOWN` is printed.

## Solution
### Edge Cases Handled:

The solution reads the the number of MIME types, number of file names and the file names. It stores the MIME types in a map with the extension as the key. Then it reads a list of file names and determines the corresponding MIME type by looking up the extension in the map. If the extension is not found, it outputs `UNKNOWN`.
- Files with no extension or a dot at the end.
- Extensions in different cases (e.g., `.TXT`, `.txt`, `.tXt` all map to the same MIME type).
- Files whose extensions aren't in the provided table result in `UNKNOWN`.

## Example Input/Output

Input:
**Input**

```
4
2
3
3
html text/html
png image/png
gif image/gif
txt text/plain
file.html
file.txt
animated.gif
portrait.png
index.html
```

Output:
**Output**

```
image/gif
image/png
text/html
text/plain
```

## Example Code
## Code Example

```python
# Read the number of elements in the association table
n = int(input())

# Read the number of file names to be analyzed
q = int(input())

# Create a dictionary to store the association table
mime_types = {}

# Read the association table
for _ in range(n):
ext, mime = input().split()
mime_types[ext.lower()] = mime

# Process each file name
for _ in range(q):
file_name = input().lower()

# Find the extension of the file
if '.' in file_name:
extension = file_name.split('.')[-1]
if extension in mime_types:
print(mime_types[extension])
# Number of elements which make up the association table.
N = int(input())

# Number of file names to be analyzed.
Q = int(input())

mime_table = {}

# Reading the MIME type associations.
for _ in range(N):
ext, mime_type = input().split()
mime_table[ext.lower()] = mime_type # Store extensions as lowercase for case-insensitivity.

# Processing each file name.
for _ in range(Q):
fname = input()

# Find the position of the last '.' in the file name.
last_dot_index = fname.rfind('.')

# If there's a '.' and it isn't the last character, extract the extension.
if last_dot_index != -1 and last_dot_index < len(fname) - 1:
file_ext = fname[last_dot_index + 1:].lower() # Get the file extension and convert to lowercase.

# Check if the extension exists in the mime_table.
if file_ext in mime_table:
print(mime_table[file_ext]) # Output the MIME type.
else:
print("UNKNOWN")
print('UNKNOWN') # Output UNKNOWN if extension not found.
else:
print("UNKNOWN")
print('UNKNOWN') # Output UNKNOWN if no extension or '.' at the end.

```
47 changes: 28 additions & 19 deletions puzzles/python3/mime-type/mime_type.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,36 @@
from typing import Dict
def mime_type_puzzle():
# Number of elements which make up the association table.
N = int(input())

# Number of file names to be analyzed.
Q = int(input())

def main():
table: Dict[str, str] = {} # file extension => mime type
nb_elements: int = int(input())
nb_names: int = int(input())
mime_table = {}

for _ in range(nb_elements):
extension, mime_type = input().split()
table[extension.lower()] = mime_type
# Reading the MIME type associations.
for _ in range(N):
ext, mime_type = input().split()
mime_table[ext.lower()] = mime_type # Store extensions as lowercase for case-insensitivity.

for _ in range(nb_names):
name: str = input().lower()
dot_index: int = name.rfind(".")
if dot_index == -1 or dot_index == len(name) - 1:
print("UNKNOWN")
else:
extension: str = name[dot_index + 1 :]
if extension in table:
print(table[extension])
# Processing each file name.
for _ in range(Q):
fname = input()

# Find the position of the last '.' in the file name.
last_dot_index = fname.rfind('.')

# If there's a '.' and it isn't the last character, extract the extension.
if last_dot_index != -1 and last_dot_index < len(fname) - 1:
file_ext = fname[last_dot_index + 1:].lower() # Get the file extension and convert to lowercase.

# Check if the extension exists in the mime_table.
if file_ext in mime_table:
print(mime_table[file_ext]) # Output the MIME type.
else:
print("UNKNOWN")
print('UNKNOWN') # Output UNKNOWN if extension not found.
else:
print('UNKNOWN') # Output UNKNOWN if no extension or '.' at the end.


if __name__ == "__main__":
main()
mime_type_puzzle()
69 changes: 65 additions & 4 deletions puzzles/python3/mime-type/test_mime_type.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from unittest.mock import patch, call

from mime_type import main
from mime_type import mime_type_puzzle


def test_mime_type():
def test_mime_type_with_unknown_extension():
# Set up
input_data = [
"3", # Number of elements
Expand All @@ -26,10 +26,71 @@ def test_mime_type():
# Execute
with patch("builtins.input", side_effect=input_data):
with patch("builtins.print") as mocked_print:
main()
mime_type_puzzle()

# Assert
mocked_print.assert_has_calls([call(output) for output in expected_output])


test_mime_type()
def test_mime_type_with_no_extension_or_dot_character():
# Set up
input_data = [
"3", # Number of elements
"4", # Number of names
"html text/html", # Extension and mime type mapping
"png image/png", # Extension and mime type mapping
"gif image/gif", # Extension and mime type mapping
"file", # Input name
"image", # Input name
"file.", # Input name with no extension
"image.", # Input name with no extension
]
expected_output = [
"UNKNOWN",
"UNKNOWN",
"UNKNOWN",
"UNKNOWN",
]

# Execute
with patch("builtins.input", side_effect=input_data):
with patch("builtins.print") as mocked_print:
mime_type_puzzle()

# Assert
mocked_print.assert_has_calls([call(output) for output in expected_output])


def test_mime_type_with_different_cases():
# Set up
input_data = [
"3", # Number of elements
"4", # Number of names
"txt text/plain", # Extension and mime type mapping
"jpg image/jpeg", # Extension and mime type mapping
"png image/png", # Extension and mime type mapping
"file.TXT", # Input name
"image.JPG", # Input name
"file.tXt", # Input name
"image.Png", # Input name
]
expected_output = [
"text/plain",
"image/jpeg",
"text/plain",
"image/png",
]

# Execute
with patch("builtins.input", side_effect=input_data):
with patch("builtins.print") as mocked_print:
mime_type_puzzle()

# Assert
mocked_print.assert_has_calls([call(output) for output in expected_output])


if __name__ == "__main__":
test_mime_type_with_unknown_extension()
test_mime_type_with_no_extension_or_dot_character()
test_mime_type_with_different_cases()
88 changes: 84 additions & 4 deletions puzzles/ts/mime-type/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,89 @@
# MIME Type

"MIME Type" is a beginner-level coding challenge available on the CodinGame platform. In this challenge, the player is given a list of file names and their corresponding MIME types, and is asked to determine the MIME type of a given file name.
## Description

A MIME type is a type of Internet standard that is used to indicate the type of data that a file contains. It is typically represented as a two-part identifier, with the first part indicating the type of data (such as "image" or "text") and the second part indicating the specific format or subtype (such as "jpeg" or "html").
The task involves creating a program to determine the MIME type of files based on their names. This involves associating file extensions with MIME types. The program reads an association table with N elements and a list of Q file names to be analyzed. For each file name, the program identifies the extension by finding the substring after the last dot character. If the extension is found in the association table (case insensitive), it prints the corresponding MIME type. If the MIME type cannot be determined or the file has no extension, it outputs UNKNOWN. The program takes the number of elements in the table, the number of file names, the extension-MIME associations, and the file names as input, and outputs the corresponding MIME types or UNKNOWN.

The challenge consists of writing a program that takes as input a list of file names and their corresponding MIME types, as well as the name of a file, and outputs the corresponding MIME type for that file. If the file type is not known, the program should output "UNKNOWN".
## Solution Overview

The challenge is designed to help players learn and practice programming skills such as string manipulation, conditional statements, and data structures. It is a fun and engaging way to improve programming skills while solving a challenging and entertaining puzzle.
To solve this problem, we need to map file extensions to their respective MIME types, and then analyze the file names to determine the MIME type by extracting the extension from the file name. If the extension matches one in our table (case insensitive), we return the MIME type; otherwise, we return `UNKNOWN`.

### Explanation:

1. **Input Parsing:**
- The number of MIME type associations (`N`) and the number of file names to analyze (`Q`) are read first.
- Then, the MIME type associations are stored in an object (`mimeTable`), where the key is the file extension and the value is the MIME type. Extensions are stored in lowercase to ensure case insensitivity.

2. **File Name Analysis:**
- For each file name, we determine if it has a valid extension by checking for the last occurrence of a `.` (dot) character.
- If the file has an extension (i.e., the `.` is not the last character), we extract the extension, convert it to lowercase, and look it up in the MIME type table.
- If the extension exists in the table, the corresponding MIME type is printed; otherwise, `UNKNOWN` is printed.

### Edge Cases Handled:

- Files with no extension or a dot at the end.
- Extensions in different cases (e.g., `.TXT`, `.txt`, `.tXt` all map to the same MIME type).
- Files whose extensions aren't in the provided table result in `UNKNOWN`.

## Example Input/Output

**Input**

```
3
3
html text/html
png image/png
gif image/gif
animated.gif
portrait.png
index.html
```

**Output**

```
image/gif
image/png
text/html
```

## Code Example

```typescript
const N: number = parseInt(readline()); // Number of elements which make up the association table.
const Q: number = parseInt(readline()); // Number Q of file names to be analyzed.

const mimeTable: { [key: string]: string } = {};

// Reading the MIME type associations.
for (let i = 0; i < N; i++) {
const inputs: string[] = readline().split(' ');
const EXT: string = inputs[0].toLowerCase(); // file extension (converted to lowercase for case-insensitivity)
const MT: string = inputs[1]; // MIME type
mimeTable[EXT] = MT; // Store the MIME type with the extension as the key
}

// Processing each file name.
for (let i = 0; i < Q; i++) {
const FNAME: string = readline();

// Find the position of the last '.' in the file name.
const lastDotIndex = FNAME.lastIndexOf('.');

// If there's a '.' and it isn't the last character, extract the extension.
if (lastDotIndex !== -1 && lastDotIndex < FNAME.length - 1) {
const fileExt = FNAME.slice(lastDotIndex + 1).toLowerCase(); // Get the file extension and convert to lowercase

// Check if the extension exists in the mimeTable.
if (mimeTable.hasOwnProperty(fileExt)) {
console.log(mimeTable[fileExt]); // Output the MIME type
} else {
console.log('UNKNOWN'); // Output UNKNOWN if extension not found
}
} else {
console.log('UNKNOWN'); // Output UNKNOWN if no extension or '.' at the end
}
}

```
23 changes: 0 additions & 23 deletions puzzles/ts/mime-type/mime-type.ts

This file was deleted.

Loading

0 comments on commit f6fb1fe

Please sign in to comment.