Skip to content
This repository has been archived by the owner on Feb 8, 2024. It is now read-only.

Commit

Permalink
Merge pull request #6 from Qiskit/fh-quantum-301
Browse files Browse the repository at this point in the history
Add composer widget
  • Loading branch information
jhwatrous committed Jun 17, 2022
2 parents f3879b3 + 3741128 commit 942a021
Show file tree
Hide file tree
Showing 33 changed files with 37,058 additions and 5,519 deletions.
8 changes: 6 additions & 2 deletions LOCALIZATION_CONTRIBUTORS
Expand Up @@ -43,24 +43,28 @@ Sungjoo Hwang | Denny-Hwang
Dayeong Kang | tula3and
Mingi Ryu | mingiryu
Young Ju Tak | glucktak
Sumin Jin | nineil91

Indonesian (ID)

Hanifan Rizki Nurahman | Hanifanrn
Natasha Valentina | natashaval

Portuguese (PT)
Portuguese (PT_UN)

Gustavo Mirapalheta | gustavomirapalheta
Marco Antonio Barroca | MarcoBarroca
André Galdino dos Santos | andregs2709
Natália Capra Ferrazzo | nataliaferrazzo
Omar Costa Hamido | omarcostahamido

Simplified Chinese (ZH-CHS)

Yunzhe Zheng | Dran-Z
Weixiao Sun | sunwx17
Bin Liu | fjirsmliu
Gang Ning | NG-Glen

Mengyin Tan | Linxi

Hindi (HI)

Expand Down
2 changes: 1 addition & 1 deletion README.md
@@ -1,5 +1,5 @@
# platypus
This repository is home of the new [Qiskit Textbook (beta)](https://qiskit.org/textbook-beta/).
This repository is home of the new [Qiskit Textbook (beta)](https://qiskit.org/learn/).

The previous version of the Qiskit Textbook textbook can be found [here](https://github.com/qiskit-community/qiskit-textbook).

Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/sidebar.spec.js
Expand Up @@ -39,7 +39,7 @@ describe('Sidebar', () => {
it('back to home link links to textbook home', () => {
const viewports = ['ipad-2', 'macbook-15']
const linkSelector = '[data-test=back-to-home-link]'
const textbookHomeUrl = 'https://qiskit.org/textbook-beta'
const textbookHomeUrl = 'https://qiskit.org/learn'

viewports.forEach((viewport) => {
cy.viewport(viewport)
Expand Down
4 changes: 3 additions & 1 deletion frontend/vue/components/MiniComposer/Circuit.vue
Expand Up @@ -5,6 +5,7 @@
:key="index"
:circuit-state="qubitLine"
:auto-measure-gate="autoMeasureGate"
:max-gates="maxGates"
@onGatesChanged="OnGatesChanged"
/>
<button
Expand All @@ -21,15 +22,16 @@

<script lang="ts">
import { Options, Vue, prop } from 'vue-class-component'
import { GateName } from './Gate.vue'
import QubitLine from './QubitLine.vue'
import { ComposerGate } from './composerTypes'
import { GateName } from './gateUtils'
class Props {
name = prop<String>({ default: GateName.H, required: true })
circuitState = prop<ComposerGate[][]>({ default: [[]], required: true })
autoMeasureGate = prop<boolean>({ default: true, required: true })
maxLines = prop<Number>({ default: 1, required: true })
maxGates = prop<Number>({ default: -1, required: true })
}
@Options({
Expand Down
283 changes: 283 additions & 0 deletions frontend/vue/components/MiniComposer/CircuitSandboxWidget.vue
@@ -0,0 +1,283 @@
<template>
<section class="mini-composer">
<div
ref="configRef"
class="mini-composer__config-container"
>
<slot />
</div>
<div
ref="instructionsRef"
class="mini-composer__exercise-text"
/>
<div class="mini-composer__gates">
<h1 class="mini-composer__gates__title">
Gates
</h1>
<GatesPool :available-gates="availableGates" />
</div>
<div class="mini-composer__circuit-section">
<h1 class="mini-composer__circuit-section__title">
Circuit
</h1>
<button
class="mini-composer__circuit-section__reset"
@click="onResetButton"
>
Reset <PlayIcon />
</button>
<Circuit
class="mini-composer__circuit-section__circuit-lines"
:circuit-state="circuitState"
:auto-measure-gate="false"
:max-lines="circuitState.length"
:max-gates="MAX_GATES"
/>
</div>
<div
ref="explanationRef"
class="mini-composer__explanation"
/>
<div class="mini-composer__state-views">
<section>
<h1 class="mini-composer__state-views__title">
Matrix
</h1>
<SymbolicNotation
class="mini-composer__state-views__area"
:tex="matrixTex"
/>
</section>
<section>
<h1 class="mini-composer__state-views__title">
State Vector
</h1>
<SymbolicNotation
class="mini-composer__state-views__area"
:tex="stateVectorTex"
/>
</section>
</div>
</section>
</template>

<script lang="ts">
import { ref } from '@vue/reactivity'
import { Options, Vue, prop } from 'vue-class-component'
import draggable from 'vuedraggable'
import PlayIcon from '@carbon/icons-vue/lib/reset/16'
import SolutionStateIndicator from '../common/SolutionStateIndicator.vue'
import GatesPool from './GatesPool.vue'
import Circuit from './Circuit.vue'
import { ComposerGate, gateMatrix } from './composerTypes'
import { GateName, IdentityState, StateMatrixToTexMatrix, StateMatrixToTexKetNotation } from './gateUtils'
import SymbolicNotation from './SymbolicNotation.vue'
class Props {
goal = prop<String>({ default: 'mini-composer-solved', required: true })
}
@Options({
components: {
Circuit,
GatesPool,
draggable,
SymbolicNotation,
SolutionStateIndicator,
PlayIcon
}
})
export default class CircuitSandboxWidget extends Vue.with(Props) {
configRef = ref<HTMLDivElement | null>(null)
get configDiv () { return (this.configRef as unknown as HTMLDivElement) }
instructionsRef = ref<HTMLDivElement | null>(null)
get instructions () { return (this.instructionsRef as unknown as HTMLDivElement) }
explanationRef = ref<HTMLDivElement | null>(null)
get explanation () { return (this.explanationRef as unknown as HTMLDivElement) }
MAX_GATES = 7
initialAvailableGates: ComposerGate[] = []
get availableGates (): ComposerGate[] {
return this.initialAvailableGates.map(gate => gate)
}
circuitState: ComposerGate[][] = [[]]
get matrixState () {
if (this.goal && this.circuitState[0].length > 0) {
this.$step?.score(this.goal as string)
}
return this.circuitState[0].reduce((prev, current) => {
return gateMatrix(current).apply(prev)
}, IdentityState())
}
get matrixTex () {
return StateMatrixToTexMatrix(this.matrixState)
}
get stateVectorTex () {
return StateMatrixToTexKetNotation(this.matrixState)
}
mounted () {
const instructionElement = this.configDiv.querySelector('.instructions')
const explanationElement = this.configDiv.querySelector('.explanation')
const availableGatesElement = this.configDiv.querySelector('.availableGates')
this.setCircuitConfig(availableGatesElement as HTMLElement)
if (instructionElement) {
this.instructions.appendChild(instructionElement)
} else {
this.instructions.remove()
}
if (explanationElement) {
this.explanation.appendChild(explanationElement)
} else {
this.explanation.remove()
}
}
setCircuitConfig (availableGatesElement: HTMLElement) {
this.initialAvailableGates = []
if (availableGatesElement && availableGatesElement.textContent) {
this.initialAvailableGates = this.stringToGateNameArray(availableGatesElement.textContent)
}
}
stringToGateNameArray (text: string) : ComposerGate[] {
let lastGateId = 0
return text.split(' ')
.filter(text => text !== '')
.map<ComposerGate>((gateText: string) => {
if (Object.values(GateName).some(gate => gateText.startsWith(gate))) {
const parts = gateText.split('(')
const gateName = parts[0]
const rotation = parts[1]?.split(')')[0]
return { name: gateName as GateName, id: lastGateId++, rotation }
}
return { name: GateName.UNKNOWN, id: lastGateId++ }
})
}
onResetButton () {
this.circuitState = [[]]
}
}
</script>
<style scoped lang="scss">
@import 'carbon-components/scss/globals/scss/typography';
@import 'carbon-components/scss/globals/scss/layout';
@import '../../../scss/variables/colors.scss';
@import '~/../scss/variables/mq.scss';
.mini-composer {
display: grid;
grid-template-columns: 20rem 1fr;
grid-template-rows: min-content min-content 1fr min-content;
grid-template-areas:
"text text"
"gates lesson"
"circuit lesson"
"explanation lesson";
@include mq ($until: medium) {
grid-template-columns: 1fr;
grid-template-rows: repeat(5, min-content);
grid-template-areas:
"text"
"gates"
"circuit"
"explanation"
"lesson";
}
&__config-container {
display: none;
}
&__exercise-text {
@include type-style('body-long-01');
grid-area: text;
border-bottom: 1px solid $border-color;
padding: $spacing-05;
}
&__explanation {
@include type-style('body-long-01');
grid-area: explanation;
padding: $spacing-05;
}
&__gates {
grid-area: gates;
border-bottom: 1px solid $border-color;
padding: $spacing-05;
&__title {
margin: $spacing-03 0 $spacing-05 0;
@include type-style('heading-01');
}
}
&__circuit-section {
grid-area: circuit;
padding: $spacing-05;
display: grid;
grid-template-columns: 1fr 4rem;
grid-template-rows: min-content 1fr;
grid-template-areas:
"title reset"
"line line";
&__title {
grid-area: title;
margin-top: $spacing-03;
@include type-style('heading-01');
}
&__reset {
@include type-style('body-short-01');
grid-area: reset;
display: flex;
flex-flow: row;
gap: $spacing-03;
color: $link-color-tertiary;
&:hover {
color: $link-hover-color-tertiary;
}
}
&__circuit-lines {
grid-area: line;
}
}
&__state-views {
grid-area: lesson;
display: flex;
flex-direction: column;
gap: $spacing-05;
border-left: 1px solid $border-color;
padding: $spacing-05;
@include mq ($until: medium) {
border-left: none;
border-top: 1px solid $border-color;
}
&__title {
@include type-style('heading-01');
margin-top: $spacing-03;
}
&__area {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 9rem;
width: 100%;
border: 2px solid $border-color;
background-color: $background-color-white;
}
}
}
</style>

0 comments on commit 942a021

Please sign in to comment.