Оригинал на cs50.harvard.edu.

Пояснения

Выполнение

Финансы

Создайте веб-сайт, через который пользователи смогут «покупать» и «продавать» акции, как показано ниже.

Подготовка

Если вы не совсем понимаете, что значит покупать и продавать акции (т. е. акции компании), загляните сюда, чтобы получить руководство.

Вам надо создать C$50 Финансы — веб-приложение, с помощью которого вы сможете управлять портфелями акций. Этот инструмент не только позволит вам проверять реальные цены на акции и стоимость портфелей, но также позволит вам покупать (хорошо, «покупать») и продавать (хорошо, «продавать») акции, запрашивая цены на акции.

Действительно, существуют инструменты (один из них известен как IEX), которые позволяют загружать котировки акций через их API (интерфейс прикладного программирования), используя такие URL-адреса, как https://api.iex.cloud/v1/data/core/quote/nflx?token=API_KEY . Обратите внимание, как в этот URL-адрес встроен символ Netflix (NFLX); именно так IEX узнает, чьи данные возвращать. Эта ссылка на самом деле не вернёт никаких данных, поскольку IEX требует от вас использования ключа API, но если бы она сделала это , вы бы увидели ответ в формате JSON (нотация объектов JavaScript) следующим образом:


{
  "avgTotalVolume": 15918066,
  "calculationPrice": "close",
  "change": -8.27,
  "changePercent": -0.03074,
  "close": 260.79,
  "closeSource": "official",
  "closeTime": 1667592000924,
  "companyName": "Netflix Inc.",
  "currency": "USD",
  "delayedPrice": 260.81,
  "delayedPriceTime": 1667591988947,
  "extendedChange": 0.21,
  "extendedChangePercent": 0.00081,
  "extendedPrice": 261,
  "extendedPriceTime": 1667606392772,
  "high": 274.97,
  "highSource": "15 minute delayed price",
  "highTime": 1667592000831,
  "iexAskPrice": None,
  "iexAskSize": None,
  "iexBidPrice": None,
  "iexBidSize": None,
  "iexClose": 260.85,
  "iexCloseTime": 1667591999754,
  "iexLastUpdated": None,
  "iexMarketPercent": None,
  "iexOpen": 271.67,
  "iexOpenTime": 1667568602197,
  "iexRealtimePrice": None,
  "iexRealtimeSize": None,
  "iexVolume": None,
  "lastTradeTime": 1667591999820,
  "latestPrice": 260.79,
  "latestSource": "Close",
  "latestTime": "November 4, 2022",
  "latestUpdate": 1667592000924,
  "latestVolume": 11124694,
  "low": 255.32,
  "lowSource": "15 minute delayed price",
  "lowTime": 1667584872696,
  "marketCap": 115215720136,
  "oddLotDelayedPrice": 260.81,
  "oddLotDelayedPriceTime": 1667591988947,
  "open": 271.9,
  "openTime": 1667568601785,
  "openSource": "official",
  "peRatio": 23.39,
  "previousClose": 269.06,
  "previousVolume": 7057350,
  "primaryExchange": "NASDAQ",
  "symbol": "NFLX",
  "volume": 11124694,
  "week52High": 700.99,
  "week52Low": 162.71,
  "ytdChange": -0.5978504176349512,
  "isUSMarketOpen": False
}

Обратите внимание, что между фигурными скобками находится список пар ключ-значение, разделенный запятыми, с двоеточием, отделяющим каждый ключ от его значения. Мы собираемся сделать нечто очень похожее с Yahoo Finance.

Давайте теперь обратим наше внимание на получение кода, который поможет вам с этой задачей!

Начало

Войдите в cs50.dev, щелкните окно терминала и выполните cd. Вы получите приглашение в окне терминала, которое выглядит следующим образом:


$

Затем выполните


wget https://cs204.github.io/psets/data/finance.zip
чтобы загрузить ZIP-архив с именем finance.zip в свое кодовое пространство.

Затем выполните


unzip finance.zip

чтобы создать папку под названием «finance». Вам больше не нужен ZIP-файл, поэтому вы можете выполнить

rm finance.zip

и введите «y», а затем Enter в ответ на приглашение, чтобы удалить загруженный вами ZIP-файл.

Теперь наберите


cd finance

затем нажмите Enter, чтобы перейти (т. е. открыть) этот каталог. Ваше приглашение теперь должно выглядеть так, как показано ниже.

finance/ $

Запустите ls, и вы должны увидеть несколько файлов и папок:


app.py finance.db helpers.py requirements.txt satatic/ templates/

Если у вас возникнут какие-либо проблемы, повторите те же действия еще раз и посмотрите, сможете ли вы определить, где вы ошиблись!

Запуск

Запустите встроенный веб-сервер Flask (в каталоге Finance/):


$ flask run

Посетите URL-адрес, выведенный flask, чтобы увидеть код дистрибутива в действии. Однако вы пока не сможете войти или зарегистрироваться!

В каталоге finance/ выполните sqlite3 finance.db, чтобы открыть файл finance.db с помощью sqlite3. Запустите .schema в командной строке SQLite, обратите внимание, что в файл finance.db входит таблица с именем users. Взгляните на её структуру (т. е. схему). Обратите внимание, что по умолчанию новые пользователи получат 10 000 долларов наличными. Но если вы запустите SELECT * FROM users;, там (пока!) нет пользователей (т. е. строк) для просмотра.

Пояснения

app.py

Откройте app.py. Поверх файла находится множество импортированных файлов, в том числе модуль SQL CS50 и несколько вспомогательных функций. Подробнее о них скоро.

После настройки Flask обратите внимание, как этот файл отключает кэширование ответов (при условии, что вы находитесь в режиме отладки, который по умолчанию находится в вашем кодовом пространстве code50), чтобы вы не внесли изменения в какой-либо файл, но ваш браузер этого не заметил. Обратите внимание, как он настраивает Jinja с помощью специального «фильтра» usd — функции (определенной в helpers.py), которая упрощает форматирование значений в долларах США (USD). Затем он дополнительно настраивает Flask для хранения сеансов в локальной файловой системе (т. е. на диске), а не в файлах cookie (с цифровой подписью), что используется Flask по умолчанию. Затем файл настраивает модуль SQL CS50 для использования Finance.db. Обратите внимание, как он использует check_password_hash для сравнения хешей паролей пользователей. Также обратите внимание, как login «запоминает», что пользователь вошёл в систему, сохраняя его или её user_id, INTEGER, в session. Таким образом, любой route из этого файла может проверить, какой пользователь (если таковой имеется) вошел в систему. Наконец, обратите внимание, что после того, как пользователь успешно вошел в систему, вход будет перенаправлен на «/», и пользователь попадет на свою домашнюю страницу. Между тем, обратите внимание, что выход из системы просто очищает session, фактически выходя из системы.

Обратите внимание, как большинство маршрутов «украшены» @login_required (функция также определена в helpers.py). Этот декоратор гарантирует, что если не вошедший в систему пользователь попытается посетить любой из этих маршрутов, он или она сначала будет перенаправлен на вход в систему.

Обратите также внимание на то, что большинство маршрутов поддерживают GET и POST. Несмотря на это, большинство из них (на данный момент!) просто возвращают «извинения», поскольку они еще не реализованы.

helpers.py

Далее взгляните на helpers.py. Ах, вот реализация apology. Обратите внимание, как в конечном итоге отображается шаблон apology.html. Также внутри функции apology определяется ещё одна функция, escape, которую она использует для замены специальных символов в извинениях. Определяя escape внутри aplolgy, мы ограничили первое только вторым; никакие другие функции не смогут вызывать escape.

Далее в файле идёт login_required. Не беспокойтесь, если он выглядит загадочно, но если вы когда-нибудь задавались вопросом, как функция может возвращать другую функцию, вот пример!

После этого идёт lockup — функция, которая по символу (например, NFLX) возвращает котировку акций компании в виде словаря с тремя ключами: name, значением которого является str, название компании; price, значение которой является float; и symbol, значением которого является str, канонизированная (в верхнем регистре) версия символа акции, независимо от того, в каком регистре была буквы при передаче в lookup.

Последней в файле usd — функция, которая форматирует число с плавающей запятой в доллары США (например, 1234.56 форматируется как $1234,56).

requirements.txt

Затем взгляните на файл requirements.txt. Этот файл просто прописывает пакеты, от которых будет зависеть это приложение.

templates

Теперь посмотрите в templates/. В login.html — это, по сути, просто HTML- форма, стилизованная с помощью Bootstrap. В apology.html находится шаблон для извинения. Напомним, что извинение в helpers.py принимало два аргумента: message, которое было передано в render_template в качестве значения bottom, и, необязательного, cod, который был передан в render_template в качестве значения top. Обратите внимание в apology.html, как в конечном итоге используются эти значения! И вот почему 0:-)

Последний файл — layout.html. Он немного больше обычного, но это главным образом потому, что он оснащен модной, удобной для мобильных устройств "navbar" (панелью навигации), также основанной на Bootstrap. Обратите внимание, как он определяет блок main, внутри которого должны размещаться шаблоны (включая apology.html и login.html). Он также включает поддержку всплывающих сообщений Flask, чтобы вы могли ретранслировать сообщения с одного маршрута на другой, чтобы пользователь мог их увидеть.

Описание


register

Завершите реализацию register таким образом, чтобы пользователь мог зарегистрировать учётную запись через форму.

После того, как вы правильно реализовали регистрацию, вы сможете зарегистрировать учетную запись и войти в систему (поскольку вход и выход из системы уже работают)! И вы сможете видеть свои строки через sqlite3.

quote

Завершите реализацию quote таким образом, чтобы пользователь мог узнать текущую цену акции.

buy

Завершите реализацию buy таким образом, чтобы пользователь мог покупать акции.

После того, как вы правильно реализовали покупку, вы сможете видеть покупки пользователей в ваших новых таблицах через sqlite3.

index

Завершите реализацию index таким образом, чтобы он отображал сводную HTML-таблицу для пользователя, вошедшего в систему в данный момент, с указанием акций, которыми владеет пользователь, количества принадлежащих акций, текущей цены каждой акции и общей стоимости для каждого вида акций (т. е. количество акций умноженное на цену). Также отобразите текущий баланс денежных средств пользователя вместе с общей суммой (т. е. общей стоимостью акций плюс денежные средства).

sell

Завершите реализацию sell таким образом, чтобы пользователь мог продавать акции (которые ему принадлежат).

history

Завершите реализацию history таким образом, чтобы она отображала HTML-таблицу, в которой суммируются все транзакции пользователя за всю историю, перечисляя построчно каждую покупку и каждую продажу.

индивидуальный подход

Внесите хотя бы один индивидуальный подход по вашему выбору:

Тестирование

Обязательно протестируйте свое веб-приложение вручную, как показано ниже.

Также проверьте некоторые неожиданные варианты использования, например

Примерное решение


Вы можете стилизовать свое приложение по-другому, но вот как выглядит вариант решения!

https://finance.cs50.net/"

Не стесняйтесь зарегистрировать учётную запись и поиграть. Не используйте пароль, который вы используете на других сайтах.

Разумно посмотреть на HTML и CSS примера.

Подсказки

Отправка на проверку

Разместите ваше приложение на render.com, укажите в форме адрес приложения.

  1. В форме укажите адрес сайта на render.com.

  2. Свои оценки вы можете посмотреть на http://90.188.117.161:8080.