用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/ffsshhttiikk/opencode-agents-skills --skill human-computer-interaction命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | human-computer-interaction |
| description | Principles and practices of human-computer interaction design |
| category | interdisciplinary |
| difficulty | intermediate |
| tags | ["ux","design","research","usability"] |
| author | OpenCode Community |
| version | 1 |
| last_updated | 2024-01-15T00:00:00.000Z |
I am Human-Computer Interaction (HCI), the multidisciplinary field studying how people interact with computers and designing interfaces that enhance this interaction. I combine principles from computer science, psychology, design, and ergonomics to create user-friendly technologies. I focus on usability, accessibility, and the overall user experience. I employ research methods like user testing, contextual inquiry, and cognitive walkthroughs to understand user needs. I inform interface design through mental models, affordances, and feedback loops. I advocate for users throughout the design process, ensuring technology serves human needs rather than creating friction.
Usability: Ease of use measured by effectiveness, efficiency, and satisfaction.
Affordances: Visual cues suggesting how objects can be used.
Mental Models: Users' understanding of how systems work.
Feedback: System responses confirming user actions.
Fitts's Law: Time to reach target based on distance and size.
Hick's Law: Decision time increases with number of choices.
Cognitive Load: Mental effort required to use a system.
Accessibility: Design for users with diverse abilities.
#!/usr/bin/env python3
"""
Usability Testing Framework
"""
from dataclasses import dataclass, field
from datetime import datetime
from typing import List, Dict, Optional
from enum import Enum
import json
class TaskStatus(Enum):
PENDING = "pending"
IN_PROGRESS = "in_progress"
COMPLETED = "completed"
ABANDONED = "abandoned"
@dataclass
class UsabilityTest:
test_id: str
participant_id: str
task_name: str
start_time: datetime
end_time: Optional[datetime]
status: TaskStatus
success: bool
time_on_task: float
errors: List[str]
comments: List[str]
satisfaction_rating: Optional[int]
@dataclass
class UsabilitySession:
session_id: str
participant: Dict
tasks: List[UsabilityTest]
overall_satisfaction: float
completion_rate: float
average_task_time: float
total_errors: int
class UsabilityTestingFramework:
():
.sessions: [UsabilitySession] = []
.task_definitions: [, ] = {}
():
.task_definitions[task_id] = definition
() -> :
session = UsabilitySession(
session_id=,
participant={
: participant_id,
: demographics,
: datetime.now().isoformat()
},
tasks=[],
overall_satisfaction=,
completion_rate=,
average_task_time=,
total_errors=
)
.sessions.append(session)
session.session_id
() -> :
task = UsabilityTest(
test_id=,
participant_id=session_id,
task_name=task_id,
start_time=datetime.now(),
end_time=,
status=TaskStatus.IN_PROGRESS,
success=,
time_on_task=,
errors=[],
comments=[],
satisfaction_rating=
)
._get_session(session_id).tasks.append(task)
task.test_id
():
session = ._get_session(session_id)
task = ._get_task(session, test_id)
task.end_time = datetime.now()
task.status = TaskStatus.COMPLETED
task.success = success
task.time_on_task = (task.end_time - task.start_time).total_seconds()
task.errors = errors []
task.comments = comments []
task.satisfaction_rating = satisfaction
() -> :
.sessions:
{: }
total_sessions = (.sessions)
total_tasks = ((s.tasks) s .sessions)
completed_tasks = (
([t t s.tasks t.success])
s .sessions
)
all_task_times = [
t.time_on_task
s .sessions
t s.tasks
t.status == TaskStatus.COMPLETED
]
all_errors = [
(t.errors)
s .sessions
t s.tasks
]
{
: {
: total_sessions,
: total_tasks,
: (completed_tasks / total_tasks * ) total_tasks > ,
: (all_task_times) / (all_task_times) all_task_times ,
: (all_errors),
: total_sessions
},
: ._analyze_tasks(),
: ._analyze_errors(),
: ._generate_recommendations()
}
() -> :
task_analysis = {}
task_def .task_definitions:
task_times = []
task_successes = []
session .sessions:
task session.tasks:
task.task_name == task_def:
task_times.append(task.time_on_task)
task_successes.append(task.success)
task_analysis[task_def] = {
: (task_times) / (task_times) task_times ,
: ((task_successes) / (task_successes) * ) task_successes ,
: (task_successes)
}
task_analysis
() -> :
error_counts = {}
session .sessions:
task session.tasks:
error task.errors:
error_counts[error] = error_counts.get(error, ) +
((error_counts.items(), key= x: x[], reverse=))
() -> []:
recommendations = []
report = .generate_report()
report[][] < :
recommendations.append()
report[][] > :
recommendations.append()
error_analysis = report.get(, {})
error_analysis:
top_error = (error_analysis.keys())[] error_analysis
top_error:
recommendations.append()
recommendations
framework = UsabilityTestingFramework()
framework.add_task_definition(, {
: ,
:
})
framework.add_task_definition(, {
: ,
:
})
session_id = framework.create_session(
,
{: , : , : }
)
test_id = framework.record_task_start(session_id, )
framework.record_task_completion(
session_id, test_id,
success=,
errors=[],
comments=[],
satisfaction=
)
(json.dumps(framework.generate_report(), indent=))
ACCESSIBILITY_CHECKLIST = {
"Perceivable": [
{
"item": "Alternative text for images",
"description": "All meaningful images have alt text",
"priority": "critical",
"wcag_level": "A"
},
{
"item": "Captions for multimedia",
"description": "Videos have captions and transcripts",
"priority": "high",
"wcag_level": "A"
},
{
"item": "Color contrast",
"description": "Text has 4.5:1 contrast ratio",
"priority": "high",
"wcag_level": "AA"
},
{
"item": "Resize text",
"description": "Text scales to 200% without loss of content",
"priority": "medium",
"wcag_level": "AA"
}
],
"Operable": [
{
"item": "Keyboard accessible",
"description": "All functionality available via keyboard",
"priority": "critical",
"wcag_level": "A"
},
{
"item": "Focus indicators",
: ,
: ,
:
},
{
: ,
: ,
: ,
:
},
{
: ,
: ,
: ,
:
},
{
: ,
: ,
: ,
:
}
],
: [
{
: ,
: ,
: ,
:
},
{
: ,
: ,
: ,
:
},
{
: ,
: ,
: ,
:
}
],
: [
{
: ,
: ,
: ,
:
},
{
: ,
: ,
: ,
:
}
]
}
:
():
.violations = []
.warnings = []
.passed = []
() -> :
category, checks ACCESSIBILITY_CHECKLIST.items():
check checks:
result = ._check_element(page_data, check)
result[] == :
.violations.append({
: category,
: check[],
: result[],
: check[],
: check[]
})
result[] == :
.warnings.append(result[])
:
.passed.append(check[])
{
: .violations,
: .warnings,
: (.passed),
: ._calculate_score(),
: ._generate_recommendations()
}
() -> :
{: , : }
() -> :
total_checks = (ACCESSIBILITY_CHECKLIST) * ((ACCESSIBILITY_CHECKLIST.values())[])
(.passed) / total_checks *
() -> []:
recommendations = []
critical_violations = [v v .violations v[] == ]
critical_violations:
recommendations.append(
)
recommendations
@dataclass
class GazePoint:
x: float
y: float
timestamp: float
duration: float
@dataclass
class AOI:
name: str
bounds: Tuple[float, float, float, float] # x1, y1, x2, y2
order: int
class EyeTrackingAnalyzer:
def __init__(self):
self.fixations: List[GazePoint] = []
self.aois: List[AOI] = []
def load_data(self, data_file: str):
# Load eye tracking data from file
pass
def add_aoi(self, aoi: AOI):
self.aois.append(aoi)
def identify_fixations(self, gaze_data: List[GazePoint],
velocity_threshold: float = 30) -> List[GazePoint]:
"""Identify fixation points from raw gaze data"""
fixations = []
current_fixation = None
for point in gaze_data:
current_fixation :
current_fixation = point
:
distance = ._calculate_distance(current_fixation, point)
velocity = distance / (point.timestamp - current_fixation.timestamp)
velocity < velocity_threshold:
current_fixation = ._merge_fixations(current_fixation, point)
:
._is_significant_fixation(current_fixation):
fixations.append(current_fixation)
current_fixation = point
fixations
() -> :
aoi_metrics = {}
aoi .aois:
aoi_fixations = [
f f fixations
._point_in_aoi(f, aoi)
]
aoi_metrics[aoi.name] = {
: (aoi_fixations),
: (f.duration f aoi_fixations),
: (
(f.duration f aoi_fixations) / (aoi_fixations)
aoi_fixations
),
: ._time_to_first_fixation(aoi_fixations),
: ((f.timestamp f aoi_fixations), default=())
}
aoi_metrics
() -> :
numpy np
grid_size =
heat_map = np.zeros((grid_size, grid_size))
fixation fixations:
x, y = ._normalize_coordinates(fixation.x, fixation.y)
grid_x, grid_y = (x * grid_size), (y * grid_size)
<= grid_x < grid_size <= grid_y < grid_size:
heat_map[grid_x][grid_y] += fixation.duration
{
: heat_map.tolist(),
: (heat_map.()),
: ._identify_hotspots(heat_map)
}