ゼロから計算機を組み立てる



導入
さて、あなたがゼロから計算機を作っていると言うと、あなたが反応のようなライブラリで作業しているときHyperBoleです.私が本当にここで意味することは、このプロジェクトを構築している間、私の意図は私自身の計算アルゴリズムを作ることでした.と私は!はい.
これは反応で計算機を構築するためのガイドではないことを念頭に置いてください.この記事は単に私の経験を文書化する私の方法です、私が道に沿って見つけた問題、および私がそれらを解決するために思い付いた解決.

目次
  • Overview of the challenge

  • The process
  • Challenge N° 1
  • Challenge N° 2
  • Challenge N° 3
  • Features left to add and issues left to solve
  • And it's done!
  • Where to find me...

  • チャレンジの概要
    オリジナルのチャレンジはFrontend Mentor . それを要約するには、男とギャルフロントエンドメンターでは、3つのテーマの間で交互にすることができますレイアウトを使用して基本的な操作を実行する計算機を作るに挑戦し、それの上に応答する.また、ボーナスの課題は、ユーザーが好ましいテーマのカラースキームを設定することができます.
    私はもともと数ヶ月前に計算機のアルゴリズムを構築していた.これは、基本的な計算(加算、減算、除算、乗算、指数関数、および因数分解)を実行することができた一連の関数は、入力として乱数の配列を使用して1つを呼び出すたびに例外関数の例外です.そのように、
    // Takes the first number and calculates it's power to the rest of the numbers inputed.
    const power = (...numbers) => {
      // Takes the first number off the list and stores it in a new variable.
      const firstNumber = numbers.splice(0, 1);
      let multiplyTheRest = 1;
      let result = 1;
      // Takes the numbers array and multiplies each one times the next.
      for (let i = 0; i < numbers.length; i++) {
        multiplyTheRest *= numbers[i];
      }
      // Multiplies the first number inside firstNumber by itself as many times whatever value was outputed in the previous loop.
      for (let i = 1; i <= multiplyTheRest; i++) {
        result *= firstNumber;
      }
      return result;
    };
    
    私は1週間前に私の鉱山のこの古いレポを発見し、私は自分自身のタッチで使用するために学んだものを置くために挑戦を取ることを決めた.したがって、なぜ最終的な製品を見ていないか、正確に挑戦のプロンプトとして振る舞う.そして、私はこれらの機能を反応州とそれで私の現在の知識で働かせるいくつかの変化をしなければならなかった間、私はまだ彼らのほとんどが彼らが元であった方法を保ちました.

    プロセス

    チャレンジn°1:グリッドを作ることは、私が望むすべてを置きました.そして、惨めに失敗します.

    I'm not going to lie. This one was kind of a though one in the visual area. Not because it was particularly difficult to style in Sass, but because after making two functions that build and returned all my buttons, I was left with an unordered grid of 20 elements (some of them bigger than the rest.)

    My first idea to make the keypad resemble the one of an actual calculator was to use the grid-template-area property on my parent element, and then give each group of related children the same grid-area name. This turned out a failure no matter how I wrote the template. Many of my buttons always ended up either overflowing or outright disappearing from the grid, and I ended up spending the biggest chunk of time just to try and make it work, then ditching it for something else, and then going back to it again.

    Lucky for me, around this time Kevin Powell had published a . It was unrelated to what I was trying to accomplish, but it introduced me to the grid-column and grid-row properties which, alongside the addition of a data attribute to every single one of my buttons, helped me to finally get that annoying grid exactly the way I wanted.

    Basically, I set the display of my parent element to grid, set my number of columns with grid-template-columns , and then I used a combination of those two properties I learned and span to put my problematic keys in their place, selecting them by their data-key attribute.

    .Buttons__button[data-key="="] {
                grid-row: 5;
                grid-column: 2/5;
            }
    

    チャレンジn°2:電卓を実際に動作させる.そして、実際にそれは数時間で行わ取得!

    As I previously mentioned, I already had a very basic calculation algorithm lying around my repositories, so I only had to figure out how to implement it in the app with the usestate hook.

    The first problem was choosing what type of input to pass into the function I was supposed to code.

    I needed to use the calc state prop not only to store my input, but also to display what the user was inputting. So I decided to go with a string, because it was easier to manipulate inside the state, and also, because I'm yet to figure out a non-convoluted way to set my state to an array of numbers interleaved with string values. Who knows, maybe I'm not seeing it, but it would be a hundred times easier to work with.

    The next problem I came across was getting each of those string values into an array without having multiple digit numbers breaking up and operators getting out of place.

    I solved this by taking the string input and, in one hand, filtering the operators out, and in the other hand, splitting it by its operators to get the numbers out. I stored each of the two resulting arrays into their own variable, and proceeded to combine both into const operations using map. Finally, I mapped the result again to obtain the final array newArray (yes, I ran out of names by this point) with parsed numbers, filtering any undesired values at the end. I hope this snippet speaks a little better about it:

    const operators = ["+", "-", "/", "*", "^", "!"];
    const numbers = nums.split(/[+-\/*^!]/)
    const opts = [...nums].filter( value => operators.includes(value))
    
    const operation = numbers.map( (num, i) => {
        if(opts[i] !== undefined) {
          return [num, opts[i]]
        } else {
          return num
        }
        }).flat().filter( value => value !== "");
    
    const newArray = operation.map( (value, i, array )=> {
        if(!(operators.includes(value))) {
            return parseFloat(value);
        } else if ( value === array[i-1] && value === "-") {
            return parseFloat(value+array[i+1])
        } else {
            return value;
        }
      }).filter( (value, i, array) => {
        if((typeof(value) === "number" && typeof(array[i-1]) === "string") || array[i-1] === undefined || typeof value === "string") {
            return value;
        }
      })
    

    This piece of code basically turns this: "2+2--222"
    Into this: [2, "+", 2, "-", -222]

    From that point on, I just had to make a loop with newArray.length > 0 as a condition to take each of its values and perform a calculation with the next one.

    Now the algorithm was ready to be used.


    チャレンジn°3:ボタンを作る迷惑な音を再生する.あなたがあなたの誇りを浅くして、ちょうど図書館を使うとき、実はかなり簡単です. This was the easiest problem of the bunch once I stopped trying to make it happen with vanilla JS and installed Howler .
    あなたのアプリの中でサウンドを再生する場合は、単に、コンソールを開くことができます実行npm -i howler , インポートholw オブジェクトのコンストラクタとして、ソースをパラメータとして取得する関数を作成し、ローカル変数内に2つのキー値ペアを持つ新しいhowlオブジェクトをインスタンス化し、play() メソッド.
    const playSound = (src) => {
        const sound = new Howl ({
          src,
          html5: true,
        })
    
        sound.play()
      }
    
    そして、それは、アプリケーションを展開する準備が整いました.

    機能を追加し、問題を解決するために残っ左
    ユーザーが長い操作を入力するとき、アルゴリズムの計算過程に関するいくつかの問題がまだあります、そして、その操作はその中のどこかで指数Calcを含んでいます.これは間違いなくアルゴリズムに優先順位を実装することによって解決されます、そして、私はすでにそれをする方法を考えました、しかし、たった今、私はそれを扱うために、それを残すほうを選びます.それは、音やテーマのトグルのような他の機能の追加.また、リファクタリングとパフォーマンスの最適化のビット.
    私はこのプロジェクトに戻って一度それらを更新します.

    そして、それは完了です! You can find my solution to this challenge in its repository . また、それを試してみることができますlive!


    どこで私を見つける. You can find me on GitHub そして、私は時々初心者開発者として私の経験を共有します.